@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
@@ -527,39 +527,37 @@ function FeatureIconGridBordered({
527
527
  patternOpacity,
528
528
  patternClassName
529
529
  }) {
530
+ const renderIcon = React.useCallback((feature) => {
531
+ if (feature.icon) return feature.icon;
532
+ if (feature.iconName) {
533
+ return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: feature.iconName, size: 20, className: "md:size-6" });
534
+ }
535
+ return null;
536
+ }, []);
530
537
  const featuresContent = React.useMemo(() => {
531
538
  if (featuresSlot) return featuresSlot;
532
539
  if (!features || features.length === 0) return null;
533
- return features.map((feature, index) => {
534
- const renderIcon = () => {
535
- if (feature.icon) return feature.icon;
536
- if (feature.iconName) {
537
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: feature.iconName, size: 20, className: "md:size-6" });
538
- }
539
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/star", size: 20, className: "md:size-6" });
540
- };
541
- return /* @__PURE__ */ jsxRuntime.jsxs(
542
- "div",
543
- {
544
- className: cn("relative flex gap-3 rounded-lg border-dashed md:block md:border-l md:p-5", cardClassName, feature.className),
545
- children: [
546
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("mb-8 flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", feature.iconClassName), children: renderIcon() }),
547
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
548
- feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
549
- feature.title,
550
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
551
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
552
- feature.title,
553
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
554
- ] })),
555
- 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 }))
556
- ] })
557
- ]
558
- },
559
- index
560
- );
561
- });
562
- }, [featuresSlot, features, cardClassName]);
540
+ return features.map((feature, index) => /* @__PURE__ */ jsxRuntime.jsxs(
541
+ "div",
542
+ {
543
+ className: cn("relative flex gap-3 rounded-lg border-dashed md:block md:border-l md:p-5", cardClassName, feature.className),
544
+ children: [
545
+ (feature.icon || feature.iconName) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("mb-8 flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", feature.iconClassName), children: renderIcon(feature) }),
546
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
547
+ feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
548
+ feature.title,
549
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
550
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
551
+ feature.title,
552
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
553
+ ] })),
554
+ 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 }))
555
+ ] })
556
+ ]
557
+ },
558
+ index
559
+ ));
560
+ }, [featuresSlot, features, cardClassName, renderIcon]);
563
561
  return /* @__PURE__ */ jsxRuntime.jsxs(
564
562
  Section,
565
563
  {
@@ -573,7 +571,7 @@ function FeatureIconGridBordered({
573
571
  children: [
574
572
  label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mb-4 text-xs text-muted-foreground", labelClassName), children: label }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mb-4 text-xs text-muted-foreground", labelClassName), children: label })),
575
573
  title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: cn("text-3xl font-medium lg:text-4xl", titleClassName), children: title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-3xl font-medium lg:text-4xl", titleClassName), children: title })),
576
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-14 grid gap-6 md:grid-cols-2 lg:mt-20 lg:grid-cols-4", gridClassName), children: featuresContent })
574
+ (featuresSlot || features && features.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-14 grid gap-6 md:grid-cols-2 lg:mt-20 lg:grid-cols-4", gridClassName), children: featuresContent })
577
575
  ]
578
576
  }
579
577
  );
@@ -17,11 +17,11 @@ interface FeatureIconGridBorderedItem {
17
17
  */
18
18
  iconName?: string;
19
19
  /**
20
- * Feature title content
20
+ * Item title content
21
21
  */
22
22
  title?: React.ReactNode;
23
23
  /**
24
- * Feature description content
24
+ * Item description content
25
25
  */
26
26
  description?: React.ReactNode;
27
27
  /**
@@ -51,11 +51,11 @@ interface FeatureIconGridBorderedProps {
51
51
  */
52
52
  title?: React.ReactNode;
53
53
  /**
54
- * Array of feature items to display
54
+ * Array of items to display
55
55
  */
56
56
  features?: FeatureIconGridBorderedItem[];
57
57
  /**
58
- * Custom slot for rendering features (overrides features array)
58
+ * Custom slot for rendering items (overrides features array)
59
59
  */
60
60
  featuresSlot?: React.ReactNode;
61
61
  /**
@@ -79,7 +79,7 @@ interface FeatureIconGridBorderedProps {
79
79
  */
80
80
  gridClassName?: string;
81
81
  /**
82
- * Additional CSS classes for each feature card
82
+ * Additional CSS classes for each card
83
83
  */
84
84
  cardClassName?: string;
85
85
  /**
@@ -104,18 +104,18 @@ interface FeatureIconGridBorderedProps {
104
104
  patternClassName?: string;
105
105
  }
106
106
  /**
107
- * Feature Icon Grid Bordered - Four-column grid of features with icons and
107
+ * Feature Icon Grid Bordered - Four-column grid of items with icons and
108
108
  * dashed left borders creating a visual timeline effect.
109
109
  *
110
110
  * Layout: Four-column responsive grid with icon badges and dashed borders.
111
111
  * Key features: Icon badges in accent circles, dashed border separators, accent line indicators.
112
- * Best for: Why us sections, value propositions, capability highlights, process steps.
112
+ * Best for: Value propositions, capability highlights, process steps, benefits showcase.
113
113
  *
114
114
  * @example
115
115
  * ```tsx
116
116
  * <FeatureIconGridBordered
117
- * label="Why Us?"
118
- * title="A better way to build websites"
117
+ * label="Why Choose Us?"
118
+ * title="A better way to build"
119
119
  * features={[
120
120
  * { iconName: "lucide/timer", title: "Performance", description: "Fast and optimized" },
121
121
  * { iconName: "lucide/zap", title: "Innovation", description: "Cutting-edge tech" },
@@ -17,11 +17,11 @@ interface FeatureIconGridBorderedItem {
17
17
  */
18
18
  iconName?: string;
19
19
  /**
20
- * Feature title content
20
+ * Item title content
21
21
  */
22
22
  title?: React.ReactNode;
23
23
  /**
24
- * Feature description content
24
+ * Item description content
25
25
  */
26
26
  description?: React.ReactNode;
27
27
  /**
@@ -51,11 +51,11 @@ interface FeatureIconGridBorderedProps {
51
51
  */
52
52
  title?: React.ReactNode;
53
53
  /**
54
- * Array of feature items to display
54
+ * Array of items to display
55
55
  */
56
56
  features?: FeatureIconGridBorderedItem[];
57
57
  /**
58
- * Custom slot for rendering features (overrides features array)
58
+ * Custom slot for rendering items (overrides features array)
59
59
  */
60
60
  featuresSlot?: React.ReactNode;
61
61
  /**
@@ -79,7 +79,7 @@ interface FeatureIconGridBorderedProps {
79
79
  */
80
80
  gridClassName?: string;
81
81
  /**
82
- * Additional CSS classes for each feature card
82
+ * Additional CSS classes for each card
83
83
  */
84
84
  cardClassName?: string;
85
85
  /**
@@ -104,18 +104,18 @@ interface FeatureIconGridBorderedProps {
104
104
  patternClassName?: string;
105
105
  }
106
106
  /**
107
- * Feature Icon Grid Bordered - Four-column grid of features with icons and
107
+ * Feature Icon Grid Bordered - Four-column grid of items with icons and
108
108
  * dashed left borders creating a visual timeline effect.
109
109
  *
110
110
  * Layout: Four-column responsive grid with icon badges and dashed borders.
111
111
  * Key features: Icon badges in accent circles, dashed border separators, accent line indicators.
112
- * Best for: Why us sections, value propositions, capability highlights, process steps.
112
+ * Best for: Value propositions, capability highlights, process steps, benefits showcase.
113
113
  *
114
114
  * @example
115
115
  * ```tsx
116
116
  * <FeatureIconGridBordered
117
- * label="Why Us?"
118
- * title="A better way to build websites"
117
+ * label="Why Choose Us?"
118
+ * title="A better way to build"
119
119
  * features={[
120
120
  * { iconName: "lucide/timer", title: "Performance", description: "Fast and optimized" },
121
121
  * { iconName: "lucide/zap", title: "Innovation", description: "Cutting-edge tech" },
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import * as React from 'react';
3
- import React__default, { useMemo } from 'react';
3
+ import React__default, { useCallback, useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -506,39 +506,37 @@ function FeatureIconGridBordered({
506
506
  patternOpacity,
507
507
  patternClassName
508
508
  }) {
509
+ const renderIcon = useCallback((feature) => {
510
+ if (feature.icon) return feature.icon;
511
+ if (feature.iconName) {
512
+ return /* @__PURE__ */ jsx(DynamicIcon, { name: feature.iconName, size: 20, className: "md:size-6" });
513
+ }
514
+ return null;
515
+ }, []);
509
516
  const featuresContent = useMemo(() => {
510
517
  if (featuresSlot) return featuresSlot;
511
518
  if (!features || features.length === 0) return null;
512
- return features.map((feature, index) => {
513
- const renderIcon = () => {
514
- if (feature.icon) return feature.icon;
515
- if (feature.iconName) {
516
- return /* @__PURE__ */ jsx(DynamicIcon, { name: feature.iconName, size: 20, className: "md:size-6" });
517
- }
518
- return /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/star", size: 20, className: "md:size-6" });
519
- };
520
- return /* @__PURE__ */ jsxs(
521
- "div",
522
- {
523
- className: cn("relative flex gap-3 rounded-lg border-dashed md:block md:border-l md:p-5", cardClassName, feature.className),
524
- children: [
525
- /* @__PURE__ */ jsx("span", { className: cn("mb-8 flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", feature.iconClassName), children: renderIcon() }),
526
- /* @__PURE__ */ jsxs("div", { children: [
527
- feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxs("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
528
- feature.title,
529
- /* @__PURE__ */ jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
530
- ] }) : /* @__PURE__ */ jsxs("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
531
- feature.title,
532
- /* @__PURE__ */ jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
533
- ] })),
534
- feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsx("div", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }))
535
- ] })
536
- ]
537
- },
538
- index
539
- );
540
- });
541
- }, [featuresSlot, features, cardClassName]);
519
+ return features.map((feature, index) => /* @__PURE__ */ jsxs(
520
+ "div",
521
+ {
522
+ className: cn("relative flex gap-3 rounded-lg border-dashed md:block md:border-l md:p-5", cardClassName, feature.className),
523
+ children: [
524
+ (feature.icon || feature.iconName) && /* @__PURE__ */ jsx("span", { className: cn("mb-8 flex size-10 shrink-0 items-center justify-center rounded-full bg-accent md:size-12", feature.iconClassName), children: renderIcon(feature) }),
525
+ /* @__PURE__ */ jsxs("div", { children: [
526
+ feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxs("h3", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
527
+ feature.title,
528
+ /* @__PURE__ */ jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
529
+ ] }) : /* @__PURE__ */ jsxs("div", { className: cn("font-medium md:mb-2 md:text-xl", feature.titleClassName), children: [
530
+ feature.title,
531
+ /* @__PURE__ */ jsx("span", { className: "absolute -left-px hidden h-6 w-px bg-primary md:inline-block" })
532
+ ] })),
533
+ feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsx("div", { className: cn("text-sm text-muted-foreground md:text-base", feature.descriptionClassName), children: feature.description }))
534
+ ] })
535
+ ]
536
+ },
537
+ index
538
+ ));
539
+ }, [featuresSlot, features, cardClassName, renderIcon]);
542
540
  return /* @__PURE__ */ jsxs(
543
541
  Section,
544
542
  {
@@ -552,7 +550,7 @@ function FeatureIconGridBordered({
552
550
  children: [
553
551
  label && (typeof label === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mb-4 text-xs text-muted-foreground", labelClassName), children: label }) : /* @__PURE__ */ jsx("div", { className: cn("mb-4 text-xs text-muted-foreground", labelClassName), children: label })),
554
552
  title && (typeof title === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-3xl font-medium lg:text-4xl", titleClassName), children: title }) : /* @__PURE__ */ jsx("div", { className: cn("text-3xl font-medium lg:text-4xl", titleClassName), children: title })),
555
- /* @__PURE__ */ jsx("div", { className: cn("mt-14 grid gap-6 md:grid-cols-2 lg:mt-20 lg:grid-cols-4", gridClassName), children: featuresContent })
553
+ (featuresSlot || features && features.length > 0) && /* @__PURE__ */ jsx("div", { className: cn("mt-14 grid gap-6 md:grid-cols-2 lg:mt-20 lg:grid-cols-4", gridClassName), children: featuresContent })
556
554
  ]
557
555
  }
558
556
  );
@@ -528,11 +528,11 @@ function FeatureIconGridMuted({
528
528
  patternOpacity,
529
529
  patternClassName
530
530
  }) {
531
- const renderFeatureIcon = (feature) => {
531
+ const renderFeatureIcon = React.useCallback((feature) => {
532
532
  if (feature.icon) return feature.icon;
533
533
  if (feature.iconName) return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: feature.iconName, size: 24, className: feature.iconClassName });
534
534
  return null;
535
- };
535
+ }, []);
536
536
  const featuresContent = React.useMemo(() => {
537
537
  if (featuresSlot) return featuresSlot;
538
538
  if (!features || features.length === 0) return null;
@@ -541,14 +541,14 @@ function FeatureIconGridMuted({
541
541
  {
542
542
  className: cn("flex flex-col gap-2.5 rounded-xl border bg-background p-7", cardClassName, feature.className),
543
543
  children: [
544
- renderFeatureIcon(feature),
544
+ (feature.icon || feature.iconName) && renderFeatureIcon(feature),
545
545
  feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("font-semibold", feature.titleClassName), children: feature.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("font-semibold", feature.titleClassName), children: feature.title })),
546
546
  feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm text-muted-foreground", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-sm text-muted-foreground", feature.descriptionClassName), children: feature.description }))
547
547
  ]
548
548
  },
549
549
  index
550
550
  ));
551
- }, [featuresSlot, features, cardClassName]);
551
+ }, [featuresSlot, features, cardClassName, renderFeatureIcon]);
552
552
  return /* @__PURE__ */ jsxRuntime.jsx(
553
553
  Section,
554
554
  {
@@ -560,11 +560,11 @@ function FeatureIconGridMuted({
560
560
  className: cn("bg-muted/60", className),
561
561
  containerClassName,
562
562
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-10", children: [
563
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mx-auto flex max-w-xl flex-col gap-2.5 text-center", headerClassName), children: [
563
+ (title || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("mx-auto flex max-w-xl flex-col gap-2.5 text-center", headerClassName), children: [
564
564
  title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("text-4xl font-semibold md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-4xl font-semibold md:text-5xl", titleClassName), children: title })),
565
565
  description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-muted-foreground", descriptionClassName), children: description }))
566
566
  ] }),
567
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-auto grid max-w-7xl gap-7 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", gridClassName), children: featuresContent })
567
+ (featuresSlot || features && features.length > 0) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-auto grid max-w-7xl gap-7 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", gridClassName), children: featuresContent })
568
568
  ] })
569
569
  }
570
570
  );
@@ -17,11 +17,11 @@ interface FeatureIconGridMutedItem {
17
17
  */
18
18
  iconName?: string;
19
19
  /**
20
- * Feature title content
20
+ * Item title content
21
21
  */
22
22
  title?: React.ReactNode;
23
23
  /**
24
- * Feature description content
24
+ * Item description content
25
25
  */
26
26
  description?: React.ReactNode;
27
27
  /**
@@ -51,11 +51,11 @@ interface FeatureIconGridMutedProps {
51
51
  */
52
52
  description?: React.ReactNode;
53
53
  /**
54
- * Array of feature items
54
+ * Array of items to display
55
55
  */
56
56
  features?: FeatureIconGridMutedItem[];
57
57
  /**
58
- * Custom slot for rendering features (overrides features array)
58
+ * Custom slot for rendering items (overrides features array)
59
59
  */
60
60
  featuresSlot?: React.ReactNode;
61
61
  /**
@@ -108,20 +108,20 @@ interface FeatureIconGridMutedProps {
108
108
  patternClassName?: string;
109
109
  }
110
110
  /**
111
- * Feature Icon Grid Muted - Five-feature grid with muted background and
111
+ * Feature Icon Grid Muted - Five-column grid with muted background and
112
112
  * icon badges showcasing key capabilities.
113
113
  *
114
114
  * Layout: Muted background section with centered header and five-column grid.
115
115
  * Key features: Muted background, icon badges, centered text, responsive grid.
116
- * Best for: Key features, time-saving tools, capability highlights.
116
+ * Best for: Capability highlights, benefits showcase, service offerings.
117
117
  *
118
118
  * @example
119
119
  * ```tsx
120
120
  * <FeatureIconGridMuted
121
- * title="Key Features That Save You Time"
122
- * description="Explore tools specifically built to enhance your workflow."
121
+ * title="Key Capabilities"
122
+ * description="Explore tools built to enhance your workflow."
123
123
  * features={[
124
- * { iconName: "lucide/check-circle-2", title: "Instant Approvals", description: "Get quick approvals" },
124
+ * { iconName: "lucide/check-circle-2", title: "Quick Processing", description: "Fast results" },
125
125
  * ]}
126
126
  * />
127
127
  * ```
@@ -17,11 +17,11 @@ interface FeatureIconGridMutedItem {
17
17
  */
18
18
  iconName?: string;
19
19
  /**
20
- * Feature title content
20
+ * Item title content
21
21
  */
22
22
  title?: React.ReactNode;
23
23
  /**
24
- * Feature description content
24
+ * Item description content
25
25
  */
26
26
  description?: React.ReactNode;
27
27
  /**
@@ -51,11 +51,11 @@ interface FeatureIconGridMutedProps {
51
51
  */
52
52
  description?: React.ReactNode;
53
53
  /**
54
- * Array of feature items
54
+ * Array of items to display
55
55
  */
56
56
  features?: FeatureIconGridMutedItem[];
57
57
  /**
58
- * Custom slot for rendering features (overrides features array)
58
+ * Custom slot for rendering items (overrides features array)
59
59
  */
60
60
  featuresSlot?: React.ReactNode;
61
61
  /**
@@ -108,20 +108,20 @@ interface FeatureIconGridMutedProps {
108
108
  patternClassName?: string;
109
109
  }
110
110
  /**
111
- * Feature Icon Grid Muted - Five-feature grid with muted background and
111
+ * Feature Icon Grid Muted - Five-column grid with muted background and
112
112
  * icon badges showcasing key capabilities.
113
113
  *
114
114
  * Layout: Muted background section with centered header and five-column grid.
115
115
  * Key features: Muted background, icon badges, centered text, responsive grid.
116
- * Best for: Key features, time-saving tools, capability highlights.
116
+ * Best for: Capability highlights, benefits showcase, service offerings.
117
117
  *
118
118
  * @example
119
119
  * ```tsx
120
120
  * <FeatureIconGridMuted
121
- * title="Key Features That Save You Time"
122
- * description="Explore tools specifically built to enhance your workflow."
121
+ * title="Key Capabilities"
122
+ * description="Explore tools built to enhance your workflow."
123
123
  * features={[
124
- * { iconName: "lucide/check-circle-2", title: "Instant Approvals", description: "Get quick approvals" },
124
+ * { iconName: "lucide/check-circle-2", title: "Quick Processing", description: "Fast results" },
125
125
  * ]}
126
126
  * />
127
127
  * ```
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import * as React from 'react';
3
- import React__default, { useMemo } from 'react';
3
+ import React__default, { useCallback, useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -507,11 +507,11 @@ function FeatureIconGridMuted({
507
507
  patternOpacity,
508
508
  patternClassName
509
509
  }) {
510
- const renderFeatureIcon = (feature) => {
510
+ const renderFeatureIcon = useCallback((feature) => {
511
511
  if (feature.icon) return feature.icon;
512
512
  if (feature.iconName) return /* @__PURE__ */ jsx(DynamicIcon, { name: feature.iconName, size: 24, className: feature.iconClassName });
513
513
  return null;
514
- };
514
+ }, []);
515
515
  const featuresContent = useMemo(() => {
516
516
  if (featuresSlot) return featuresSlot;
517
517
  if (!features || features.length === 0) return null;
@@ -520,14 +520,14 @@ function FeatureIconGridMuted({
520
520
  {
521
521
  className: cn("flex flex-col gap-2.5 rounded-xl border bg-background p-7", cardClassName, feature.className),
522
522
  children: [
523
- renderFeatureIcon(feature),
523
+ (feature.icon || feature.iconName) && renderFeatureIcon(feature),
524
524
  feature.title && (typeof feature.title === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("font-semibold", feature.titleClassName), children: feature.title }) : /* @__PURE__ */ jsx("div", { className: cn("font-semibold", feature.titleClassName), children: feature.title })),
525
525
  feature.description && (typeof feature.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground", feature.descriptionClassName), children: feature.description }) : /* @__PURE__ */ jsx("div", { className: cn("text-sm text-muted-foreground", feature.descriptionClassName), children: feature.description }))
526
526
  ]
527
527
  },
528
528
  index
529
529
  ));
530
- }, [featuresSlot, features, cardClassName]);
530
+ }, [featuresSlot, features, cardClassName, renderFeatureIcon]);
531
531
  return /* @__PURE__ */ jsx(
532
532
  Section,
533
533
  {
@@ -539,11 +539,11 @@ function FeatureIconGridMuted({
539
539
  className: cn("bg-muted/60", className),
540
540
  containerClassName,
541
541
  children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-10", children: [
542
- /* @__PURE__ */ jsxs("div", { className: cn("mx-auto flex max-w-xl flex-col gap-2.5 text-center", headerClassName), children: [
542
+ (title || description) && /* @__PURE__ */ jsxs("div", { className: cn("mx-auto flex max-w-xl flex-col gap-2.5 text-center", headerClassName), children: [
543
543
  title && (typeof title === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("text-4xl font-semibold md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsx("div", { className: cn("text-4xl font-semibold md:text-5xl", titleClassName), children: title })),
544
544
  description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground", descriptionClassName), children: description }))
545
545
  ] }),
546
- /* @__PURE__ */ jsx("div", { className: cn("mx-auto grid max-w-7xl gap-7 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", gridClassName), children: featuresContent })
546
+ (featuresSlot || features && features.length > 0) && /* @__PURE__ */ jsx("div", { className: cn("mx-auto grid max-w-7xl gap-7 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5", gridClassName), children: featuresContent })
547
547
  ] })
548
548
  }
549
549
  );
@@ -1047,12 +1047,12 @@ function FeatureIconTabsContent({
1047
1047
  patternOpacity,
1048
1048
  patternClassName
1049
1049
  }) {
1050
- const renderTabIcon = React.useMemo(() => (tab) => {
1050
+ const renderTabIcon = React.useCallback((tab) => {
1051
1051
  if (tab.icon) return tab.icon;
1052
1052
  if (tab.iconName) return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: tab.iconName, size: 16 });
1053
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/star", size: 16 });
1053
+ return null;
1054
1054
  }, []);
1055
- const renderTabContentActions = React.useMemo(() => (content) => {
1055
+ const renderTabContentActions = React.useCallback((content) => {
1056
1056
  if (content.actionsSlot) return content.actionsSlot;
1057
1057
  if (!content.actions || content.actions.length === 0) return null;
1058
1058
  return content.actions.map((action, index) => {
@@ -1092,7 +1092,7 @@ function FeatureIconTabsContent({
1092
1092
  );
1093
1093
  });
1094
1094
  }, []);
1095
- const renderTabContentImage = React.useMemo(() => (content) => {
1095
+ const renderTabContentImage = React.useCallback((content) => {
1096
1096
  if (content.imageSlot) return content.imageSlot;
1097
1097
  if (content.imageSrc) {
1098
1098
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1119,7 +1119,7 @@ function FeatureIconTabsContent({
1119
1119
  value: tab.value,
1120
1120
  className: cn("flex items-center gap-2 rounded-xl px-4 py-3 text-sm font-semibold text-muted-foreground data-[state=active]:bg-muted data-[state=active]:text-primary", tabTriggerClassName, tab.className),
1121
1121
  children: [
1122
- renderTabIcon(tab),
1122
+ (tab.icon || tab.iconName) && renderTabIcon(tab),
1123
1123
  tab.label
1124
1124
  ]
1125
1125
  },
@@ -1141,9 +1141,9 @@ function FeatureIconTabsContent({
1141
1141
  content.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: cn("w-fit bg-background", content.badgeClassName), children: content.badge }),
1142
1142
  content.title && (typeof content.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("text-3xl font-semibold lg:text-5xl", content.titleClassName), children: content.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-3xl font-semibold lg:text-5xl", content.titleClassName), children: content.title })),
1143
1143
  content.description && (typeof content.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground lg:text-lg", content.descriptionClassName), children: content.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-muted-foreground lg:text-lg", content.descriptionClassName), children: content.description })),
1144
- renderTabContentActions(content)
1144
+ (content.actionsSlot || content.actions && content.actions.length > 0) && renderTabContentActions(content)
1145
1145
  ] }),
1146
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-[300px] w-full lg:h-[400px]", children: renderTabContentImage(content) })
1146
+ (content.imageSlot || content.imageSrc) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-[300px] w-full lg:h-[400px]", children: renderTabContentImage(content) })
1147
1147
  ]
1148
1148
  },
1149
1149
  tab.value
@@ -1162,7 +1162,7 @@ function FeatureIconTabsContent({
1162
1162
  className,
1163
1163
  containerClassName: cn("mx-auto", containerClassName),
1164
1164
  children: [
1165
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-center gap-4 text-center", headerClassName), children: [
1165
+ (badge || heading || description) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-center gap-4 text-center", headerClassName), children: [
1166
1166
  badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: badgeClassName, children: badge }),
1167
1167
  heading && (typeof heading === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn("max-w-2xl text-3xl font-semibold md:text-4xl", headingClassName), children: heading }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("max-w-2xl text-3xl font-semibold md:text-4xl", headingClassName), children: heading })),
1168
1168
  description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-muted-foreground", descriptionClassName), children: description }))
@@ -21,7 +21,7 @@ interface FeatureIconTabsContentTabContent {
21
21
  */
22
22
  description?: React.ReactNode;
23
23
  /**
24
- * Array of action configurations for CTA buttons
24
+ * Array of action configurations for buttons
25
25
  */
26
26
  actions?: ActionConfig[];
27
27
  /**
@@ -183,29 +183,29 @@ interface FeatureIconTabsContentProps {
183
183
  }
184
184
  /**
185
185
  * Feature Icon Tabs Content - Tabbed interface with icon triggers and
186
- * content panels featuring images and CTAs.
186
+ * content panels featuring images and actions.
187
187
  *
188
188
  * Layout: Centered header with icon tabs, muted background content area.
189
- * Key features: Icon tab triggers, badge labels, CTA buttons, responsive images.
190
- * Best for: Feature categories, product tours, service breakdowns.
189
+ * Key features: Icon tab triggers, badge labels, action buttons, responsive images.
190
+ * Best for: Content categories, product tours, service breakdowns, multi-section showcases.
191
191
  *
192
192
  * @example
193
193
  * ```tsx
194
194
  * <FeatureIconTabsContent
195
- * badge="Features"
196
- * heading="A Collection of Components"
195
+ * badge="Overview"
196
+ * heading="Explore Our Offerings"
197
197
  * tabs={[
198
198
  * {
199
199
  * value: "tab-1",
200
200
  * iconName: "lucide/zap",
201
- * label: "Boost Revenue",
201
+ * label: "Performance",
202
202
  * content: {
203
- * badge: "Modern Tactics",
204
- * title: "Make your site stand out",
205
- * description: "Discover new web trends.",
206
- * actions: [{ label: "See Plans", href: "#", variant: "default" }],
207
- * imageSrc: "/feature.jpg",
208
- * imageAlt: "Feature"
203
+ * badge: "Speed",
204
+ * title: "Lightning Fast",
205
+ * description: "Optimized for performance.",
206
+ * actions: [{ label: "Learn More", href: "#", variant: "default" }],
207
+ * imageSrc: "/image.jpg",
208
+ * imageAlt: "Performance"
209
209
  * }
210
210
  * },
211
211
  * ]}