@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.
- package/dist/carousel-horizontal-cards.cjs +8 -6
- package/dist/carousel-horizontal-cards.js +8 -6
- package/dist/carousel-image-hero.cjs +119 -177
- package/dist/carousel-image-hero.d.cts +1 -5
- package/dist/carousel-image-hero.d.ts +1 -5
- package/dist/carousel-image-hero.js +119 -177
- package/dist/carousel-portfolio-hero.cjs +138 -59
- package/dist/carousel-portfolio-hero.js +138 -59
- package/dist/carousel-product-feature-showcase.cjs +148 -95
- package/dist/carousel-product-feature-showcase.js +148 -95
- package/dist/carousel-progress-slider.cjs +13 -9
- package/dist/carousel-progress-slider.js +13 -9
- package/dist/carousel-scrolling-feature-showcase.cjs +105 -54
- package/dist/carousel-scrolling-feature-showcase.js +105 -54
- package/dist/feature-accordion-image.cjs +9 -8
- package/dist/feature-accordion-image.js +9 -8
- package/dist/feature-animated-carousel.cjs +65 -49
- package/dist/feature-animated-carousel.js +65 -49
- package/dist/feature-badge-grid-six.cjs +20 -17
- package/dist/feature-badge-grid-six.js +21 -18
- package/dist/feature-bento-image-grid.cjs +12 -8
- package/dist/feature-bento-image-grid.js +12 -8
- package/dist/feature-bento-utilities.cjs +9 -5
- package/dist/feature-bento-utilities.js +9 -5
- package/dist/feature-capabilities-grid.cjs +41 -38
- package/dist/feature-capabilities-grid.js +41 -38
- package/dist/feature-card-grid-linked.cjs +18 -18
- package/dist/feature-card-grid-linked.js +19 -19
- package/dist/feature-carousel-progress.cjs +3 -3
- package/dist/feature-carousel-progress.js +4 -4
- package/dist/feature-category-image-cards.cjs +3 -3
- package/dist/feature-category-image-cards.js +4 -4
- package/dist/feature-checklist-image.cjs +2 -2
- package/dist/feature-checklist-image.js +2 -2
- package/dist/feature-checklist-three-column.cjs +6 -6
- package/dist/feature-checklist-three-column.js +7 -7
- package/dist/feature-icon-grid-accent.cjs +2 -2
- package/dist/feature-icon-grid-accent.js +2 -2
- package/dist/feature-icon-grid-bordered.cjs +29 -31
- package/dist/feature-icon-grid-bordered.d.cts +9 -9
- package/dist/feature-icon-grid-bordered.d.ts +9 -9
- package/dist/feature-icon-grid-bordered.js +30 -32
- package/dist/feature-icon-grid-muted.cjs +6 -6
- package/dist/feature-icon-grid-muted.d.cts +9 -9
- package/dist/feature-icon-grid-muted.d.ts +9 -9
- package/dist/feature-icon-grid-muted.js +7 -7
- package/dist/feature-icon-tabs-content.cjs +8 -8
- package/dist/feature-icon-tabs-content.d.cts +13 -13
- package/dist/feature-icon-tabs-content.d.ts +13 -13
- package/dist/feature-icon-tabs-content.js +9 -9
- package/dist/feature-image-cards-three-column.cjs +26 -27
- package/dist/feature-image-cards-three-column.js +27 -28
- package/dist/feature-image-overlay-badge.cjs +23 -21
- package/dist/feature-image-overlay-badge.js +24 -22
- package/dist/feature-integration-cards.cjs +19 -18
- package/dist/feature-integration-cards.js +20 -19
- package/dist/feature-numbered-cards.cjs +2 -2
- package/dist/feature-numbered-cards.js +3 -3
- package/dist/feature-pattern-grid-links.cjs +26 -29
- package/dist/feature-pattern-grid-links.d.cts +1 -5
- package/dist/feature-pattern-grid-links.d.ts +1 -5
- package/dist/feature-pattern-grid-links.js +27 -30
- package/dist/feature-showcase.cjs +441 -40
- package/dist/feature-showcase.d.cts +62 -5
- package/dist/feature-showcase.d.ts +62 -5
- package/dist/feature-showcase.js +438 -37
- package/dist/feature-split-image-reverse.cjs +15 -36
- package/dist/feature-split-image-reverse.js +16 -37
- package/dist/feature-split-image.cjs +15 -36
- package/dist/feature-split-image.js +16 -37
- package/dist/feature-stats-highlight.cjs +20 -32
- package/dist/feature-stats-highlight.js +21 -33
- package/dist/feature-tabbed-content-image.cjs +11 -6
- package/dist/feature-tabbed-content-image.js +11 -6
- package/dist/feature-three-column-values.cjs +6 -6
- package/dist/feature-three-column-values.js +6 -6
- package/dist/feature-utility-cards-grid.cjs +17 -15
- package/dist/feature-utility-cards-grid.js +18 -16
- package/dist/navbar-tabbed-sections.cjs +23 -16
- package/dist/navbar-tabbed-sections.js +23 -16
- package/dist/registry.cjs +964 -714
- package/dist/registry.js +966 -716
- package/package.json +1 -1
|
@@ -17,11 +17,11 @@ interface FeatureIconGridMutedItem {
|
|
|
17
17
|
*/
|
|
18
18
|
iconName?: string;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Item title content
|
|
21
21
|
*/
|
|
22
22
|
title?: React.ReactNode;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
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
|
|
54
|
+
* Array of items to display
|
|
55
55
|
*/
|
|
56
56
|
features?: FeatureIconGridMutedItem[];
|
|
57
57
|
/**
|
|
58
|
-
* Custom slot for rendering
|
|
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-
|
|
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:
|
|
116
|
+
* Best for: Capability highlights, benefits showcase, service offerings.
|
|
117
117
|
*
|
|
118
118
|
* @example
|
|
119
119
|
* ```tsx
|
|
120
120
|
* <FeatureIconGridMuted
|
|
121
|
-
* title="Key
|
|
122
|
-
* description="Explore tools
|
|
121
|
+
* title="Key Capabilities"
|
|
122
|
+
* description="Explore tools built to enhance your workflow."
|
|
123
123
|
* features={[
|
|
124
|
-
* { iconName: "lucide/check-circle-2", title: "
|
|
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
|
-
*
|
|
20
|
+
* Item title content
|
|
21
21
|
*/
|
|
22
22
|
title?: React.ReactNode;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
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
|
|
54
|
+
* Array of items to display
|
|
55
55
|
*/
|
|
56
56
|
features?: FeatureIconGridMutedItem[];
|
|
57
57
|
/**
|
|
58
|
-
* Custom slot for rendering
|
|
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-
|
|
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:
|
|
116
|
+
* Best for: Capability highlights, benefits showcase, service offerings.
|
|
117
117
|
*
|
|
118
118
|
* @example
|
|
119
119
|
* ```tsx
|
|
120
120
|
* <FeatureIconGridMuted
|
|
121
|
-
* title="Key
|
|
122
|
-
* description="Explore tools
|
|
121
|
+
* title="Key Capabilities"
|
|
122
|
+
* description="Explore tools built to enhance your workflow."
|
|
123
123
|
* features={[
|
|
124
|
-
* { iconName: "lucide/check-circle-2", title: "
|
|
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.
|
|
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
|
|
1053
|
+
return null;
|
|
1054
1054
|
}, []);
|
|
1055
|
-
const renderTabContentActions = React.
|
|
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.
|
|
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
|
|
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
|
|
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,
|
|
190
|
-
* Best for:
|
|
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="
|
|
196
|
-
* heading="
|
|
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: "
|
|
201
|
+
* label: "Performance",
|
|
202
202
|
* content: {
|
|
203
|
-
* badge: "
|
|
204
|
-
* title: "
|
|
205
|
-
* description: "
|
|
206
|
-
* actions: [{ label: "
|
|
207
|
-
* imageSrc: "/
|
|
208
|
-
* imageAlt: "
|
|
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
|
* ]}
|
|
@@ -21,7 +21,7 @@ interface FeatureIconTabsContentTabContent {
|
|
|
21
21
|
*/
|
|
22
22
|
description?: React.ReactNode;
|
|
23
23
|
/**
|
|
24
|
-
* Array of action configurations for
|
|
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
|
|
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,
|
|
190
|
-
* Best for:
|
|
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="
|
|
196
|
-
* heading="
|
|
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: "
|
|
201
|
+
* label: "Performance",
|
|
202
202
|
* content: {
|
|
203
|
-
* badge: "
|
|
204
|
-
* title: "
|
|
205
|
-
* description: "
|
|
206
|
-
* actions: [{ label: "
|
|
207
|
-
* imageSrc: "/
|
|
208
|
-
* imageAlt: "
|
|
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 =
|
|
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
|
|
1031
|
+
return null;
|
|
1032
1032
|
}, []);
|
|
1033
|
-
const renderTabContentActions =
|
|
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 =
|
|
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,
|
|
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,
|
|
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.
|
|
1108
|
-
|
|
1109
|
-
/* @__PURE__ */ jsxRuntime.jsxs("
|
|
1110
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
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
|
] })
|