@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
@@ -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
  * ]}
@@ -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';
@@ -1025,12 +1025,12 @@ function FeatureIconTabsContent({
1025
1025
  patternOpacity,
1026
1026
  patternClassName
1027
1027
  }) {
1028
- const renderTabIcon = useMemo(() => (tab) => {
1028
+ const renderTabIcon = useCallback((tab) => {
1029
1029
  if (tab.icon) return tab.icon;
1030
1030
  if (tab.iconName) return /* @__PURE__ */ jsx(DynamicIcon, { name: tab.iconName, size: 16 });
1031
- return /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/star", size: 16 });
1031
+ return null;
1032
1032
  }, []);
1033
- const renderTabContentActions = useMemo(() => (content) => {
1033
+ const renderTabContentActions = useCallback((content) => {
1034
1034
  if (content.actionsSlot) return content.actionsSlot;
1035
1035
  if (!content.actions || content.actions.length === 0) return null;
1036
1036
  return content.actions.map((action, index) => {
@@ -1070,7 +1070,7 @@ function FeatureIconTabsContent({
1070
1070
  );
1071
1071
  });
1072
1072
  }, []);
1073
- const renderTabContentImage = useMemo(() => (content) => {
1073
+ const renderTabContentImage = useCallback((content) => {
1074
1074
  if (content.imageSlot) return content.imageSlot;
1075
1075
  if (content.imageSrc) {
1076
1076
  return /* @__PURE__ */ jsx(
@@ -1097,7 +1097,7 @@ function FeatureIconTabsContent({
1097
1097
  value: tab.value,
1098
1098
  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),
1099
1099
  children: [
1100
- renderTabIcon(tab),
1100
+ (tab.icon || tab.iconName) && renderTabIcon(tab),
1101
1101
  tab.label
1102
1102
  ]
1103
1103
  },
@@ -1119,9 +1119,9 @@ function FeatureIconTabsContent({
1119
1119
  content.badge && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: cn("w-fit bg-background", content.badgeClassName), children: content.badge }),
1120
1120
  content.title && (typeof content.title === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("text-3xl font-semibold lg:text-5xl", content.titleClassName), children: content.title }) : /* @__PURE__ */ jsx("div", { className: cn("text-3xl font-semibold lg:text-5xl", content.titleClassName), children: content.title })),
1121
1121
  content.description && (typeof content.description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground lg:text-lg", content.descriptionClassName), children: content.description }) : /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground lg:text-lg", content.descriptionClassName), children: content.description })),
1122
- renderTabContentActions(content)
1122
+ (content.actionsSlot || content.actions && content.actions.length > 0) && renderTabContentActions(content)
1123
1123
  ] }),
1124
- /* @__PURE__ */ jsx("div", { className: "relative h-[300px] w-full lg:h-[400px]", children: renderTabContentImage(content) })
1124
+ (content.imageSlot || content.imageSrc) && /* @__PURE__ */ jsx("div", { className: "relative h-[300px] w-full lg:h-[400px]", children: renderTabContentImage(content) })
1125
1125
  ]
1126
1126
  },
1127
1127
  tab.value
@@ -1140,7 +1140,7 @@ function FeatureIconTabsContent({
1140
1140
  className,
1141
1141
  containerClassName: cn("mx-auto", containerClassName),
1142
1142
  children: [
1143
- /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center gap-4 text-center", headerClassName), children: [
1143
+ (badge || heading || description) && /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center gap-4 text-center", headerClassName), children: [
1144
1144
  badge && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: badgeClassName, children: badge }),
1145
1145
  heading && (typeof heading === "string" ? /* @__PURE__ */ jsx("h1", { className: cn("max-w-2xl text-3xl font-semibold md:text-4xl", headingClassName), children: heading }) : /* @__PURE__ */ jsx("div", { className: cn("max-w-2xl text-3xl font-semibold md:text-4xl", headingClassName), children: heading })),
1146
1146
  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 }))
@@ -979,34 +979,33 @@ function FeatureImageCardsThreeColumn({
979
979
  patternOpacity,
980
980
  patternClassName
981
981
  }) {
982
+ const renderImage = React.useCallback((card, imageAlt) => {
983
+ if (card.imageSlot) return card.imageSlot;
984
+ if (!card.imageSrc) return null;
985
+ return /* @__PURE__ */ jsxRuntime.jsx(
986
+ img.Img,
987
+ {
988
+ src: card.imageSrc,
989
+ alt: imageAlt,
990
+ className: "h-full max-h-[450px] w-full rounded-xl object-cover object-center",
991
+ loading: "lazy",
992
+ optixFlowConfig
993
+ }
994
+ );
995
+ }, [optixFlowConfig]);
996
+ const renderBadgeIcon = React.useCallback((card) => {
997
+ if (card.avatarSrc) {
998
+ return /* @__PURE__ */ jsxRuntime.jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: card.avatarSrc, alt: "Avatar" }) });
999
+ }
1000
+ if (card.icon) return card.icon;
1001
+ if (!card.iconName) return null;
1002
+ return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: card.iconName, size: 24 });
1003
+ }, []);
982
1004
  const cardsContent = React.useMemo(() => {
983
1005
  if (cardsSlot) return cardsSlot;
984
1006
  if (!cards || cards.length === 0) return null;
985
1007
  return cards.map((card, index) => {
986
1008
  const imageAlt = card.imageAlt || (typeof card.title === "string" ? card.title : "Card image");
987
- const renderImage = () => {
988
- if (card.imageSlot) return card.imageSlot;
989
- if (card.imageSrc) {
990
- return /* @__PURE__ */ jsxRuntime.jsx(
991
- img.Img,
992
- {
993
- src: card.imageSrc,
994
- alt: imageAlt,
995
- className: "h-full max-h-[450px] w-full rounded-xl object-cover object-center",
996
- loading: "lazy",
997
- optixFlowConfig
998
- }
999
- );
1000
- }
1001
- return null;
1002
- };
1003
- const renderBadgeIcon = () => {
1004
- if (card.avatarSrc) {
1005
- return /* @__PURE__ */ jsxRuntime.jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: card.avatarSrc, alt: "Avatar" }) });
1006
- }
1007
- if (card.icon) return card.icon;
1008
- return /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: card.iconName || "lucide/zap", size: 24 });
1009
- };
1010
1009
  return /* @__PURE__ */ jsxRuntime.jsxs(
1011
1010
  Pressable,
1012
1011
  {
@@ -1014,10 +1013,10 @@ function FeatureImageCardsThreeColumn({
1014
1013
  onClick: card.onClick,
1015
1014
  className: cn("group relative overflow-hidden rounded-xl", cardClassName, card.className),
1016
1015
  children: [
1017
- renderImage(),
1016
+ renderImage(card, imageAlt),
1018
1017
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 right-0 bottom-0 left-0 translate-y-20 rounded-xl bg-linear-to-t from-primary to-transparent transition-transform duration-300 group-hover:translate-y-0" }),
1019
1018
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
1020
- /* @__PURE__ */ jsxRuntime.jsxs(
1019
+ (card.badgeText || card.avatarSrc || card.icon || card.iconName) && /* @__PURE__ */ jsxRuntime.jsxs(
1021
1020
  "span",
1022
1021
  {
1023
1022
  className: cn(
@@ -1026,7 +1025,7 @@ function FeatureImageCardsThreeColumn({
1026
1025
  card.badgeClassName
1027
1026
  ),
1028
1027
  children: [
1029
- renderBadgeIcon(),
1028
+ renderBadgeIcon(card),
1030
1029
  card.badgeText
1031
1030
  ]
1032
1031
  }
@@ -1044,7 +1043,7 @@ function FeatureImageCardsThreeColumn({
1044
1043
  index
1045
1044
  );
1046
1045
  });
1047
- }, [cardsSlot, cards, cardClassName, optixFlowConfig]);
1046
+ }, [cardsSlot, cards, cardClassName, renderImage, renderBadgeIcon]);
1048
1047
  return /* @__PURE__ */ jsxRuntime.jsxs(
1049
1048
  Section,
1050
1049
  {
@@ -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';
@@ -957,34 +957,33 @@ function FeatureImageCardsThreeColumn({
957
957
  patternOpacity,
958
958
  patternClassName
959
959
  }) {
960
+ const renderImage = useCallback((card, imageAlt) => {
961
+ if (card.imageSlot) return card.imageSlot;
962
+ if (!card.imageSrc) return null;
963
+ return /* @__PURE__ */ jsx(
964
+ Img,
965
+ {
966
+ src: card.imageSrc,
967
+ alt: imageAlt,
968
+ className: "h-full max-h-[450px] w-full rounded-xl object-cover object-center",
969
+ loading: "lazy",
970
+ optixFlowConfig
971
+ }
972
+ );
973
+ }, [optixFlowConfig]);
974
+ const renderBadgeIcon = useCallback((card) => {
975
+ if (card.avatarSrc) {
976
+ return /* @__PURE__ */ jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsx(AvatarImage, { src: card.avatarSrc, alt: "Avatar" }) });
977
+ }
978
+ if (card.icon) return card.icon;
979
+ if (!card.iconName) return null;
980
+ return /* @__PURE__ */ jsx(DynamicIcon, { name: card.iconName, size: 24 });
981
+ }, []);
960
982
  const cardsContent = useMemo(() => {
961
983
  if (cardsSlot) return cardsSlot;
962
984
  if (!cards || cards.length === 0) return null;
963
985
  return cards.map((card, index) => {
964
986
  const imageAlt = card.imageAlt || (typeof card.title === "string" ? card.title : "Card image");
965
- const renderImage = () => {
966
- if (card.imageSlot) return card.imageSlot;
967
- if (card.imageSrc) {
968
- return /* @__PURE__ */ jsx(
969
- Img,
970
- {
971
- src: card.imageSrc,
972
- alt: imageAlt,
973
- className: "h-full max-h-[450px] w-full rounded-xl object-cover object-center",
974
- loading: "lazy",
975
- optixFlowConfig
976
- }
977
- );
978
- }
979
- return null;
980
- };
981
- const renderBadgeIcon = () => {
982
- if (card.avatarSrc) {
983
- return /* @__PURE__ */ jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsx(AvatarImage, { src: card.avatarSrc, alt: "Avatar" }) });
984
- }
985
- if (card.icon) return card.icon;
986
- return /* @__PURE__ */ jsx(DynamicIcon, { name: card.iconName || "lucide/zap", size: 24 });
987
- };
988
987
  return /* @__PURE__ */ jsxs(
989
988
  Pressable,
990
989
  {
@@ -992,10 +991,10 @@ function FeatureImageCardsThreeColumn({
992
991
  onClick: card.onClick,
993
992
  className: cn("group relative overflow-hidden rounded-xl", cardClassName, card.className),
994
993
  children: [
995
- renderImage(),
994
+ renderImage(card, imageAlt),
996
995
  /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0 bottom-0 left-0 translate-y-20 rounded-xl bg-linear-to-t from-primary to-transparent transition-transform duration-300 group-hover:translate-y-0" }),
997
996
  /* @__PURE__ */ jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
998
- /* @__PURE__ */ jsxs(
997
+ (card.badgeText || card.avatarSrc || card.icon || card.iconName) && /* @__PURE__ */ jsxs(
999
998
  "span",
1000
999
  {
1001
1000
  className: cn(
@@ -1004,7 +1003,7 @@ function FeatureImageCardsThreeColumn({
1004
1003
  card.badgeClassName
1005
1004
  ),
1006
1005
  children: [
1007
- renderBadgeIcon(),
1006
+ renderBadgeIcon(card),
1008
1007
  card.badgeText
1009
1008
  ]
1010
1009
  }
@@ -1022,7 +1021,7 @@ function FeatureImageCardsThreeColumn({
1022
1021
  index
1023
1022
  );
1024
1023
  });
1025
- }, [cardsSlot, cards, cardClassName, optixFlowConfig]);
1024
+ }, [cardsSlot, cards, cardClassName, renderImage, renderBadgeIcon]);
1026
1025
  return /* @__PURE__ */ jsxs(
1027
1026
  Section,
1028
1027
  {
@@ -1102,28 +1102,30 @@ function FeatureImageOverlayBadge({
1102
1102
  description && (typeof description === "string" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-muted-foreground lg:text-lg", descriptionClassName), children: description }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-muted-foreground lg:text-lg", descriptionClassName), children: description })),
1103
1103
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: actionsClassName, children: actionsContent })
1104
1104
  ] }),
1105
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative rounded-xl", imageWrapperClassName), children: [
1105
+ imageContent && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative rounded-xl", imageWrapperClassName), children: [
1106
1106
  imageContent,
1107
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("absolute top-0 right-0 bottom-0 left-0 rounded-xl bg-linear-to-t from-primary via-transparent to-transparent", overlayClassName) }),
1108
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
1109
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("ml-auto flex w-fit items-center gap-2 rounded-full bg-background/30 px-4 py-2.5 text-sm font-semibold backdrop-blur-sm", avatarBadgeClassName), children: [
1110
- /* @__PURE__ */ jsxRuntime.jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: avatarSrc, alt: "Avatar" }) }),
1111
- avatarBadgeText
1112
- ] }),
1113
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5 text-background", children: [
1114
- overlayTitle && (typeof overlayTitle === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h4", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle })),
1115
- overlayLinkText && /* @__PURE__ */ jsxRuntime.jsxs(
1116
- Pressable,
1117
- {
1118
- href: overlayLinkUrl,
1119
- onClick: overlayLinkOnClick,
1120
- className: "flex items-center gap-1 font-medium",
1121
- children: [
1122
- overlayLinkText,
1123
- /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 16 })
1124
- ]
1125
- }
1126
- )
1107
+ (avatarSrc || avatarBadgeText || overlayTitle || overlayLinkText) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1108
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("absolute top-0 right-0 bottom-0 left-0 rounded-xl bg-linear-to-t from-primary via-transparent to-transparent", overlayClassName) }),
1109
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
1110
+ (avatarSrc || avatarBadgeText) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("ml-auto flex w-fit items-center gap-2 rounded-full bg-background/30 px-4 py-2.5 text-sm font-semibold backdrop-blur-sm", avatarBadgeClassName), children: [
1111
+ avatarSrc && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: avatarSrc, alt: "Avatar" }) }),
1112
+ avatarBadgeText
1113
+ ] }),
1114
+ (overlayTitle || overlayLinkText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5 text-background", children: [
1115
+ overlayTitle && (typeof overlayTitle === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h4", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle })),
1116
+ overlayLinkText && /* @__PURE__ */ jsxRuntime.jsxs(
1117
+ Pressable,
1118
+ {
1119
+ href: overlayLinkUrl,
1120
+ onClick: overlayLinkOnClick,
1121
+ className: "flex items-center gap-1 font-medium",
1122
+ children: [
1123
+ overlayLinkText,
1124
+ /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/chevron-right", size: 16 })
1125
+ ]
1126
+ }
1127
+ )
1128
+ ] })
1127
1129
  ] })
1128
1130
  ] })
1129
1131
  ] })
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import React__default, { useMemo } from 'react';
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { jsx, jsxs } from 'react/jsx-runtime';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import { Slot } from '@radix-ui/react-slot';
9
9
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
@@ -1080,28 +1080,30 @@ function FeatureImageOverlayBadge({
1080
1080
  description && (typeof description === "string" ? /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground lg:text-lg", descriptionClassName), children: description }) : /* @__PURE__ */ jsx("div", { className: cn("text-muted-foreground lg:text-lg", descriptionClassName), children: description })),
1081
1081
  /* @__PURE__ */ jsx("div", { className: actionsClassName, children: actionsContent })
1082
1082
  ] }),
1083
- /* @__PURE__ */ jsxs("div", { className: cn("relative rounded-xl", imageWrapperClassName), children: [
1083
+ imageContent && /* @__PURE__ */ jsxs("div", { className: cn("relative rounded-xl", imageWrapperClassName), children: [
1084
1084
  imageContent,
1085
- /* @__PURE__ */ jsx("div", { className: cn("absolute top-0 right-0 bottom-0 left-0 rounded-xl bg-linear-to-t from-primary via-transparent to-transparent", overlayClassName) }),
1086
- /* @__PURE__ */ jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
1087
- /* @__PURE__ */ jsxs("span", { className: cn("ml-auto flex w-fit items-center gap-2 rounded-full bg-background/30 px-4 py-2.5 text-sm font-semibold backdrop-blur-sm", avatarBadgeClassName), children: [
1088
- /* @__PURE__ */ jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsx(AvatarImage, { src: avatarSrc, alt: "Avatar" }) }),
1089
- avatarBadgeText
1090
- ] }),
1091
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 text-background", children: [
1092
- overlayTitle && (typeof overlayTitle === "string" ? /* @__PURE__ */ jsx("h4", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle }) : /* @__PURE__ */ jsx("div", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle })),
1093
- overlayLinkText && /* @__PURE__ */ jsxs(
1094
- Pressable,
1095
- {
1096
- href: overlayLinkUrl,
1097
- onClick: overlayLinkOnClick,
1098
- className: "flex items-center gap-1 font-medium",
1099
- children: [
1100
- overlayLinkText,
1101
- /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 16 })
1102
- ]
1103
- }
1104
- )
1085
+ (avatarSrc || avatarBadgeText || overlayTitle || overlayLinkText) && /* @__PURE__ */ jsxs(Fragment, { children: [
1086
+ /* @__PURE__ */ jsx("div", { className: cn("absolute top-0 right-0 bottom-0 left-0 rounded-xl bg-linear-to-t from-primary via-transparent to-transparent", overlayClassName) }),
1087
+ /* @__PURE__ */ jsxs("div", { className: "absolute top-0 flex h-full w-full flex-col justify-between p-7", children: [
1088
+ (avatarSrc || avatarBadgeText) && /* @__PURE__ */ jsxs("span", { className: cn("ml-auto flex w-fit items-center gap-2 rounded-full bg-background/30 px-4 py-2.5 text-sm font-semibold backdrop-blur-sm", avatarBadgeClassName), children: [
1089
+ avatarSrc && /* @__PURE__ */ jsx(Avatar, { className: "size-7 rounded-full", children: /* @__PURE__ */ jsx(AvatarImage, { src: avatarSrc, alt: "Avatar" }) }),
1090
+ avatarBadgeText
1091
+ ] }),
1092
+ (overlayTitle || overlayLinkText) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-5 text-background", children: [
1093
+ overlayTitle && (typeof overlayTitle === "string" ? /* @__PURE__ */ jsx("h4", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle }) : /* @__PURE__ */ jsx("div", { className: cn("text-lg font-semibold lg:text-3xl", overlayTitleClassName), children: overlayTitle })),
1094
+ overlayLinkText && /* @__PURE__ */ jsxs(
1095
+ Pressable,
1096
+ {
1097
+ href: overlayLinkUrl,
1098
+ onClick: overlayLinkOnClick,
1099
+ className: "flex items-center gap-1 font-medium",
1100
+ children: [
1101
+ overlayLinkText,
1102
+ /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/chevron-right", size: 16 })
1103
+ ]
1104
+ }
1105
+ )
1106
+ ] })
1105
1107
  ] })
1106
1108
  ] })
1107
1109
  ] })
@@ -949,26 +949,25 @@ function FeatureIntegrationCards({
949
949
  patternOpacity,
950
950
  patternClassName
951
951
  }) {
952
- const renderIntegrationIcon = React.useMemo(() => (integration) => {
952
+ const renderIntegrationIcon = React.useCallback((integration) => {
953
953
  if (integration.iconSlot) return integration.iconSlot;
954
- if (integration.icon) {
955
- return /* @__PURE__ */ jsxRuntime.jsx(
956
- img.Img,
957
- {
958
- src: integration.icon,
959
- alt: integration.iconAlt || (typeof integration.title === "string" ? integration.title : "Integration icon"),
960
- className: cn("h-auto w-7", integration.iconClassName),
961
- loading: "lazy",
962
- optixFlowConfig
963
- }
964
- );
965
- }
966
- return null;
954
+ if (!integration.icon) return null;
955
+ return /* @__PURE__ */ jsxRuntime.jsx(
956
+ img.Img,
957
+ {
958
+ src: integration.icon,
959
+ alt: integration.iconAlt || (typeof integration.title === "string" ? integration.title : "Integration icon"),
960
+ className: cn("h-auto w-7", integration.iconClassName),
961
+ loading: "lazy",
962
+ optixFlowConfig
963
+ }
964
+ );
967
965
  }, [optixFlowConfig]);
968
- const renderLinkLabel = React.useMemo(() => (integration) => {
966
+ const renderLinkLabel = React.useCallback((integration) => {
969
967
  if (integration.linkLabelSlot) return integration.linkLabelSlot;
968
+ if (!integration.linkLabel) return null;
970
969
  return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("flex items-center gap-1 rounded-full border px-3 py-2.5 text-sm", integration.linkLabelClassName), children: [
971
- integration.linkLabel || "Visit Website",
970
+ integration.linkLabel,
972
971
  /* @__PURE__ */ jsxRuntime.jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16 })
973
972
  ] });
974
973
  }, []);
@@ -976,10 +975,12 @@ function FeatureIntegrationCards({
976
975
  if (integrationsSlot) return integrationsSlot;
977
976
  if (!integrations || integrations.length === 0) return null;
978
977
  return integrations.map((integration, index) => {
978
+ const iconContent = renderIntegrationIcon(integration);
979
+ const linkLabelContent = renderLinkLabel(integration);
979
980
  const cardContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
980
981
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
981
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid size-12 shrink-0 place-content-center rounded-md border", children: renderIntegrationIcon(integration) }),
982
- renderLinkLabel(integration)
982
+ iconContent && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "grid size-12 shrink-0 place-content-center rounded-md border", children: iconContent }),
983
+ linkLabelContent
983
984
  ] }),
984
985
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
985
986
  integration.title && (typeof integration.title === "string" ? /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn("font-medium md:text-lg", integration.titleClassName), children: integration.title }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("font-medium md:text-lg", integration.titleClassName), children: integration.title })),
@@ -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, Fragment } from 'react/jsx-runtime';
@@ -928,26 +928,25 @@ function FeatureIntegrationCards({
928
928
  patternOpacity,
929
929
  patternClassName
930
930
  }) {
931
- const renderIntegrationIcon = useMemo(() => (integration) => {
931
+ const renderIntegrationIcon = useCallback((integration) => {
932
932
  if (integration.iconSlot) return integration.iconSlot;
933
- if (integration.icon) {
934
- return /* @__PURE__ */ jsx(
935
- Img,
936
- {
937
- src: integration.icon,
938
- alt: integration.iconAlt || (typeof integration.title === "string" ? integration.title : "Integration icon"),
939
- className: cn("h-auto w-7", integration.iconClassName),
940
- loading: "lazy",
941
- optixFlowConfig
942
- }
943
- );
944
- }
945
- return null;
933
+ if (!integration.icon) return null;
934
+ return /* @__PURE__ */ jsx(
935
+ Img,
936
+ {
937
+ src: integration.icon,
938
+ alt: integration.iconAlt || (typeof integration.title === "string" ? integration.title : "Integration icon"),
939
+ className: cn("h-auto w-7", integration.iconClassName),
940
+ loading: "lazy",
941
+ optixFlowConfig
942
+ }
943
+ );
946
944
  }, [optixFlowConfig]);
947
- const renderLinkLabel = useMemo(() => (integration) => {
945
+ const renderLinkLabel = useCallback((integration) => {
948
946
  if (integration.linkLabelSlot) return integration.linkLabelSlot;
947
+ if (!integration.linkLabel) return null;
949
948
  return /* @__PURE__ */ jsxs("span", { className: cn("flex items-center gap-1 rounded-full border px-3 py-2.5 text-sm", integration.linkLabelClassName), children: [
950
- integration.linkLabel || "Visit Website",
949
+ integration.linkLabel,
951
950
  /* @__PURE__ */ jsx(DynamicIcon, { name: "lucide/arrow-right", size: 16 })
952
951
  ] });
953
952
  }, []);
@@ -955,10 +954,12 @@ function FeatureIntegrationCards({
955
954
  if (integrationsSlot) return integrationsSlot;
956
955
  if (!integrations || integrations.length === 0) return null;
957
956
  return integrations.map((integration, index) => {
957
+ const iconContent = renderIntegrationIcon(integration);
958
+ const linkLabelContent = renderLinkLabel(integration);
958
959
  const cardContent = /* @__PURE__ */ jsxs(Fragment, { children: [
959
960
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
960
- /* @__PURE__ */ jsx("span", { className: "grid size-12 shrink-0 place-content-center rounded-md border", children: renderIntegrationIcon(integration) }),
961
- renderLinkLabel(integration)
961
+ iconContent && /* @__PURE__ */ jsx("span", { className: "grid size-12 shrink-0 place-content-center rounded-md border", children: iconContent }),
962
+ linkLabelContent
962
963
  ] }),
963
964
  /* @__PURE__ */ jsxs("div", { children: [
964
965
  integration.title && (typeof integration.title === "string" ? /* @__PURE__ */ jsx("h3", { className: cn("font-medium md:text-lg", integration.titleClassName), children: integration.title }) : /* @__PURE__ */ jsx("div", { className: cn("font-medium md:text-lg", integration.titleClassName), children: integration.title })),
@@ -529,7 +529,7 @@ function FeatureNumberedCards({
529
529
  patternOpacity,
530
530
  patternClassName
531
531
  }) {
532
- const renderChecklistItems = (feature) => {
532
+ const renderChecklistItems = React.useCallback((feature) => {
533
533
  if (feature.checklistSlot) return feature.checklistSlot;
534
534
  if (!feature.checklistItems || feature.checklistItems.length === 0) return null;
535
535
  return feature.checklistItems.map((item, itemIndex) => {
@@ -549,7 +549,7 @@ function FeatureNumberedCards({
549
549
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm md:text-base", children: content })
550
550
  ] }, itemIndex);
551
551
  });
552
- };
552
+ }, []);
553
553
  const featuresContent = React.useMemo(() => {
554
554
  if (featuresSlot) return featuresSlot;
555
555
  if (!features || features.length === 0) return null;
@@ -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';
@@ -508,7 +508,7 @@ function FeatureNumberedCards({
508
508
  patternOpacity,
509
509
  patternClassName
510
510
  }) {
511
- const renderChecklistItems = (feature) => {
511
+ const renderChecklistItems = useCallback((feature) => {
512
512
  if (feature.checklistSlot) return feature.checklistSlot;
513
513
  if (!feature.checklistItems || feature.checklistItems.length === 0) return null;
514
514
  return feature.checklistItems.map((item, itemIndex) => {
@@ -528,7 +528,7 @@ function FeatureNumberedCards({
528
528
  /* @__PURE__ */ jsx("p", { className: "text-sm md:text-base", children: content })
529
529
  ] }, itemIndex);
530
530
  });
531
- };
531
+ }, []);
532
532
  const featuresContent = useMemo(() => {
533
533
  if (featuresSlot) return featuresSlot;
534
534
  if (!features || features.length === 0) return null;