@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
@@ -1237,10 +1237,10 @@ function FeatureCarouselProgress({
1237
1237
  );
1238
1238
  });
1239
1239
  }, [api, slidesLength]);
1240
- const renderSlideIcon = React4.useMemo(() => (slide) => {
1240
+ const renderSlideIcon = React4.useCallback((slide) => {
1241
1241
  if (slide.icon) return slide.icon;
1242
1242
  if (slide.iconName) return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: slide.iconName, size: 16 });
1243
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/star", size: 16 });
1243
+ return null;
1244
1244
  }, []);
1245
1245
  const slidesContent = React4.useMemo(() => {
1246
1246
  if (slidesSlot) return slidesSlot;
@@ -1250,7 +1250,7 @@ function FeatureCarouselProgress({
1250
1250
  {
1251
1251
  className: "basis-full md:basis-1/2 lg:basis-1/3",
1252
1252
  children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-1", children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: cn(cardClassName, slide.className), children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "flex flex-col justify-center p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1253
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10", slide.iconClassName), children: renderSlideIcon(slide) }),
1253
+ (slide.icon || slide.iconName) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10", slide.iconClassName), children: renderSlideIcon(slide) }),
1254
1254
  slide.title && (typeof slide.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-xl font-semibold md:text-2xl lg:text-2xl", slide.titleClassName), children: slide.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-xl font-semibold md:text-2xl lg:text-2xl", slide.titleClassName), children: slide.title })),
1255
1255
  slide.description && (typeof slide.description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("pt-2 text-muted-foreground", slide.descriptionClassName), children: slide.description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("pt-2 text-muted-foreground", slide.descriptionClassName), children: slide.description }))
1256
1256
  ] }) }) }) })
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import * as React4 from 'react';
3
- import React4__default, { useState, useEffect, useMemo } from 'react';
3
+ import React4__default, { useState, useEffect, 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';
@@ -1212,10 +1212,10 @@ function FeatureCarouselProgress({
1212
1212
  );
1213
1213
  });
1214
1214
  }, [api, slidesLength]);
1215
- const renderSlideIcon = useMemo(() => (slide) => {
1215
+ const renderSlideIcon = useCallback((slide) => {
1216
1216
  if (slide.icon) return slide.icon;
1217
1217
  if (slide.iconName) return /* @__PURE__ */ jsx(DynamicIcon, { name: slide.iconName, size: 16 });
1218
- return /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/star", size: 16 });
1218
+ return null;
1219
1219
  }, []);
1220
1220
  const slidesContent = useMemo(() => {
1221
1221
  if (slidesSlot) return slidesSlot;
@@ -1225,7 +1225,7 @@ function FeatureCarouselProgress({
1225
1225
  {
1226
1226
  className: "basis-full md:basis-1/2 lg:basis-1/3",
1227
1227
  children: /* @__PURE__ */ jsx("div", { className: "p-1", children: /* @__PURE__ */ jsx(Card, { className: cn(cardClassName, slide.className), children: /* @__PURE__ */ jsx(CardContent, { className: "flex flex-col justify-center p-6", children: /* @__PURE__ */ jsxs("div", { children: [
1228
- /* @__PURE__ */ jsx("span", { className: cn("mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10", slide.iconClassName), children: renderSlideIcon(slide) }),
1228
+ (slide.icon || slide.iconName) && /* @__PURE__ */ jsx("span", { className: cn("mb-5 flex size-8 items-center justify-center rounded-full bg-accent lg:size-10", slide.iconClassName), children: renderSlideIcon(slide) }),
1229
1229
  slide.title && (typeof slide.title === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-xl font-semibold md:text-2xl lg:text-2xl", slide.titleClassName), children: slide.title }) : /* @__PURE__ */ jsx("div", { className: cn("text-xl font-semibold md:text-2xl lg:text-2xl", slide.titleClassName), children: slide.title })),
1230
1230
  slide.description && (typeof slide.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("pt-2 text-muted-foreground", slide.descriptionClassName), children: slide.description }) : /* @__PURE__ */ jsx("div", { className: cn("pt-2 text-muted-foreground", slide.descriptionClassName), children: slide.description }))
1231
1231
  ] }) }) }) })
@@ -501,7 +501,7 @@ function FeatureCategoryImageCards({
501
501
  patternOpacity,
502
502
  patternClassName
503
503
  }) {
504
- const renderFeatureImage = (feature) => {
504
+ const renderFeatureImage = React.useCallback((feature) => {
505
505
  if (feature.imageSlot) return feature.imageSlot;
506
506
  if (feature.imageSrc) {
507
507
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -516,7 +516,7 @@ function FeatureCategoryImageCards({
516
516
  );
517
517
  }
518
518
  return null;
519
- };
519
+ }, [optixFlowConfig]);
520
520
  const featuresContent = React.useMemo(() => {
521
521
  if (featuresSlot) return featuresSlot;
522
522
  if (!features || features.length === 0) return null;
@@ -527,7 +527,7 @@ function FeatureCategoryImageCards({
527
527
  ] }),
528
528
  /* @__PURE__ */ jsxRuntime.jsx(CardContent, { className: "px-7 pb-7", children: renderFeatureImage(feature) })
529
529
  ] }, index));
530
- }, [featuresSlot, features, cardClassName, optixFlowConfig]);
530
+ }, [featuresSlot, features, cardClassName, renderFeatureImage]);
531
531
  return /* @__PURE__ */ jsxRuntime.jsxs(
532
532
  Section,
533
533
  {
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import React, { useMemo } from 'react';
2
+ import React, { useCallback, useMemo } from 'react';
3
3
  import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { Slot } from '@radix-ui/react-slot';
@@ -495,7 +495,7 @@ function FeatureCategoryImageCards({
495
495
  patternOpacity,
496
496
  patternClassName
497
497
  }) {
498
- const renderFeatureImage = (feature) => {
498
+ const renderFeatureImage = useCallback((feature) => {
499
499
  if (feature.imageSlot) return feature.imageSlot;
500
500
  if (feature.imageSrc) {
501
501
  return /* @__PURE__ */ jsx(
@@ -510,7 +510,7 @@ function FeatureCategoryImageCards({
510
510
  );
511
511
  }
512
512
  return null;
513
- };
513
+ }, [optixFlowConfig]);
514
514
  const featuresContent = useMemo(() => {
515
515
  if (featuresSlot) return featuresSlot;
516
516
  if (!features || features.length === 0) return null;
@@ -521,7 +521,7 @@ function FeatureCategoryImageCards({
521
521
  ] }),
522
522
  /* @__PURE__ */ jsx(CardContent, { className: "px-7 pb-7", children: renderFeatureImage(feature) })
523
523
  ] }, index));
524
- }, [featuresSlot, features, cardClassName, optixFlowConfig]);
524
+ }, [featuresSlot, features, cardClassName, renderFeatureImage]);
525
525
  return /* @__PURE__ */ jsxs(
526
526
  Section,
527
527
  {
@@ -1039,8 +1039,8 @@ function FeatureChecklistImage({
1039
1039
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("lg:p-10", contentClassName), children: [
1040
1040
  title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: cn("text-3xl font-medium text-balance md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-3xl font-medium text-balance md:text-5xl", titleClassName), children: title })),
1041
1041
  description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("mt-1 text-muted-foreground md:mt-6", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-1 text-muted-foreground md:mt-6", descriptionClassName), children: description })),
1042
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: actionsClassName, children: actionsContent }),
1043
- /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("mt-10 flex-wrap items-center gap-6 space-y-6 md:flex md:space-y-0", checklistClassName), children: checklistContent })
1042
+ actionsContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: actionsClassName, children: actionsContent }),
1043
+ checklistContent && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("mt-10 flex-wrap items-center gap-6 space-y-6 md:flex md:space-y-0", checklistClassName), children: checklistContent })
1044
1044
  ] })
1045
1045
  ] })
1046
1046
  }
@@ -1018,8 +1018,8 @@ function FeatureChecklistImage({
1018
1018
  /* @__PURE__ */ jsxs("div", { className: cn("lg:p-10", contentClassName), children: [
1019
1019
  title && (typeof title === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-3xl font-medium text-balance md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsx("div", { className: cn("text-3xl font-medium text-balance md:text-5xl", titleClassName), children: title })),
1020
1020
  description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-muted-foreground md:mt-6", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: cn("mt-1 text-muted-foreground md:mt-6", descriptionClassName), children: description })),
1021
- /* @__PURE__ */ jsx("div", { className: actionsClassName, children: actionsContent }),
1022
- /* @__PURE__ */ jsx("ul", { className: cn("mt-10 flex-wrap items-center gap-6 space-y-6 md:flex md:space-y-0", checklistClassName), children: checklistContent })
1021
+ actionsContent && /* @__PURE__ */ jsx("div", { className: actionsClassName, children: actionsContent }),
1022
+ checklistContent && /* @__PURE__ */ jsx("ul", { className: cn("mt-10 flex-wrap items-center gap-6 space-y-6 md:flex md:space-y-0", checklistClassName), children: checklistContent })
1023
1023
  ] })
1024
1024
  ] })
1025
1025
  }
@@ -985,15 +985,15 @@ function FeatureChecklistThreeColumn({
985
985
  patternOpacity,
986
986
  patternClassName
987
987
  }) {
988
- const getCheckItemContent = React.useMemo(() => (item) => {
988
+ const getCheckItemContent = React.useCallback((item) => {
989
989
  if (typeof item === "string") return item;
990
990
  return item.content;
991
991
  }, []);
992
- const getCheckItemClassName = React.useMemo(() => (item) => {
992
+ const getCheckItemClassName = React.useCallback((item) => {
993
993
  if (typeof item === "string") return void 0;
994
994
  return item.className;
995
995
  }, []);
996
- const renderChecklistColumn = React.useMemo(() => (items, slot, gapClass) => {
996
+ const renderChecklistColumn = React.useCallback((items, slot, gapClass) => {
997
997
  if (slot) return slot;
998
998
  if (!items || items.length === 0) return null;
999
999
  return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("flex flex-col text-muted-foreground", gapClass, checklistClassName), children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cn("flex items-center gap-2", getCheckItemClassName(item)), children: [
@@ -1001,7 +1001,7 @@ function FeatureChecklistThreeColumn({
1001
1001
  getCheckItemContent(item)
1002
1002
  ] }, index)) });
1003
1003
  }, [checklistClassName, getCheckItemContent, getCheckItemClassName]);
1004
- const renderCardImage = React.useMemo(() => (card) => {
1004
+ const renderCardImage = React.useCallback((card) => {
1005
1005
  if (card.imageSlot) return card.imageSlot;
1006
1006
  if (card.image) {
1007
1007
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1017,7 +1017,7 @@ function FeatureChecklistThreeColumn({
1017
1017
  }
1018
1018
  return null;
1019
1019
  }, [optixFlowConfig]);
1020
- const renderCardLink = React.useMemo(() => (card) => {
1020
+ const renderCardLink = React.useCallback((card) => {
1021
1021
  if (card.linkSlot) return card.linkSlot;
1022
1022
  if (!card.link) return null;
1023
1023
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1080,7 +1080,7 @@ function FeatureChecklistThreeColumn({
1080
1080
  pattern,
1081
1081
  patternOpacity,
1082
1082
  patternClassName,
1083
- className: cn("py-16 sm:py-24 md:py-32", className),
1083
+ className,
1084
1084
  containerClassName,
1085
1085
  children: [
1086
1086
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid gap-4 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:grid-cols-3 lg:gap-16", headerGridClassName), children: [
@@ -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';
@@ -964,15 +964,15 @@ function FeatureChecklistThreeColumn({
964
964
  patternOpacity,
965
965
  patternClassName
966
966
  }) {
967
- const getCheckItemContent = useMemo(() => (item) => {
967
+ const getCheckItemContent = useCallback((item) => {
968
968
  if (typeof item === "string") return item;
969
969
  return item.content;
970
970
  }, []);
971
- const getCheckItemClassName = useMemo(() => (item) => {
971
+ const getCheckItemClassName = useCallback((item) => {
972
972
  if (typeof item === "string") return void 0;
973
973
  return item.className;
974
974
  }, []);
975
- const renderChecklistColumn = useMemo(() => (items, slot, gapClass) => {
975
+ const renderChecklistColumn = useCallback((items, slot, gapClass) => {
976
976
  if (slot) return slot;
977
977
  if (!items || items.length === 0) return null;
978
978
  return /* @__PURE__ */ jsx("ul", { className: cn("flex flex-col text-muted-foreground", gapClass, checklistClassName), children: items.map((item, index) => /* @__PURE__ */ jsxs("li", { className: cn("flex items-center gap-2", getCheckItemClassName(item)), children: [
@@ -980,7 +980,7 @@ function FeatureChecklistThreeColumn({
980
980
  getCheckItemContent(item)
981
981
  ] }, index)) });
982
982
  }, [checklistClassName, getCheckItemContent, getCheckItemClassName]);
983
- const renderCardImage = useMemo(() => (card) => {
983
+ const renderCardImage = useCallback((card) => {
984
984
  if (card.imageSlot) return card.imageSlot;
985
985
  if (card.image) {
986
986
  return /* @__PURE__ */ jsx(
@@ -996,7 +996,7 @@ function FeatureChecklistThreeColumn({
996
996
  }
997
997
  return null;
998
998
  }, [optixFlowConfig]);
999
- const renderCardLink = useMemo(() => (card) => {
999
+ const renderCardLink = useCallback((card) => {
1000
1000
  if (card.linkSlot) return card.linkSlot;
1001
1001
  if (!card.link) return null;
1002
1002
  return /* @__PURE__ */ jsxs(
@@ -1059,7 +1059,7 @@ function FeatureChecklistThreeColumn({
1059
1059
  pattern,
1060
1060
  patternOpacity,
1061
1061
  patternClassName,
1062
- className: cn("py-16 sm:py-24 md:py-32", className),
1062
+ className,
1063
1063
  containerClassName,
1064
1064
  children: [
1065
1065
  /* @__PURE__ */ jsxs("div", { className: cn("grid gap-4 sm:grid-cols-2 sm:gap-8 md:gap-12 lg:grid-cols-3 lg:gap-16", headerGridClassName), children: [
@@ -566,12 +566,12 @@ function FeatureIconGridAccent({
566
566
  className,
567
567
  containerClassName,
568
568
  children: [
569
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex w-full flex-col items-center", headerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center space-y-4 text-center sm:space-y-6 md:max-w-3xl md:text-center", children: [
569
+ (label || title || description) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex w-full flex-col items-center", headerClassName), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center space-y-4 text-center sm:space-y-6 md:max-w-3xl md:text-center", children: [
570
570
  label && (typeof label === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm text-muted-foreground", labelClassName), children: label }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: labelClassName, children: label })),
571
571
  title && (typeof title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h2", { className: cn("text-3xl font-medium md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: titleClassName, children: title })),
572
572
  description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground md:max-w-2xl", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: descriptionClassName, children: description }))
573
573
  ] }) }),
574
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-auto mt-20 grid max-w-5xl gap-6 md:grid-cols-2", gridClassName), children: featuresContent })
574
+ featuresContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mx-auto mt-20 grid max-w-5xl gap-6 md:grid-cols-2", gridClassName), children: featuresContent })
575
575
  ]
576
576
  }
577
577
  );
@@ -545,12 +545,12 @@ function FeatureIconGridAccent({
545
545
  className,
546
546
  containerClassName,
547
547
  children: [
548
- /* @__PURE__ */ jsx("div", { className: cn("flex w-full flex-col items-center", headerClassName), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-4 text-center sm:space-y-6 md:max-w-3xl md:text-center", children: [
548
+ (label || title || description) && /* @__PURE__ */ jsx("div", { className: cn("flex w-full flex-col items-center", headerClassName), children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-4 text-center sm:space-y-6 md:max-w-3xl md:text-center", children: [
549
549
  label && (typeof label === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground", labelClassName), children: label }) : /* @__PURE__ */ jsx("div", { className: labelClassName, children: label })),
550
550
  title && (typeof title === "string" ? /* @__PURE__ */ jsx("h2", { className: cn("text-3xl font-medium md:text-5xl", titleClassName), children: title }) : /* @__PURE__ */ jsx("div", { className: titleClassName, children: title })),
551
551
  description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground md:max-w-2xl", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: descriptionClassName, children: description }))
552
552
  ] }) }),
553
- /* @__PURE__ */ jsx("div", { className: cn("mx-auto mt-20 grid max-w-5xl gap-6 md:grid-cols-2", gridClassName), children: featuresContent })
553
+ featuresContent && /* @__PURE__ */ jsx("div", { className: cn("mx-auto mt-20 grid max-w-5xl gap-6 md:grid-cols-2", gridClassName), children: featuresContent })
554
554
  ]
555
555
  }
556
556
  );
@@ -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
  );