@opensite/ui 0.8.1 → 0.8.3

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 +119 -177
  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 +119 -177
  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 +964 -714
  82. package/dist/registry.js +966 -716
  83. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React = require('react');
4
+ var React4 = require('react');
5
5
  var framerMotion = require('framer-motion');
6
6
  var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
@@ -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 React4__namespace = /*#__PURE__*/_interopNamespace(React4);
30
30
 
31
31
  // components/blocks/features/feature-animated-carousel.tsx
32
32
  function cn(...inputs) {
@@ -40,10 +40,10 @@ function DynamicIcon({
40
40
  className,
41
41
  alt
42
42
  }) {
43
- const [svgContent, setSvgContent] = React__namespace.useState(null);
44
- const [isLoading, setIsLoading] = React__namespace.useState(true);
45
- const [error, setError] = React__namespace.useState(null);
46
- const { url, iconName } = React__namespace.useMemo(() => {
43
+ const [svgContent, setSvgContent] = React4__namespace.useState(null);
44
+ const [isLoading, setIsLoading] = React4__namespace.useState(true);
45
+ const [error, setError] = React4__namespace.useState(null);
46
+ const { url, iconName } = React4__namespace.useMemo(() => {
47
47
  const separator = name.includes("/") ? "/" : ":";
48
48
  const [prefix, iconName2] = name.split(separator);
49
49
  const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
@@ -52,7 +52,7 @@ function DynamicIcon({
52
52
  iconName: iconName2
53
53
  };
54
54
  }, [name, size]);
55
- React__namespace.useEffect(() => {
55
+ React4__namespace.useEffect(() => {
56
56
  let isMounted = true;
57
57
  const fetchSvg = async () => {
58
58
  const cached = svgCache.get(url);
@@ -146,7 +146,7 @@ var maxWidthStyles = {
146
146
  "4xl": "max-w-[1536px]",
147
147
  full: "max-w-full"
148
148
  };
149
- var Container = React__namespace.default.forwardRef(
149
+ var Container = React4__namespace.default.forwardRef(
150
150
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
151
151
  const Component = as;
152
152
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -451,7 +451,7 @@ var spacingStyles = {
451
451
  };
452
452
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
453
453
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
454
- var Section = React__namespace.default.forwardRef(
454
+ var Section = React4__namespace.default.forwardRef(
455
455
  ({
456
456
  id,
457
457
  title,
@@ -512,7 +512,7 @@ var Section = React__namespace.default.forwardRef(
512
512
  }
513
513
  );
514
514
  Section.displayName = "Section";
515
- var Controls = ({
515
+ var Controls = React4__namespace.memo(({
516
516
  handleNext,
517
517
  handlePrevious,
518
518
  isPreviousDisabled,
@@ -540,9 +540,9 @@ var Controls = ({
540
540
  }
541
541
  )
542
542
  ] });
543
- };
544
- var FeatureCard = ({ feature, isActive, onClick }) => {
545
- const variants = {
543
+ });
544
+ var FeatureCard = React4__namespace.memo(({ feature, isActive, onClick }) => {
545
+ const variants = React4.useMemo(() => ({
546
546
  initial: {
547
547
  opacity: 0
548
548
  },
@@ -552,7 +552,7 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
552
552
  exit: {
553
553
  opacity: 0
554
554
  }
555
- };
555
+ }), []);
556
556
  return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsxRuntime.jsx(
557
557
  framerMotion.motion.div,
558
558
  {
@@ -582,13 +582,13 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
582
582
  ease: "easeOut"
583
583
  },
584
584
  className: "p-6 text-sm md:p-8 md:text-base",
585
- children: /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
586
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
585
+ children: (feature.title || feature.description) && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
586
+ feature.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
587
587
  feature.title,
588
588
  "."
589
589
  ] }),
590
- " ",
591
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: feature.description })
590
+ feature.title && feature.description && " ",
591
+ feature.description && /* @__PURE__ */ jsxRuntime.jsx("span", { children: feature.description })
592
592
  ] })
593
593
  },
594
594
  `feature-description-active-${feature.title}`
@@ -622,15 +622,15 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
622
622
  className: "shrink-0"
623
623
  }
624
624
  ),
625
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
625
+ feature.title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
626
626
  ]
627
627
  },
628
628
  `feature-description-inactive-${feature.title}`
629
629
  )
630
630
  }
631
631
  ) });
632
- };
633
- var FeaturesDesktop = ({
632
+ });
633
+ var FeaturesDesktop = React4__namespace.memo(({
634
634
  features,
635
635
  handleNext,
636
636
  handlePrevious,
@@ -661,8 +661,8 @@ var FeaturesDesktop = ({
661
661
  );
662
662
  }) })
663
663
  ] });
664
- };
665
- var FeaturesMobile = ({
664
+ });
665
+ var FeaturesMobile = React4__namespace.memo(({
666
666
  features,
667
667
  handleNext,
668
668
  handlePrevious,
@@ -671,7 +671,7 @@ var FeaturesMobile = ({
671
671
  isPreviousDisabled,
672
672
  isNextDisabled
673
673
  }) => {
674
- const variants = {
674
+ const variants = React4.useMemo(() => ({
675
675
  enter: (direction2) => ({
676
676
  x: direction2 > 0 ? 100 : -100,
677
677
  opacity: 0
@@ -684,7 +684,8 @@ var FeaturesMobile = ({
684
684
  x: direction2 < 0 ? 100 : -100,
685
685
  opacity: 0
686
686
  })
687
- };
687
+ }), []);
688
+ const currentFeature = features[activeIndex];
688
689
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex flex-col items-center gap-6 md:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center justify-between gap-4", children: [
689
690
  /* @__PURE__ */ jsxRuntime.jsx(
690
691
  "button",
@@ -709,13 +710,13 @@ var FeaturesMobile = ({
709
710
  opacity: { duration: 0.2 }
710
711
  },
711
712
  className: "absolute inset-0 flex items-center justify-center rounded-3xl bg-background p-4",
712
- children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm", children: [
713
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
714
- features[activeIndex].title,
713
+ children: (currentFeature?.title || currentFeature?.description) && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-center text-sm", children: [
714
+ currentFeature.title && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold", children: [
715
+ currentFeature.title,
715
716
  "."
716
717
  ] }),
717
- " ",
718
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: features[activeIndex].description })
718
+ currentFeature.title && currentFeature.description && " ",
719
+ currentFeature.description && /* @__PURE__ */ jsxRuntime.jsx("span", { children: currentFeature.description })
719
720
  ] })
720
721
  },
721
722
  activeIndex
@@ -731,9 +732,9 @@ var FeaturesMobile = ({
731
732
  }
732
733
  )
733
734
  ] }) });
734
- };
735
+ });
735
736
  function FeatureAnimatedCarousel({
736
- features = [],
737
+ features,
737
738
  className,
738
739
  optixFlowConfig,
739
740
  background,
@@ -742,27 +743,27 @@ function FeatureAnimatedCarousel({
742
743
  patternOpacity,
743
744
  patternClassName
744
745
  }) {
745
- const [activeIndex, setActiveIndex] = React__namespace.useState(0);
746
- const [direction, setDirection] = React__namespace.useState(1);
747
- const handleNext = () => {
748
- if (activeIndex < features.length - 1) {
746
+ const [activeIndex, setActiveIndex] = React4__namespace.useState(0);
747
+ const [direction, setDirection] = React4__namespace.useState(1);
748
+ const handleNext = React4.useCallback(() => {
749
+ if (features && activeIndex < features.length - 1) {
749
750
  setDirection(1);
750
751
  setActiveIndex(activeIndex + 1);
751
752
  }
752
- };
753
- const handlePrevious = () => {
753
+ }, [activeIndex, features]);
754
+ const handlePrevious = React4.useCallback(() => {
754
755
  if (activeIndex > 0) {
755
756
  setDirection(-1);
756
757
  setActiveIndex(activeIndex - 1);
757
758
  }
758
- };
759
- const handleFeatureClick = (index) => {
759
+ }, [activeIndex]);
760
+ const handleFeatureClick = React4.useCallback((index) => {
760
761
  setDirection(index > activeIndex ? 1 : -1);
761
762
  setActiveIndex(index);
762
- };
763
+ }, [activeIndex]);
763
764
  const isPreviousDisabled = activeIndex === 0;
764
- const isNextDisabled = activeIndex === features.length - 1;
765
- const imageVariants = {
765
+ const isNextDisabled = !features || activeIndex === features.length - 1;
766
+ const imageVariants = React4.useMemo(() => ({
766
767
  enter: (direction2) => ({
767
768
  x: direction2 > 0 ? 300 : -300,
768
769
  opacity: 0
@@ -775,7 +776,22 @@ function FeatureAnimatedCarousel({
775
776
  x: direction2 < 0 ? 300 : -300,
776
777
  opacity: 0
777
778
  })
778
- };
779
+ }), []);
780
+ if (!features || features.length === 0) {
781
+ return /* @__PURE__ */ jsxRuntime.jsx(
782
+ Section,
783
+ {
784
+ background,
785
+ spacing,
786
+ pattern,
787
+ patternOpacity,
788
+ patternClassName,
789
+ className,
790
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl bg-muted p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]" })
791
+ }
792
+ );
793
+ }
794
+ const currentFeature = features[activeIndex];
779
795
  return /* @__PURE__ */ jsxRuntime.jsx(
780
796
  Section,
781
797
  {
@@ -786,7 +802,7 @@ function FeatureAnimatedCarousel({
786
802
  patternClassName,
787
803
  className,
788
804
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl bg-muted p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]", children: [
789
- features && /* @__PURE__ */ jsxRuntime.jsx(
805
+ /* @__PURE__ */ jsxRuntime.jsx(
790
806
  FeaturesDesktop,
791
807
  {
792
808
  features,
@@ -798,7 +814,7 @@ function FeatureAnimatedCarousel({
798
814
  isNextDisabled
799
815
  }
800
816
  ),
801
- features && /* @__PURE__ */ jsxRuntime.jsx(
817
+ /* @__PURE__ */ jsxRuntime.jsx(
802
818
  FeaturesMobile,
803
819
  {
804
820
  features,
@@ -810,7 +826,7 @@ function FeatureAnimatedCarousel({
810
826
  isNextDisabled
811
827
  }
812
828
  ),
813
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
829
+ currentFeature?.image && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1 overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsxRuntime.jsx(
814
830
  framerMotion.motion.div,
815
831
  {
816
832
  custom: direction,
@@ -826,8 +842,8 @@ function FeatureAnimatedCarousel({
826
842
  children: /* @__PURE__ */ jsxRuntime.jsx(
827
843
  img.Img,
828
844
  {
829
- src: features ? features[activeIndex].image : void 0,
830
- alt: features ? features[activeIndex].imageAlt || (typeof features[activeIndex].title === "string" ? features[activeIndex].title : "Feature image") : void 0,
845
+ src: currentFeature.image,
846
+ alt: currentFeature.imageAlt || (typeof currentFeature.title === "string" ? currentFeature.title : "Feature image"),
831
847
  className: "h-full w-full object-cover",
832
848
  optixFlowConfig
833
849
  }
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import * as React from 'react';
3
- import React__default from 'react';
2
+ import * as React4 from 'react';
3
+ import React4__default, { useMemo, useCallback } from 'react';
4
4
  import { AnimatePresence, motion } from 'framer-motion';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
@@ -19,10 +19,10 @@ function DynamicIcon({
19
19
  className,
20
20
  alt
21
21
  }) {
22
- const [svgContent, setSvgContent] = React.useState(null);
23
- const [isLoading, setIsLoading] = React.useState(true);
24
- const [error, setError] = React.useState(null);
25
- const { url, iconName } = React.useMemo(() => {
22
+ const [svgContent, setSvgContent] = React4.useState(null);
23
+ const [isLoading, setIsLoading] = React4.useState(true);
24
+ const [error, setError] = React4.useState(null);
25
+ const { url, iconName } = React4.useMemo(() => {
26
26
  const separator = name.includes("/") ? "/" : ":";
27
27
  const [prefix, iconName2] = name.split(separator);
28
28
  const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
@@ -31,7 +31,7 @@ function DynamicIcon({
31
31
  iconName: iconName2
32
32
  };
33
33
  }, [name, size]);
34
- React.useEffect(() => {
34
+ React4.useEffect(() => {
35
35
  let isMounted = true;
36
36
  const fetchSvg = async () => {
37
37
  const cached = svgCache.get(url);
@@ -125,7 +125,7 @@ var maxWidthStyles = {
125
125
  "4xl": "max-w-[1536px]",
126
126
  full: "max-w-full"
127
127
  };
128
- var Container = React__default.forwardRef(
128
+ var Container = React4__default.forwardRef(
129
129
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
130
130
  const Component = as;
131
131
  return /* @__PURE__ */ jsx(
@@ -430,7 +430,7 @@ var spacingStyles = {
430
430
  };
431
431
  var predefinedSpacings = ["none", "sm", "md", "lg", "xl"];
432
432
  var isPredefinedSpacing = (spacing) => predefinedSpacings.includes(spacing);
433
- var Section = React__default.forwardRef(
433
+ var Section = React4__default.forwardRef(
434
434
  ({
435
435
  id,
436
436
  title,
@@ -491,7 +491,7 @@ var Section = React__default.forwardRef(
491
491
  }
492
492
  );
493
493
  Section.displayName = "Section";
494
- var Controls = ({
494
+ var Controls = React4.memo(({
495
495
  handleNext,
496
496
  handlePrevious,
497
497
  isPreviousDisabled,
@@ -519,9 +519,9 @@ var Controls = ({
519
519
  }
520
520
  )
521
521
  ] });
522
- };
523
- var FeatureCard = ({ feature, isActive, onClick }) => {
524
- const variants = {
522
+ });
523
+ var FeatureCard = React4.memo(({ feature, isActive, onClick }) => {
524
+ const variants = useMemo(() => ({
525
525
  initial: {
526
526
  opacity: 0
527
527
  },
@@ -531,7 +531,7 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
531
531
  exit: {
532
532
  opacity: 0
533
533
  }
534
- };
534
+ }), []);
535
535
  return /* @__PURE__ */ jsx(AnimatePresence, { mode: "popLayout", children: /* @__PURE__ */ jsx(
536
536
  motion.div,
537
537
  {
@@ -561,13 +561,13 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
561
561
  ease: "easeOut"
562
562
  },
563
563
  className: "p-6 text-sm md:p-8 md:text-base",
564
- children: /* @__PURE__ */ jsxs("p", { children: [
565
- /* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
564
+ children: (feature.title || feature.description) && /* @__PURE__ */ jsxs("p", { children: [
565
+ feature.title && /* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
566
566
  feature.title,
567
567
  "."
568
568
  ] }),
569
- " ",
570
- /* @__PURE__ */ jsx("span", { children: feature.description })
569
+ feature.title && feature.description && " ",
570
+ feature.description && /* @__PURE__ */ jsx("span", { children: feature.description })
571
571
  ] })
572
572
  },
573
573
  `feature-description-active-${feature.title}`
@@ -601,15 +601,15 @@ var FeatureCard = ({ feature, isActive, onClick }) => {
601
601
  className: "shrink-0"
602
602
  }
603
603
  ),
604
- /* @__PURE__ */ jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
604
+ feature.title && /* @__PURE__ */ jsx("p", { className: "shrink-0 font-semibold", children: feature.title })
605
605
  ]
606
606
  },
607
607
  `feature-description-inactive-${feature.title}`
608
608
  )
609
609
  }
610
610
  ) });
611
- };
612
- var FeaturesDesktop = ({
611
+ });
612
+ var FeaturesDesktop = React4.memo(({
613
613
  features,
614
614
  handleNext,
615
615
  handlePrevious,
@@ -640,8 +640,8 @@ var FeaturesDesktop = ({
640
640
  );
641
641
  }) })
642
642
  ] });
643
- };
644
- var FeaturesMobile = ({
643
+ });
644
+ var FeaturesMobile = React4.memo(({
645
645
  features,
646
646
  handleNext,
647
647
  handlePrevious,
@@ -650,7 +650,7 @@ var FeaturesMobile = ({
650
650
  isPreviousDisabled,
651
651
  isNextDisabled
652
652
  }) => {
653
- const variants = {
653
+ const variants = useMemo(() => ({
654
654
  enter: (direction2) => ({
655
655
  x: direction2 > 0 ? 100 : -100,
656
656
  opacity: 0
@@ -663,7 +663,8 @@ var FeaturesMobile = ({
663
663
  x: direction2 < 0 ? 100 : -100,
664
664
  opacity: 0
665
665
  })
666
- };
666
+ }), []);
667
+ const currentFeature = features[activeIndex];
667
668
  return /* @__PURE__ */ jsx("div", { className: "relative z-10 flex flex-col items-center gap-6 md:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between gap-4", children: [
668
669
  /* @__PURE__ */ jsx(
669
670
  "button",
@@ -688,13 +689,13 @@ var FeaturesMobile = ({
688
689
  opacity: { duration: 0.2 }
689
690
  },
690
691
  className: "absolute inset-0 flex items-center justify-center rounded-3xl bg-background p-4",
691
- children: /* @__PURE__ */ jsxs("p", { className: "text-center text-sm", children: [
692
- /* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
693
- features[activeIndex].title,
692
+ children: (currentFeature?.title || currentFeature?.description) && /* @__PURE__ */ jsxs("p", { className: "text-center text-sm", children: [
693
+ currentFeature.title && /* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
694
+ currentFeature.title,
694
695
  "."
695
696
  ] }),
696
- " ",
697
- /* @__PURE__ */ jsx("span", { children: features[activeIndex].description })
697
+ currentFeature.title && currentFeature.description && " ",
698
+ currentFeature.description && /* @__PURE__ */ jsx("span", { children: currentFeature.description })
698
699
  ] })
699
700
  },
700
701
  activeIndex
@@ -710,9 +711,9 @@ var FeaturesMobile = ({
710
711
  }
711
712
  )
712
713
  ] }) });
713
- };
714
+ });
714
715
  function FeatureAnimatedCarousel({
715
- features = [],
716
+ features,
716
717
  className,
717
718
  optixFlowConfig,
718
719
  background,
@@ -721,27 +722,27 @@ function FeatureAnimatedCarousel({
721
722
  patternOpacity,
722
723
  patternClassName
723
724
  }) {
724
- const [activeIndex, setActiveIndex] = React.useState(0);
725
- const [direction, setDirection] = React.useState(1);
726
- const handleNext = () => {
727
- if (activeIndex < features.length - 1) {
725
+ const [activeIndex, setActiveIndex] = React4.useState(0);
726
+ const [direction, setDirection] = React4.useState(1);
727
+ const handleNext = useCallback(() => {
728
+ if (features && activeIndex < features.length - 1) {
728
729
  setDirection(1);
729
730
  setActiveIndex(activeIndex + 1);
730
731
  }
731
- };
732
- const handlePrevious = () => {
732
+ }, [activeIndex, features]);
733
+ const handlePrevious = useCallback(() => {
733
734
  if (activeIndex > 0) {
734
735
  setDirection(-1);
735
736
  setActiveIndex(activeIndex - 1);
736
737
  }
737
- };
738
- const handleFeatureClick = (index) => {
738
+ }, [activeIndex]);
739
+ const handleFeatureClick = useCallback((index) => {
739
740
  setDirection(index > activeIndex ? 1 : -1);
740
741
  setActiveIndex(index);
741
- };
742
+ }, [activeIndex]);
742
743
  const isPreviousDisabled = activeIndex === 0;
743
- const isNextDisabled = activeIndex === features.length - 1;
744
- const imageVariants = {
744
+ const isNextDisabled = !features || activeIndex === features.length - 1;
745
+ const imageVariants = useMemo(() => ({
745
746
  enter: (direction2) => ({
746
747
  x: direction2 > 0 ? 300 : -300,
747
748
  opacity: 0
@@ -754,7 +755,22 @@ function FeatureAnimatedCarousel({
754
755
  x: direction2 < 0 ? 300 : -300,
755
756
  opacity: 0
756
757
  })
757
- };
758
+ }), []);
759
+ if (!features || features.length === 0) {
760
+ return /* @__PURE__ */ jsx(
761
+ Section,
762
+ {
763
+ background,
764
+ spacing,
765
+ pattern,
766
+ patternOpacity,
767
+ patternClassName,
768
+ className,
769
+ children: /* @__PURE__ */ jsx("div", { className: "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl bg-muted p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]" })
770
+ }
771
+ );
772
+ }
773
+ const currentFeature = features[activeIndex];
758
774
  return /* @__PURE__ */ jsx(
759
775
  Section,
760
776
  {
@@ -765,7 +781,7 @@ function FeatureAnimatedCarousel({
765
781
  patternClassName,
766
782
  className,
767
783
  children: /* @__PURE__ */ jsxs("div", { className: "relative flex min-h-[500px] flex-col-reverse gap-8 overflow-hidden rounded-3xl bg-muted p-6 md:flex-row md:items-center md:p-12 lg:min-h-[600px]", children: [
768
- features && /* @__PURE__ */ jsx(
784
+ /* @__PURE__ */ jsx(
769
785
  FeaturesDesktop,
770
786
  {
771
787
  features,
@@ -777,7 +793,7 @@ function FeatureAnimatedCarousel({
777
793
  isNextDisabled
778
794
  }
779
795
  ),
780
- features && /* @__PURE__ */ jsx(
796
+ /* @__PURE__ */ jsx(
781
797
  FeaturesMobile,
782
798
  {
783
799
  features,
@@ -789,7 +805,7 @@ function FeatureAnimatedCarousel({
789
805
  isNextDisabled
790
806
  }
791
807
  ),
792
- /* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsx(
808
+ currentFeature?.image && /* @__PURE__ */ jsx("div", { className: "relative flex-1 overflow-hidden rounded-2xl md:absolute md:right-8 md:top-8 md:bottom-8 md:w-1/2", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", custom: direction, children: /* @__PURE__ */ jsx(
793
809
  motion.div,
794
810
  {
795
811
  custom: direction,
@@ -805,8 +821,8 @@ function FeatureAnimatedCarousel({
805
821
  children: /* @__PURE__ */ jsx(
806
822
  Img,
807
823
  {
808
- src: features ? features[activeIndex].image : void 0,
809
- alt: features ? features[activeIndex].imageAlt || (typeof features[activeIndex].title === "string" ? features[activeIndex].title : "Feature image") : void 0,
824
+ src: currentFeature.image,
825
+ alt: currentFeature.imageAlt || (typeof currentFeature.title === "string" ? currentFeature.title : "Feature image"),
810
826
  className: "h-full w-full object-cover",
811
827
  optixFlowConfig
812
828
  }
@@ -989,7 +989,7 @@ function FeatureBadgeGridSix({
989
989
  if (!label) return null;
990
990
  return /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: badgeClassName, children: label });
991
991
  }, [badgeSlot, label, badgeClassName]);
992
- const renderFeatureIcon = (feature) => {
992
+ const renderFeatureIcon = React.useCallback((feature) => {
993
993
  if (feature.icon) return feature.icon;
994
994
  if (feature.iconName) {
995
995
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1002,25 +1002,28 @@ function FeatureBadgeGridSix({
1002
1002
  );
1003
1003
  }
1004
1004
  return null;
1005
- };
1005
+ }, []);
1006
1006
  const featuresContent = React.useMemo(() => {
1007
1007
  if (featuresSlot) return featuresSlot;
1008
1008
  if (!features || features.length === 0) return null;
1009
- return features.map((feature, index) => /* @__PURE__ */ jsxRuntime.jsxs(
1010
- "div",
1011
- {
1012
- className: cn("flex gap-6 space-y-4 rounded-lg md:block", cardClassName, feature.className),
1013
- children: [
1014
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", children: renderFeatureIcon(feature) }),
1015
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1016
- feature.heading && (typeof feature.heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.headingClassName), children: feature.heading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.headingClassName), children: feature.heading })),
1017
- feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }))
1018
- ] })
1019
- ]
1020
- },
1021
- index
1022
- ));
1023
- }, [featuresSlot, features, cardClassName]);
1009
+ return features.map((feature, index) => {
1010
+ const iconContent = renderFeatureIcon(feature);
1011
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1012
+ "div",
1013
+ {
1014
+ className: cn("flex gap-6 space-y-4 rounded-lg md:block", cardClassName, feature.className),
1015
+ children: [
1016
+ iconContent && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", children: iconContent }),
1017
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1018
+ feature.heading && (typeof feature.heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.headingClassName), children: feature.heading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.headingClassName), children: feature.heading })),
1019
+ feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }))
1020
+ ] })
1021
+ ]
1022
+ },
1023
+ index
1024
+ );
1025
+ });
1026
+ }, [featuresSlot, features, cardClassName, renderFeatureIcon]);
1024
1027
  const actionContent = React.useMemo(() => {
1025
1028
  if (actionSlot) return actionSlot;
1026
1029
  if (!action) return null;