@opensite/ui 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/carousel-horizontal-cards.cjs +8 -6
  2. package/dist/carousel-horizontal-cards.js +8 -6
  3. package/dist/carousel-image-hero.cjs +85 -160
  4. package/dist/carousel-image-hero.d.cts +1 -5
  5. package/dist/carousel-image-hero.d.ts +1 -5
  6. package/dist/carousel-image-hero.js +85 -160
  7. package/dist/carousel-portfolio-hero.cjs +138 -59
  8. package/dist/carousel-portfolio-hero.js +138 -59
  9. package/dist/carousel-product-feature-showcase.cjs +148 -95
  10. package/dist/carousel-product-feature-showcase.js +148 -95
  11. package/dist/carousel-progress-slider.cjs +13 -9
  12. package/dist/carousel-progress-slider.js +13 -9
  13. package/dist/carousel-scrolling-feature-showcase.cjs +105 -54
  14. package/dist/carousel-scrolling-feature-showcase.js +105 -54
  15. package/dist/feature-accordion-image.cjs +9 -8
  16. package/dist/feature-accordion-image.js +9 -8
  17. package/dist/feature-animated-carousel.cjs +65 -49
  18. package/dist/feature-animated-carousel.js +65 -49
  19. package/dist/feature-badge-grid-six.cjs +20 -17
  20. package/dist/feature-badge-grid-six.js +21 -18
  21. package/dist/feature-bento-image-grid.cjs +12 -8
  22. package/dist/feature-bento-image-grid.js +12 -8
  23. package/dist/feature-bento-utilities.cjs +9 -5
  24. package/dist/feature-bento-utilities.js +9 -5
  25. package/dist/feature-capabilities-grid.cjs +41 -38
  26. package/dist/feature-capabilities-grid.js +41 -38
  27. package/dist/feature-card-grid-linked.cjs +18 -18
  28. package/dist/feature-card-grid-linked.js +19 -19
  29. package/dist/feature-carousel-progress.cjs +3 -3
  30. package/dist/feature-carousel-progress.js +4 -4
  31. package/dist/feature-category-image-cards.cjs +3 -3
  32. package/dist/feature-category-image-cards.js +4 -4
  33. package/dist/feature-checklist-image.cjs +2 -2
  34. package/dist/feature-checklist-image.js +2 -2
  35. package/dist/feature-checklist-three-column.cjs +6 -6
  36. package/dist/feature-checklist-three-column.js +7 -7
  37. package/dist/feature-icon-grid-accent.cjs +2 -2
  38. package/dist/feature-icon-grid-accent.js +2 -2
  39. package/dist/feature-icon-grid-bordered.cjs +29 -31
  40. package/dist/feature-icon-grid-bordered.d.cts +9 -9
  41. package/dist/feature-icon-grid-bordered.d.ts +9 -9
  42. package/dist/feature-icon-grid-bordered.js +30 -32
  43. package/dist/feature-icon-grid-muted.cjs +6 -6
  44. package/dist/feature-icon-grid-muted.d.cts +9 -9
  45. package/dist/feature-icon-grid-muted.d.ts +9 -9
  46. package/dist/feature-icon-grid-muted.js +7 -7
  47. package/dist/feature-icon-tabs-content.cjs +8 -8
  48. package/dist/feature-icon-tabs-content.d.cts +13 -13
  49. package/dist/feature-icon-tabs-content.d.ts +13 -13
  50. package/dist/feature-icon-tabs-content.js +9 -9
  51. package/dist/feature-image-cards-three-column.cjs +26 -27
  52. package/dist/feature-image-cards-three-column.js +27 -28
  53. package/dist/feature-image-overlay-badge.cjs +23 -21
  54. package/dist/feature-image-overlay-badge.js +24 -22
  55. package/dist/feature-integration-cards.cjs +19 -18
  56. package/dist/feature-integration-cards.js +20 -19
  57. package/dist/feature-numbered-cards.cjs +2 -2
  58. package/dist/feature-numbered-cards.js +3 -3
  59. package/dist/feature-pattern-grid-links.cjs +26 -29
  60. package/dist/feature-pattern-grid-links.d.cts +1 -5
  61. package/dist/feature-pattern-grid-links.d.ts +1 -5
  62. package/dist/feature-pattern-grid-links.js +27 -30
  63. package/dist/feature-showcase.cjs +441 -40
  64. package/dist/feature-showcase.d.cts +62 -5
  65. package/dist/feature-showcase.d.ts +62 -5
  66. package/dist/feature-showcase.js +438 -37
  67. package/dist/feature-split-image-reverse.cjs +15 -36
  68. package/dist/feature-split-image-reverse.js +16 -37
  69. package/dist/feature-split-image.cjs +15 -36
  70. package/dist/feature-split-image.js +16 -37
  71. package/dist/feature-stats-highlight.cjs +20 -32
  72. package/dist/feature-stats-highlight.js +21 -33
  73. package/dist/feature-tabbed-content-image.cjs +11 -6
  74. package/dist/feature-tabbed-content-image.js +11 -6
  75. package/dist/feature-three-column-values.cjs +6 -6
  76. package/dist/feature-three-column-values.js +6 -6
  77. package/dist/feature-utility-cards-grid.cjs +17 -15
  78. package/dist/feature-utility-cards-grid.js +18 -16
  79. package/dist/navbar-tabbed-sections.cjs +23 -16
  80. package/dist/navbar-tabbed-sections.js +23 -16
  81. package/dist/registry.cjs +941 -708
  82. package/dist/registry.js +943 -710
  83. package/package.json +1 -1
@@ -429,111 +429,6 @@ var Pressable = React.forwardRef(
429
429
  }
430
430
  );
431
431
  Pressable.displayName = "Pressable";
432
- var svgCache = /* @__PURE__ */ new Map();
433
- function DynamicIcon({
434
- name,
435
- size = 28,
436
- color,
437
- className,
438
- alt
439
- }) {
440
- const [svgContent, setSvgContent] = React.useState(null);
441
- const [isLoading, setIsLoading] = React.useState(true);
442
- const [error, setError] = React.useState(null);
443
- const { url, iconName } = React.useMemo(() => {
444
- const separator = name.includes("/") ? "/" : ":";
445
- const [prefix, iconName2] = name.split(separator);
446
- const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
447
- return {
448
- url: baseUrl,
449
- iconName: iconName2
450
- };
451
- }, [name, size]);
452
- React.useEffect(() => {
453
- let isMounted = true;
454
- const fetchSvg = async () => {
455
- const cached = svgCache.get(url);
456
- if (cached) {
457
- if (isMounted) {
458
- setSvgContent(cached);
459
- setIsLoading(false);
460
- }
461
- return;
462
- }
463
- try {
464
- setIsLoading(true);
465
- setError(null);
466
- const response = await fetch(url);
467
- if (!response.ok) {
468
- throw new Error(`Failed to fetch icon: ${response.status}`);
469
- }
470
- let svg = await response.text();
471
- svg = processSvgForCurrentColor(svg);
472
- svgCache.set(url, svg);
473
- if (isMounted) {
474
- setSvgContent(svg);
475
- setIsLoading(false);
476
- }
477
- } catch (err) {
478
- if (isMounted) {
479
- setError(err instanceof Error ? err.message : "Failed to load icon");
480
- setIsLoading(false);
481
- }
482
- }
483
- };
484
- fetchSvg();
485
- return () => {
486
- isMounted = false;
487
- };
488
- }, [url]);
489
- if (isLoading) {
490
- return /* @__PURE__ */ jsx(
491
- "span",
492
- {
493
- className: cn("inline-block", className),
494
- style: { width: size, height: size },
495
- "aria-hidden": "true"
496
- }
497
- );
498
- }
499
- if (error || !svgContent) {
500
- return /* @__PURE__ */ jsx(
501
- "span",
502
- {
503
- className: cn("inline-block", className),
504
- style: { width: size, height: size },
505
- role: "img",
506
- "aria-label": alt || iconName
507
- }
508
- );
509
- }
510
- return /* @__PURE__ */ jsx(
511
- "span",
512
- {
513
- className: cn("inline-flex items-center justify-center", className),
514
- style: {
515
- width: size,
516
- height: size,
517
- color: color || "inherit"
518
- },
519
- role: "img",
520
- "aria-label": alt || iconName,
521
- dangerouslySetInnerHTML: { __html: svgContent }
522
- }
523
- );
524
- }
525
- function processSvgForCurrentColor(svg) {
526
- let processed = svg;
527
- processed = processed.replace(
528
- /stroke=["'](#000000|#000|black)["']/gi,
529
- 'stroke="currentColor"'
530
- );
531
- processed = processed.replace(
532
- /fill=["'](#000000|#000|black)["']/gi,
533
- 'fill="currentColor"'
534
- );
535
- return processed;
536
- }
537
432
  var maxWidthStyles = {
538
433
  sm: "max-w-screen-sm",
539
434
  md: "max-w-screen-md",
@@ -916,43 +811,43 @@ function CarouselImageHero({
916
811
  actions,
917
812
  actionsSlot,
918
813
  images,
919
- autoPlayInterval = 5e3,
814
+ autoPlayInterval = 7500,
920
815
  className,
921
- containerClassName,
816
+ containerClassName = "mx-auto w-full max-w-7xl relative z-10 rounded-2xl overflow-hidden shadow-xl",
922
817
  contentClassName,
923
818
  badgeClassName,
924
819
  headingClassName,
925
820
  descriptionClassName,
926
821
  actionsClassName,
927
822
  imageClassName,
928
- navigationClassName,
929
823
  indicatorsClassName,
930
824
  optixFlowConfig,
931
- background = "white",
932
- spacing = "xl",
825
+ background,
826
+ spacing,
933
827
  pattern,
934
828
  patternOpacity
935
829
  }) {
936
830
  const [currentImageIndex, setCurrentImageIndex] = React.useState(0);
937
831
  React.useEffect(() => {
938
832
  const interval = setInterval(() => {
939
- setCurrentImageIndex((prevIndex) => (prevIndex + 1) % (images?.length ?? 1));
833
+ setCurrentImageIndex(
834
+ (prevIndex) => (prevIndex + 1) % (images?.length ?? 1)
835
+ );
940
836
  }, autoPlayInterval);
941
837
  return () => clearInterval(interval);
942
838
  }, [images?.length, autoPlayInterval]);
943
- const goToNextImage = () => {
944
- setCurrentImageIndex((prevIndex) => (prevIndex + 1) % (images?.length ?? 1));
945
- };
946
- const goToPreviousImage = () => {
947
- setCurrentImageIndex(
948
- (prevIndex) => (prevIndex - 1 + (images?.length ?? 1)) % (images?.length ?? 1)
949
- );
950
- };
951
839
  const renderActions = () => {
952
840
  if (actionsSlot) return actionsSlot;
953
841
  if (!actions || actions.length === 0) return null;
954
842
  return actions.map((action, index) => {
955
- const { label, icon, iconAfter, children, className: actionClassName, ...pressableProps } = action;
843
+ const {
844
+ label,
845
+ icon,
846
+ iconAfter,
847
+ children,
848
+ className: actionClassName,
849
+ ...pressableProps
850
+ } = action;
956
851
  return /* @__PURE__ */ jsx(
957
852
  Pressable,
958
853
  {
@@ -977,6 +872,7 @@ function CarouselImageHero({
977
872
  className: cn("relative min-h-[600px] overflow-hidden", className),
978
873
  pattern,
979
874
  patternOpacity,
875
+ containerClassName,
980
876
  children: [
981
877
  /* @__PURE__ */ jsxs("div", { className: cn("absolute inset-0", imageClassName), children: [
982
878
  images?.map((image, index) => /* @__PURE__ */ jsxs(
@@ -1002,50 +898,79 @@ function CarouselImageHero({
1002
898
  index
1003
899
  )),
1004
900
  /* @__PURE__ */ jsx(
1005
- Pressable,
1006
- {
1007
- onClick: goToPreviousImage,
1008
- asButton: true,
1009
- variant: "ghost",
1010
- size: "icon",
1011
- className: cn("absolute left-4 top-1/2 z-20 hidden -translate-y-1/2 rounded-full bg-background/30 p-2 backdrop-blur-sm transition-colors hover:bg-background/50 md:block", navigationClassName),
1012
- "aria-label": "Previous image",
1013
- children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-left", size: 24, className: "text-white" })
1014
- }
1015
- ),
1016
- /* @__PURE__ */ jsx(
1017
- Pressable,
1018
- {
1019
- onClick: goToNextImage,
1020
- asButton: true,
1021
- variant: "ghost",
1022
- size: "icon",
1023
- className: cn("absolute right-4 top-1/2 z-20 hidden -translate-y-1/2 rounded-full bg-background/30 p-2 backdrop-blur-sm transition-colors hover:bg-background/50 md:block", navigationClassName),
1024
- "aria-label": "Next image",
1025
- children: /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 24, className: "text-white" })
1026
- }
1027
- ),
1028
- /* @__PURE__ */ jsx("div", { className: cn("absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-3", indicatorsClassName), children: images?.map((_, index) => /* @__PURE__ */ jsx(
1029
- "button",
901
+ "div",
1030
902
  {
1031
- onClick: () => setCurrentImageIndex(index),
1032
903
  className: cn(
1033
- "flex h-3 w-3 items-center justify-center rounded-full transition-colors",
1034
- index === currentImageIndex ? "bg-white" : "bg-white/50 hover:bg-white/80"
904
+ "absolute bottom-6 left-1/2 z-10 flex -translate-x-1/2 gap-3",
905
+ indicatorsClassName
1035
906
  ),
1036
- "aria-label": `Go to image ${index + 1}`
1037
- },
1038
- index
1039
- )) })
907
+ children: images?.map((_, index) => /* @__PURE__ */ jsx(
908
+ "button",
909
+ {
910
+ onClick: () => setCurrentImageIndex(index),
911
+ className: cn(
912
+ "flex h-4 w-4 items-center justify-center rounded-full transition-colors",
913
+ index === currentImageIndex ? "bg-white" : "bg-white/50 hover:bg-white/80"
914
+ ),
915
+ "aria-label": `Go to image ${index + 1}`
916
+ },
917
+ index
918
+ ))
919
+ }
920
+ )
1040
921
  ] }),
1041
- /* @__PURE__ */ jsx("div", { className: cn("container relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-16 text-center md:px-6 md:py-20", containerClassName), children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-4xl space-y-6", contentClassName), children: [
1042
- /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1043
- badge && (typeof badge === "string" ? /* @__PURE__ */ jsx("div", { className: cn("inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-sm font-medium text-white backdrop-blur-sm", badgeClassName), children: /* @__PURE__ */ jsx("span", { children: badge }) }) : /* @__PURE__ */ jsx("div", { className: badgeClassName, children: badge })),
1044
- heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("text-4xl font-bold tracking-tight text-primary-foreground dark:text-primary sm:text-5xl md:text-6xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
1045
- description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-xl text-primary-foreground dark:text-primary", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
1046
- ] }),
1047
- (actionsSlot || actions && actions.length > 0) && /* @__PURE__ */ jsx("div", { className: cn("flex flex-col justify-center gap-4 sm:flex-row", actionsClassName), children: renderActions() })
1048
- ] }) })
922
+ /* @__PURE__ */ jsx(
923
+ "div",
924
+ {
925
+ className: cn(
926
+ "relative z-10 mx-auto flex min-h-[600px] flex-col items-center justify-center px-4 py-16 text-center md:px-16 md:py-20"
927
+ ),
928
+ children: /* @__PURE__ */ jsxs("div", { className: cn("max-w-4xl space-y-6", contentClassName), children: [
929
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
930
+ badge && (typeof badge === "string" ? /* @__PURE__ */ jsx(
931
+ "div",
932
+ {
933
+ className: cn(
934
+ "inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-sm font-medium text-white backdrop-blur-sm",
935
+ badgeClassName
936
+ ),
937
+ children: /* @__PURE__ */ jsx("span", { children: badge })
938
+ }
939
+ ) : /* @__PURE__ */ jsx("div", { className: badgeClassName, children: badge })),
940
+ heading && (typeof heading === "string" ? /* @__PURE__ */ jsx(
941
+ "h1",
942
+ {
943
+ className: cn(
944
+ "text-4xl font-bold sm:text-5xl md:text-6xl text-balance text-shadow",
945
+ headingClassName
946
+ ),
947
+ children: heading
948
+ }
949
+ ) : /* @__PURE__ */ jsx("div", { className: headingClassName, children: heading })),
950
+ description && (typeof description === "string" ? /* @__PURE__ */ jsx(
951
+ "p",
952
+ {
953
+ className: cn(
954
+ "text-xl text-balance text-shadow",
955
+ descriptionClassName
956
+ ),
957
+ children: description
958
+ }
959
+ ) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
960
+ ] }),
961
+ (actionsSlot || actions && actions.length > 0) && /* @__PURE__ */ jsx(
962
+ "div",
963
+ {
964
+ className: cn(
965
+ "flex flex-col justify-center gap-4 sm:flex-row",
966
+ actionsClassName
967
+ ),
968
+ children: renderActions()
969
+ }
970
+ )
971
+ ] })
972
+ }
973
+ )
1049
974
  ]
1050
975
  }
1051
976
  );
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React = require('react');
4
+ var React6 = require('react');
5
5
  var clsx = require('clsx');
6
6
  var tailwindMerge = require('tailwind-merge');
7
7
  var classVarianceAuthority = require('class-variance-authority');
@@ -26,7 +26,7 @@ function _interopNamespace(e) {
26
26
  return Object.freeze(n);
27
27
  }
28
28
 
29
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
+ var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
30
30
 
31
31
  // components/blocks/carousel/carousel-portfolio-hero.tsx
32
32
  function cn(...inputs) {
@@ -117,7 +117,7 @@ function useNavigation({
117
117
  href,
118
118
  onClick
119
119
  } = {}) {
120
- const linkType = React__namespace.useMemo(() => {
120
+ const linkType = React6__namespace.useMemo(() => {
121
121
  if (!href || href.trim() === "") {
122
122
  return onClick ? "none" : "none";
123
123
  }
@@ -138,7 +138,7 @@ function useNavigation({
138
138
  return "internal";
139
139
  }
140
140
  }, [href, onClick]);
141
- const normalizedHref = React__namespace.useMemo(() => {
141
+ const normalizedHref = React6__namespace.useMemo(() => {
142
142
  if (!href || href.trim() === "") {
143
143
  return void 0;
144
144
  }
@@ -156,7 +156,7 @@ function useNavigation({
156
156
  return trimmed;
157
157
  }
158
158
  }, [href, linkType]);
159
- const target = React__namespace.useMemo(() => {
159
+ const target = React6__namespace.useMemo(() => {
160
160
  switch (linkType) {
161
161
  case "external":
162
162
  return "_blank";
@@ -169,7 +169,7 @@ function useNavigation({
169
169
  return void 0;
170
170
  }
171
171
  }, [linkType]);
172
- const rel = React__namespace.useMemo(() => {
172
+ const rel = React6__namespace.useMemo(() => {
173
173
  if (linkType === "external") {
174
174
  return "noopener noreferrer";
175
175
  }
@@ -178,7 +178,7 @@ function useNavigation({
178
178
  const isExternal = linkType === "external";
179
179
  const isInternal = linkType === "internal";
180
180
  const shouldUseRouter = isInternal && typeof normalizedHref === "string" && normalizedHref.startsWith("/");
181
- const handleClick = React__namespace.useCallback(
181
+ const handleClick = React6__namespace.useCallback(
182
182
  (event) => {
183
183
  if (onClick) {
184
184
  try {
@@ -362,7 +362,7 @@ var buttonVariants = classVarianceAuthority.cva(baseStyles, {
362
362
  size: "default"
363
363
  }
364
364
  });
365
- var Pressable = React__namespace.forwardRef(
365
+ var Pressable = React6__namespace.forwardRef(
366
366
  ({
367
367
  children,
368
368
  className,
@@ -468,10 +468,10 @@ function DynamicIcon({
468
468
  className,
469
469
  alt
470
470
  }) {
471
- const [svgContent, setSvgContent] = React__namespace.useState(null);
472
- const [isLoading, setIsLoading] = React__namespace.useState(true);
473
- const [error, setError] = React__namespace.useState(null);
474
- const { url, iconName } = React__namespace.useMemo(() => {
471
+ const [svgContent, setSvgContent] = React6__namespace.useState(null);
472
+ const [isLoading, setIsLoading] = React6__namespace.useState(true);
473
+ const [error, setError] = React6__namespace.useState(null);
474
+ const { url, iconName } = React6__namespace.useMemo(() => {
475
475
  const separator = name.includes("/") ? "/" : ":";
476
476
  const [prefix, iconName2] = name.split(separator);
477
477
  const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
@@ -480,7 +480,7 @@ function DynamicIcon({
480
480
  iconName: iconName2
481
481
  };
482
482
  }, [name, size]);
483
- React__namespace.useEffect(() => {
483
+ React6__namespace.useEffect(() => {
484
484
  let isMounted = true;
485
485
  const fetchSvg = async () => {
486
486
  const cached = svgCache.get(url);
@@ -574,7 +574,7 @@ var maxWidthStyles = {
574
574
  "4xl": "max-w-[1536px]",
575
575
  full: "max-w-full"
576
576
  };
577
- var Container = React__namespace.default.forwardRef(
577
+ var Container = React6__namespace.default.forwardRef(
578
578
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
579
579
  const Component = as;
580
580
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -879,7 +879,7 @@ var spacingStyles = {
879
879
  };
880
880
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
881
881
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
882
- var Section = React__namespace.default.forwardRef(
882
+ var Section = React6__namespace.default.forwardRef(
883
883
  ({
884
884
  id,
885
885
  title,
@@ -947,7 +947,7 @@ function CarouselPortfolioHero({
947
947
  actionsSlot,
948
948
  autoPlayInterval = 5e3,
949
949
  className,
950
- containerClassName,
950
+ containerClassName = "mx-auto w-full p-0 px-0 sm:px-0 lg:px-0 max-w-full relative z-10 h-full flex flex-col justify-center",
951
951
  contentClassName,
952
952
  tagClassName,
953
953
  titleClassName,
@@ -962,24 +962,46 @@ function CarouselPortfolioHero({
962
962
  patternOpacity,
963
963
  slideMediaBrightness = "50"
964
964
  }) {
965
- const [currentIndex, setCurrentIndex] = React__namespace.useState(0);
966
- const goToNext = React__namespace.useCallback(() => {
965
+ const [currentIndex, setCurrentIndex] = React6__namespace.useState(0);
966
+ const intervalRef = React6__namespace.useRef(null);
967
+ const resetInterval = React6__namespace.useCallback(() => {
968
+ if (intervalRef.current) {
969
+ clearInterval(intervalRef.current);
970
+ }
971
+ intervalRef.current = setInterval(() => {
972
+ setCurrentIndex((prevIndex) => (prevIndex + 1) % (slides?.length ?? 1));
973
+ }, autoPlayInterval);
974
+ }, [autoPlayInterval, slides?.length]);
975
+ const goToNext = React6__namespace.useCallback(() => {
967
976
  setCurrentIndex((prevIndex) => (prevIndex + 1) % (slides?.length ?? 1));
968
- }, [slides?.length]);
969
- const goToPrev = React__namespace.useCallback(() => {
977
+ resetInterval();
978
+ }, [slides?.length, resetInterval]);
979
+ const goToPrev = React6__namespace.useCallback(() => {
970
980
  setCurrentIndex(
971
981
  (prevIndex) => (prevIndex - 1 + (slides?.length ?? 1)) % (slides?.length ?? 1)
972
982
  );
973
- }, [slides?.length]);
974
- React__namespace.useEffect(() => {
975
- const interval = setInterval(goToNext, autoPlayInterval);
976
- return () => clearInterval(interval);
977
- }, [goToNext, autoPlayInterval]);
983
+ resetInterval();
984
+ }, [slides?.length, resetInterval]);
985
+ React6__namespace.useEffect(() => {
986
+ resetInterval();
987
+ return () => {
988
+ if (intervalRef.current) {
989
+ clearInterval(intervalRef.current);
990
+ }
991
+ };
992
+ }, [resetInterval]);
978
993
  const renderActions = () => {
979
994
  if (actionsSlot) return actionsSlot;
980
995
  if (!actions || actions.length === 0) return null;
981
996
  return actions.map((action, index) => {
982
- const { label, icon, iconAfter, children, className: actionClassName, ...pressableProps } = action;
997
+ const {
998
+ label,
999
+ icon,
1000
+ iconAfter,
1001
+ children,
1002
+ className: actionClassName,
1003
+ ...pressableProps
1004
+ } = action;
983
1005
  return /* @__PURE__ */ jsxRuntime.jsx(
984
1006
  Pressable,
985
1007
  {
@@ -1005,6 +1027,7 @@ function CarouselPortfolioHero({
1005
1027
  className: cn("relative h-screen w-full overflow-hidden", className),
1006
1028
  pattern,
1007
1029
  patternOpacity,
1030
+ containerClassName,
1008
1031
  children: [
1009
1032
  slidesSlot ? slidesSlot : slides?.map((slide, index) => /* @__PURE__ */ jsxRuntime.jsx(
1010
1033
  "div",
@@ -1030,43 +1053,99 @@ function CarouselPortfolioHero({
1030
1053
  },
1031
1054
  slide.id
1032
1055
  )),
1033
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative z-10 flex h-full w-full flex-col justify-end px-6 pb-16 text-white md:px-8 lg:px-12", containerClassName), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-4xl", contentClassName), children: [
1034
- currentSlide?.tag && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: typeof currentSlide.tag === "string" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("inline-block rounded-full bg-primary px-3 py-1 text-sm font-medium", tagClassName), children: currentSlide.tag }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagClassName, children: currentSlide.tag }) }),
1035
- currentSlide?.title && (typeof currentSlide.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-bold sm:text-5xl md:text-6xl", titleClassName), children: currentSlide.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: titleClassName, children: currentSlide.title })),
1036
- currentSlide?.description && (typeof currentSlide.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-4 text-lg text-white/80 sm:text-xl md:max-w-2xl", descriptionClassName), children: currentSlide.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: currentSlide.description })),
1037
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mt-8 flex items-center gap-4", actionsClassName), children: [
1038
- renderActions(),
1039
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("ml-auto flex items-center gap-2", navigationClassName), children: [
1040
- /* @__PURE__ */ jsxRuntime.jsx(
1041
- Pressable,
1056
+ /* @__PURE__ */ jsxRuntime.jsx(
1057
+ "div",
1058
+ {
1059
+ className: cn(
1060
+ "relative z-10 flex h-full w-full flex-col justify-end px-6 pb-16 text-white md:px-8 lg:px-12"
1061
+ ),
1062
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("max-w-4xl", contentClassName), children: [
1063
+ currentSlide?.tag && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: typeof currentSlide.tag === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1064
+ "span",
1042
1065
  {
1043
- variant: "outline",
1044
- size: "icon",
1045
- className: "rounded-full border-white/40 bg-black/30 text-white hover:bg-black/50 hover:text-white",
1046
- onClick: goToPrev,
1047
- asButton: true,
1048
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-left", size: 20 })
1066
+ className: cn(
1067
+ "inline-block rounded-full bg-primary px-3 py-1 text-sm font-medium",
1068
+ tagClassName
1069
+ ),
1070
+ children: currentSlide.tag
1049
1071
  }
1050
- ),
1051
- /* @__PURE__ */ jsxRuntime.jsx(
1052
- Pressable,
1072
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: tagClassName, children: currentSlide.tag }) }),
1073
+ currentSlide?.title && (typeof currentSlide.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1074
+ "h1",
1053
1075
  {
1054
- variant: "outline",
1055
- size: "icon",
1056
- className: "rounded-full border-white/40 bg-black/30 text-white hover:bg-black/50 hover:text-white",
1057
- onClick: goToNext,
1058
- asButton: true,
1059
- children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 20 })
1076
+ className: cn(
1077
+ "text-4xl font-bold sm:text-5xl md:text-6xl text-balance text-shadow",
1078
+ titleClassName
1079
+ ),
1080
+ children: currentSlide.title
1060
1081
  }
1061
- ),
1062
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("ml-3 text-sm text-white/80", counterClassName), children: [
1063
- currentIndex + 1,
1064
- " / ",
1065
- slides?.length ?? 0
1066
- ] })
1067
- ] })
1068
- ] })
1069
- ] }) }) })
1082
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: titleClassName, children: currentSlide.title })),
1083
+ currentSlide?.description && (typeof currentSlide.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx(
1084
+ "p",
1085
+ {
1086
+ className: cn(
1087
+ "mt-4 text-lg text-white/80 sm:text-xl md:max-w-2xl text-balance text-shadow",
1088
+ descriptionClassName
1089
+ ),
1090
+ children: currentSlide.description
1091
+ }
1092
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: currentSlide.description })),
1093
+ /* @__PURE__ */ jsxRuntime.jsxs(
1094
+ "div",
1095
+ {
1096
+ className: cn("mt-8 flex items-center gap-4", actionsClassName),
1097
+ children: [
1098
+ renderActions(),
1099
+ /* @__PURE__ */ jsxRuntime.jsxs(
1100
+ "div",
1101
+ {
1102
+ className: cn(
1103
+ "ml-auto flex items-center gap-2",
1104
+ navigationClassName
1105
+ ),
1106
+ children: [
1107
+ /* @__PURE__ */ jsxRuntime.jsx(
1108
+ Pressable,
1109
+ {
1110
+ variant: "outline",
1111
+ size: "icon",
1112
+ className: "rounded-full border-white/40 bg-black/30 text-white hover:bg-black/50 hover:text-white",
1113
+ onClick: goToPrev,
1114
+ asButton: true,
1115
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-left", size: 20 })
1116
+ }
1117
+ ),
1118
+ /* @__PURE__ */ jsxRuntime.jsx(
1119
+ Pressable,
1120
+ {
1121
+ variant: "outline",
1122
+ size: "icon",
1123
+ className: "rounded-full border-white/40 bg-black/30 text-white hover:bg-black/50 hover:text-white",
1124
+ onClick: goToNext,
1125
+ asButton: true,
1126
+ children: /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 20 })
1127
+ }
1128
+ ),
1129
+ /* @__PURE__ */ jsxRuntime.jsxs(
1130
+ "div",
1131
+ {
1132
+ className: cn("ml-3 text-sm text-white/80", counterClassName),
1133
+ children: [
1134
+ currentIndex + 1,
1135
+ " / ",
1136
+ slides?.length ?? 0
1137
+ ]
1138
+ }
1139
+ )
1140
+ ]
1141
+ }
1142
+ )
1143
+ ]
1144
+ }
1145
+ )
1146
+ ] }) })
1147
+ }
1148
+ )
1070
1149
  ]
1071
1150
  }
1072
1151
  );