@opensite/ui 0.0.4 → 0.0.6
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/button.cjs +14 -13
- package/dist/button.cjs.map +1 -1
- package/dist/button.d.cts +1 -1
- package/dist/button.d.ts +1 -1
- package/dist/button.js +14 -13
- package/dist/button.js.map +1 -1
- package/dist/components.cjs +45 -15
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +1 -0
- package/dist/components.d.ts +1 -0
- package/dist/components.js +45 -16
- package/dist/components.js.map +1 -1
- package/dist/dynamic-icon.cjs +37 -0
- package/dist/dynamic-icon.cjs.map +1 -0
- package/dist/dynamic-icon.d.cts +46 -0
- package/dist/dynamic-icon.d.ts +46 -0
- package/dist/dynamic-icon.js +35 -0
- package/dist/dynamic-icon.js.map +1 -0
- package/dist/feature-showcase.cjs +418 -0
- package/dist/feature-showcase.cjs.map +1 -0
- package/dist/feature-showcase.d.cts +46 -0
- package/dist/feature-showcase.d.ts +46 -0
- package/dist/feature-showcase.js +394 -0
- package/dist/feature-showcase.js.map +1 -0
- package/dist/index.cjs +45 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +45 -16
- package/dist/index.js.map +1 -1
- package/dist/page-hero-banner.cjs +7 -2
- package/dist/page-hero-banner.cjs.map +1 -1
- package/dist/page-hero-banner.d.cts +1 -1
- package/dist/page-hero-banner.d.ts +1 -1
- package/dist/page-hero-banner.js +7 -2
- package/dist/page-hero-banner.js.map +1 -1
- package/dist/registry.cjs +461 -4
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +442 -3
- package/dist/registry.js.map +1 -1
- package/dist/types.d.cts +68 -1
- package/dist/types.d.ts +68 -1
- package/package.json +12 -2
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var useEmblaCarousel = require('embla-carousel-react');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
var reactSlot = require('@radix-ui/react-slot');
|
|
9
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
10
|
+
|
|
11
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
|
|
13
|
+
function _interopNamespace(e) {
|
|
14
|
+
if (e && e.__esModule) return e;
|
|
15
|
+
var n = Object.create(null);
|
|
16
|
+
if (e) {
|
|
17
|
+
Object.keys(e).forEach(function (k) {
|
|
18
|
+
if (k !== 'default') {
|
|
19
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return e[k]; }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
32
|
+
var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
|
|
33
|
+
|
|
34
|
+
// components/blocks/features/feature-showcase.tsx
|
|
35
|
+
function cn(...inputs) {
|
|
36
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
37
|
+
}
|
|
38
|
+
var ArrowLeft = ({
|
|
39
|
+
size = 24,
|
|
40
|
+
className,
|
|
41
|
+
strokeWidth = 2,
|
|
42
|
+
...props
|
|
43
|
+
}) => {
|
|
44
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
+
"svg",
|
|
46
|
+
{
|
|
47
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
48
|
+
width: size,
|
|
49
|
+
height: size,
|
|
50
|
+
viewBox: "0 0 24 24",
|
|
51
|
+
fill: "none",
|
|
52
|
+
stroke: "currentColor",
|
|
53
|
+
strokeWidth,
|
|
54
|
+
strokeLinecap: "round",
|
|
55
|
+
strokeLinejoin: "round",
|
|
56
|
+
className,
|
|
57
|
+
...props,
|
|
58
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m12 19l-7-7l7-7m7 7H5" })
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
var ArrowRight = ({
|
|
63
|
+
size = 24,
|
|
64
|
+
className,
|
|
65
|
+
strokeWidth = 2,
|
|
66
|
+
...props
|
|
67
|
+
}) => {
|
|
68
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
69
|
+
"svg",
|
|
70
|
+
{
|
|
71
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
72
|
+
width: size,
|
|
73
|
+
height: size,
|
|
74
|
+
viewBox: "0 0 24 24",
|
|
75
|
+
fill: "none",
|
|
76
|
+
stroke: "currentColor",
|
|
77
|
+
strokeWidth,
|
|
78
|
+
strokeLinecap: "round",
|
|
79
|
+
strokeLinejoin: "round",
|
|
80
|
+
className,
|
|
81
|
+
...props,
|
|
82
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14m-7-7l7 7l-7 7" })
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
87
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-button text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
88
|
+
{
|
|
89
|
+
variants: {
|
|
90
|
+
variant: {
|
|
91
|
+
default: "bg-[var(--button-default-bg,hsl(var(--primary)))] text-[var(--button-default-fg,hsl(var(--primary-foreground)))] hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]",
|
|
92
|
+
destructive: "bg-[var(--button-destructive-bg,hsl(var(--destructive)))] text-[var(--button-destructive-fg,white)] hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
93
|
+
outline: "border-[var(--button-outline-border-width,1px)] border-[var(--button-outline-border,hsl(var(--border)))] bg-[var(--button-outline-bg,hsl(var(--background)))] text-[var(--button-outline-fg,inherit)] shadow-xs hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))] hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))] dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
94
|
+
secondary: "bg-[var(--button-secondary-bg,hsl(var(--secondary)))] text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))] hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]",
|
|
95
|
+
ghost: "bg-[var(--button-ghost-bg,transparent)] text-[var(--button-ghost-fg,inherit)] hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))] hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))] dark:hover:bg-accent/50",
|
|
96
|
+
link: "text-[var(--button-link-fg,hsl(var(--primary)))] underline-offset-4 hover:underline"
|
|
97
|
+
},
|
|
98
|
+
size: {
|
|
99
|
+
default: "h-[var(--button-height-md,2.25rem)] px-[var(--button-padding-x-md,1rem)] py-2 has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]",
|
|
100
|
+
sm: "h-[var(--button-height-sm,2rem)] rounded-button gap-1.5 px-[var(--button-padding-x-sm,0.75rem)] has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]",
|
|
101
|
+
md: "h-[var(--button-height-md,2.25rem)] px-[var(--button-padding-x-md,1rem)] py-2 has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]",
|
|
102
|
+
lg: "h-[var(--button-height-lg,2.5rem)] rounded-button px-[var(--button-padding-x-lg,1.5rem)] has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]",
|
|
103
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
104
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
105
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
defaultVariants: {
|
|
109
|
+
variant: "default",
|
|
110
|
+
size: "default"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
function Button({
|
|
115
|
+
className,
|
|
116
|
+
variant = "default",
|
|
117
|
+
size = "default",
|
|
118
|
+
asChild = false,
|
|
119
|
+
...props
|
|
120
|
+
}) {
|
|
121
|
+
const Comp = asChild ? reactSlot.Slot : "button";
|
|
122
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
123
|
+
Comp,
|
|
124
|
+
{
|
|
125
|
+
"data-slot": "button",
|
|
126
|
+
"data-variant": variant,
|
|
127
|
+
"data-size": size,
|
|
128
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
129
|
+
...props
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
var CarouselContext = React__namespace.createContext(null);
|
|
134
|
+
function useCarousel() {
|
|
135
|
+
const context = React__namespace.useContext(CarouselContext);
|
|
136
|
+
if (!context) {
|
|
137
|
+
throw new Error("useCarousel must be used within a <Carousel />");
|
|
138
|
+
}
|
|
139
|
+
return context;
|
|
140
|
+
}
|
|
141
|
+
function Carousel({
|
|
142
|
+
orientation = "horizontal",
|
|
143
|
+
opts,
|
|
144
|
+
setApi,
|
|
145
|
+
plugins,
|
|
146
|
+
className,
|
|
147
|
+
children,
|
|
148
|
+
...props
|
|
149
|
+
}) {
|
|
150
|
+
const [carouselRef, api] = useEmblaCarousel__default.default(
|
|
151
|
+
{
|
|
152
|
+
...opts,
|
|
153
|
+
axis: orientation === "horizontal" ? "x" : "y"
|
|
154
|
+
},
|
|
155
|
+
plugins
|
|
156
|
+
);
|
|
157
|
+
const [canScrollPrev, setCanScrollPrev] = React__namespace.useState(false);
|
|
158
|
+
const [canScrollNext, setCanScrollNext] = React__namespace.useState(false);
|
|
159
|
+
const onSelect = React__namespace.useCallback((api2) => {
|
|
160
|
+
if (!api2) return;
|
|
161
|
+
setCanScrollPrev(api2.canScrollPrev());
|
|
162
|
+
setCanScrollNext(api2.canScrollNext());
|
|
163
|
+
}, []);
|
|
164
|
+
const scrollPrev = React__namespace.useCallback(() => {
|
|
165
|
+
api?.scrollPrev();
|
|
166
|
+
}, [api]);
|
|
167
|
+
const scrollNext = React__namespace.useCallback(() => {
|
|
168
|
+
api?.scrollNext();
|
|
169
|
+
}, [api]);
|
|
170
|
+
const handleKeyDown = React__namespace.useCallback(
|
|
171
|
+
(event) => {
|
|
172
|
+
if (event.key === "ArrowLeft") {
|
|
173
|
+
event.preventDefault();
|
|
174
|
+
scrollPrev();
|
|
175
|
+
} else if (event.key === "ArrowRight") {
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
scrollNext();
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
[scrollPrev, scrollNext]
|
|
181
|
+
);
|
|
182
|
+
React__namespace.useEffect(() => {
|
|
183
|
+
if (!api || !setApi) return;
|
|
184
|
+
setApi(api);
|
|
185
|
+
}, [api, setApi]);
|
|
186
|
+
React__namespace.useEffect(() => {
|
|
187
|
+
if (!api) return;
|
|
188
|
+
onSelect(api);
|
|
189
|
+
api.on("reInit", onSelect);
|
|
190
|
+
api.on("select", onSelect);
|
|
191
|
+
return () => {
|
|
192
|
+
api?.off("select", onSelect);
|
|
193
|
+
};
|
|
194
|
+
}, [api, onSelect]);
|
|
195
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
196
|
+
CarouselContext.Provider,
|
|
197
|
+
{
|
|
198
|
+
value: {
|
|
199
|
+
carouselRef,
|
|
200
|
+
api,
|
|
201
|
+
opts,
|
|
202
|
+
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
|
203
|
+
scrollPrev,
|
|
204
|
+
scrollNext,
|
|
205
|
+
canScrollPrev,
|
|
206
|
+
canScrollNext
|
|
207
|
+
},
|
|
208
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
209
|
+
"div",
|
|
210
|
+
{
|
|
211
|
+
onKeyDownCapture: handleKeyDown,
|
|
212
|
+
className: cn("relative", className),
|
|
213
|
+
role: "region",
|
|
214
|
+
"aria-roledescription": "carousel",
|
|
215
|
+
"data-slot": "carousel",
|
|
216
|
+
...props,
|
|
217
|
+
children
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
function CarouselContent({ className, ...props }) {
|
|
224
|
+
const { carouselRef, orientation } = useCarousel();
|
|
225
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
226
|
+
"div",
|
|
227
|
+
{
|
|
228
|
+
ref: carouselRef,
|
|
229
|
+
className: "overflow-hidden",
|
|
230
|
+
"data-slot": "carousel-content",
|
|
231
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
232
|
+
"div",
|
|
233
|
+
{
|
|
234
|
+
className: cn(
|
|
235
|
+
"flex",
|
|
236
|
+
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
|
237
|
+
className
|
|
238
|
+
),
|
|
239
|
+
...props
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
function CarouselItem({ className, ...props }) {
|
|
246
|
+
const { orientation } = useCarousel();
|
|
247
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
248
|
+
"div",
|
|
249
|
+
{
|
|
250
|
+
role: "group",
|
|
251
|
+
"aria-roledescription": "slide",
|
|
252
|
+
"data-slot": "carousel-item",
|
|
253
|
+
className: cn(
|
|
254
|
+
"min-w-0 shrink-0 grow-0 basis-full",
|
|
255
|
+
orientation === "horizontal" ? "pl-4" : "pt-4",
|
|
256
|
+
className
|
|
257
|
+
),
|
|
258
|
+
...props
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
function CarouselPrevious({
|
|
263
|
+
className,
|
|
264
|
+
variant = "outline",
|
|
265
|
+
size = "icon",
|
|
266
|
+
...props
|
|
267
|
+
}) {
|
|
268
|
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
269
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
270
|
+
Button,
|
|
271
|
+
{
|
|
272
|
+
"data-slot": "carousel-previous",
|
|
273
|
+
variant,
|
|
274
|
+
size,
|
|
275
|
+
className: cn(
|
|
276
|
+
"absolute size-8 rounded-full",
|
|
277
|
+
orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
278
|
+
className
|
|
279
|
+
),
|
|
280
|
+
disabled: !canScrollPrev,
|
|
281
|
+
onClick: scrollPrev,
|
|
282
|
+
...props,
|
|
283
|
+
children: [
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx(ArrowLeft, {}),
|
|
285
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Previous slide" })
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
function CarouselNext({
|
|
291
|
+
className,
|
|
292
|
+
variant = "outline",
|
|
293
|
+
size = "icon",
|
|
294
|
+
...props
|
|
295
|
+
}) {
|
|
296
|
+
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
297
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
298
|
+
Button,
|
|
299
|
+
{
|
|
300
|
+
"data-slot": "carousel-next",
|
|
301
|
+
variant,
|
|
302
|
+
size,
|
|
303
|
+
className: cn(
|
|
304
|
+
"absolute size-8 rounded-full",
|
|
305
|
+
orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
306
|
+
className
|
|
307
|
+
),
|
|
308
|
+
disabled: !canScrollNext,
|
|
309
|
+
onClick: scrollNext,
|
|
310
|
+
...props,
|
|
311
|
+
children: [
|
|
312
|
+
/* @__PURE__ */ jsxRuntime.jsx(ArrowRight, {}),
|
|
313
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Next slide" })
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
function FeatureShowcase({
|
|
319
|
+
items,
|
|
320
|
+
children,
|
|
321
|
+
className,
|
|
322
|
+
carouselClassName,
|
|
323
|
+
slideClassName,
|
|
324
|
+
contentClassName,
|
|
325
|
+
mediaClassName,
|
|
326
|
+
arrowClassName,
|
|
327
|
+
equalizeOnMobile = true,
|
|
328
|
+
stretchMediaOnMobile = true
|
|
329
|
+
}) {
|
|
330
|
+
const baseArrowClassName = "bottom-4 top-auto size-12 translate-y-0 rounded-full border border-current bg-transparent text-current shadow-sm focus:ring-current focus:ring-offset-2 focus:ring-offset-transparent hover:bg-current/10 md:bottom-6";
|
|
331
|
+
const [mobileSlideHeight, setMobileSlideHeight] = React.useState(
|
|
332
|
+
null
|
|
333
|
+
);
|
|
334
|
+
const slideRefs = React.useRef([]);
|
|
335
|
+
const mediaWrapperClassName = equalizeOnMobile && stretchMediaOnMobile ? "flex-1 min-h-0 md:flex-none" : "";
|
|
336
|
+
React.useEffect(() => {
|
|
337
|
+
if (!equalizeOnMobile) {
|
|
338
|
+
setMobileSlideHeight(null);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const updateHeights = () => {
|
|
342
|
+
if (typeof window === "undefined") return;
|
|
343
|
+
const isMobile = window.innerWidth < 768;
|
|
344
|
+
if (!isMobile) {
|
|
345
|
+
setMobileSlideHeight(null);
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const heights = slideRefs.current.slice(0, items.length).map((node) => node?.offsetHeight ?? 0);
|
|
349
|
+
const maxHeight = Math.max(...heights, 0);
|
|
350
|
+
if (maxHeight > 0) {
|
|
351
|
+
setMobileSlideHeight(
|
|
352
|
+
(prev) => prev === maxHeight ? prev : maxHeight
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
updateHeights();
|
|
357
|
+
window.addEventListener("resize", updateHeights);
|
|
358
|
+
let resizeObserver = null;
|
|
359
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
360
|
+
resizeObserver = new ResizeObserver(updateHeights);
|
|
361
|
+
slideRefs.current.slice(0, items.length).forEach((node) => {
|
|
362
|
+
if (node) resizeObserver?.observe(node);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
return () => {
|
|
366
|
+
window.removeEventListener("resize", updateHeights);
|
|
367
|
+
resizeObserver?.disconnect();
|
|
368
|
+
};
|
|
369
|
+
}, [equalizeOnMobile, items.length]);
|
|
370
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
371
|
+
children,
|
|
372
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Carousel, { className: carouselClassName, children: [
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pb-18 md:pb-24", children: /* @__PURE__ */ jsxRuntime.jsx(CarouselContent, { className: "ease-in", children: items.map((item, itemIndex) => /* @__PURE__ */ jsxRuntime.jsx(CarouselItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
374
|
+
"div",
|
|
375
|
+
{
|
|
376
|
+
ref: (node) => {
|
|
377
|
+
slideRefs.current[itemIndex] = node;
|
|
378
|
+
},
|
|
379
|
+
style: equalizeOnMobile && mobileSlideHeight ? { minHeight: mobileSlideHeight } : void 0,
|
|
380
|
+
className: cn(
|
|
381
|
+
"flex flex-col gap-8 md:gap-14 md:flex-row md:items-center md:justify-between",
|
|
382
|
+
slideClassName
|
|
383
|
+
),
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full", contentClassName), children: item.content }),
|
|
386
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
387
|
+
"div",
|
|
388
|
+
{
|
|
389
|
+
className: cn(
|
|
390
|
+
"w-full",
|
|
391
|
+
mediaWrapperClassName,
|
|
392
|
+
mediaClassName
|
|
393
|
+
),
|
|
394
|
+
children: item.mediaComponent
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
]
|
|
398
|
+
}
|
|
399
|
+
) }, `slide-${itemIndex}`)) }) }),
|
|
400
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
401
|
+
CarouselPrevious,
|
|
402
|
+
{
|
|
403
|
+
className: cn(baseArrowClassName, "left-4 md:left-6", arrowClassName)
|
|
404
|
+
}
|
|
405
|
+
),
|
|
406
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
407
|
+
CarouselNext,
|
|
408
|
+
{
|
|
409
|
+
className: cn(baseArrowClassName, "right-4 md:right-6", arrowClassName)
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
] })
|
|
413
|
+
] });
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
exports.FeatureShowcase = FeatureShowcase;
|
|
417
|
+
//# sourceMappingURL=feature-showcase.cjs.map
|
|
418
|
+
//# sourceMappingURL=feature-showcase.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../icons/arrow-left.tsx","../icons/arrow-right.tsx","../components/ui/button.tsx","../components/ui/carousel.tsx","../components/blocks/features/feature-showcase.tsx"],"names":["twMerge","clsx","jsx","cva","Slot","React","useEmblaCarousel","api","jsxs","useState","useRef","useEffect"],"mappings":"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","file":"feature-showcase.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { SVGProps } from \"react\";\n\nexport interface IconProps extends SVGProps<SVGSVGElement> {\n size?: number | string;\n}\n\nexport const ArrowLeft = ({\n size = 24,\n className,\n strokeWidth = 2,\n ...props\n}: IconProps) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"m12 19l-7-7l7-7m7 7H5\" />\n </svg>\n );\n};\n","import type { SVGProps } from \"react\";\n\nexport interface IconProps extends SVGProps<SVGSVGElement> {\n size?: number | string;\n}\n\nexport const ArrowRight = ({\n size = 24,\n className,\n strokeWidth = 2,\n ...props\n}: IconProps) => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n {...props}\n >\n <path d=\"M5 12h14m-7-7l7 7l-7 7\" />\n </svg>\n );\n};\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-button text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-[var(--button-default-bg,hsl(var(--primary)))] text-[var(--button-default-fg,hsl(var(--primary-foreground)))] hover:bg-[var(--button-default-hover-bg,hsl(var(--primary)/0.9))]\",\n destructive:\n \"bg-[var(--button-destructive-bg,hsl(var(--destructive)))] text-[var(--button-destructive-fg,white)] hover:bg-[var(--button-destructive-hover-bg,hsl(var(--destructive)/0.9))] focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border-[var(--button-outline-border-width,1px)] border-[var(--button-outline-border,hsl(var(--border)))] bg-[var(--button-outline-bg,hsl(var(--background)))] text-[var(--button-outline-fg,inherit)] shadow-xs hover:bg-[var(--button-outline-hover-bg,hsl(var(--accent)))] hover:text-[var(--button-outline-hover-fg,hsl(var(--accent-foreground)))] dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-[var(--button-secondary-bg,hsl(var(--secondary)))] text-[var(--button-secondary-fg,hsl(var(--secondary-foreground)))] hover:bg-[var(--button-secondary-hover-bg,hsl(var(--secondary)/0.8))]\",\n ghost:\n \"bg-[var(--button-ghost-bg,transparent)] text-[var(--button-ghost-fg,inherit)] hover:bg-[var(--button-ghost-hover-bg,hsl(var(--accent)))] hover:text-[var(--button-ghost-hover-fg,hsl(var(--accent-foreground)))] dark:hover:bg-accent/50\",\n link: \"text-[var(--button-link-fg,hsl(var(--primary)))] underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-[var(--button-height-md,2.25rem)] px-[var(--button-padding-x-md,1rem)] py-2 has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]\",\n sm: \"h-[var(--button-height-sm,2rem)] rounded-button gap-1.5 px-[var(--button-padding-x-sm,0.75rem)] has-[>svg]:px-[calc(var(--button-padding-x-sm,0.75rem)*0.83)]\",\n md: \"h-[var(--button-height-md,2.25rem)] px-[var(--button-padding-x-md,1rem)] py-2 has-[>svg]:px-[calc(var(--button-padding-x-md,1rem)*0.75)]\",\n lg: \"h-[var(--button-height-lg,2.5rem)] rounded-button px-[var(--button-padding-x-lg,1.5rem)] has-[>svg]:px-[calc(var(--button-padding-x-lg,1.5rem)*0.67)]\",\n icon: \"size-[var(--button-height-md,2.25rem)]\",\n \"icon-sm\": \"size-[var(--button-height-sm,2rem)]\",\n \"icon-lg\": \"size-[var(--button-height-lg,2.5rem)]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n","import * as React from \"react\"\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\"\nimport { ArrowLeft } from \"../../icons/arrow-left\"\nimport { ArrowRight } from \"../../icons/arrow-right\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\n\ntype CarouselApi = UseEmblaCarouselType[1]\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>\ntype CarouselOptions = UseCarouselParameters[0]\ntype CarouselPlugin = UseCarouselParameters[1]\n\ntype CarouselProps = {\n opts?: CarouselOptions\n plugins?: CarouselPlugin\n orientation?: \"horizontal\" | \"vertical\"\n setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0]\n api: ReturnType<typeof useEmblaCarousel>[1]\n scrollPrev: () => void\n scrollNext: () => void\n canScrollPrev: boolean\n canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext)\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a <Carousel />\")\n }\n\n return context\n}\n\nfunction Carousel({\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins\n )\n const [canScrollPrev, setCanScrollPrev] = React.useState(false)\n const [canScrollNext, setCanScrollNext] = React.useState(false)\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) return\n setCanScrollPrev(api.canScrollPrev())\n setCanScrollNext(api.canScrollNext())\n }, [])\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev()\n }, [api])\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext()\n }, [api])\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault()\n scrollPrev()\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault()\n scrollNext()\n }\n },\n [scrollPrev, scrollNext]\n )\n\n React.useEffect(() => {\n if (!api || !setApi) return\n setApi(api)\n }, [api, setApi])\n\n React.useEffect(() => {\n if (!api) return\n onSelect(api)\n api.on(\"reInit\", onSelect)\n api.on(\"select\", onSelect)\n\n return () => {\n api?.off(\"select\", onSelect)\n }\n }, [api, onSelect])\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api: api,\n opts,\n orientation:\n orientation || (opts?.axis === \"y\" ? \"vertical\" : \"horizontal\"),\n scrollPrev,\n scrollNext,\n canScrollPrev,\n canScrollNext,\n }}\n >\n <div\n onKeyDownCapture={handleKeyDown}\n className={cn(\"relative\", className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n data-slot=\"carousel\"\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n )\n}\n\nfunction CarouselContent({ className, ...props }: React.ComponentProps<\"div\">) {\n const { carouselRef, orientation } = useCarousel()\n\n return (\n <div\n ref={carouselRef}\n className=\"overflow-hidden\"\n data-slot=\"carousel-content\"\n >\n <div\n className={cn(\n \"flex\",\n orientation === \"horizontal\" ? \"-ml-4\" : \"-mt-4 flex-col\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction CarouselItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const { orientation } = useCarousel()\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n data-slot=\"carousel-item\"\n className={cn(\n \"min-w-0 shrink-0 grow-0 basis-full\",\n orientation === \"horizontal\" ? \"pl-4\" : \"pt-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CarouselPrevious({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel()\n\n return (\n <Button\n data-slot=\"carousel-previous\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -left-12 -translate-y-1/2\"\n : \"-top-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollPrev}\n onClick={scrollPrev}\n {...props}\n >\n <ArrowLeft />\n <span className=\"sr-only\">Previous slide</span>\n </Button>\n )\n}\n\nfunction CarouselNext({\n className,\n variant = \"outline\",\n size = \"icon\",\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { orientation, scrollNext, canScrollNext } = useCarousel()\n\n return (\n <Button\n data-slot=\"carousel-next\"\n variant={variant}\n size={size}\n className={cn(\n \"absolute size-8 rounded-full\",\n orientation === \"horizontal\"\n ? \"top-1/2 -right-12 -translate-y-1/2\"\n : \"-bottom-12 left-1/2 -translate-x-1/2 rotate-90\",\n className\n )}\n disabled={!canScrollNext}\n onClick={scrollNext}\n {...props}\n >\n <ArrowRight />\n <span className=\"sr-only\">Next slide</span>\n </Button>\n )\n}\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"../../ui/carousel\";\n\nexport interface FeatureShowcaseItem {\n content: ReactNode;\n mediaComponent: ReactNode;\n}\n\nexport interface FeatureShowcaseProps {\n items: FeatureShowcaseItem[];\n children?: ReactNode;\n className?: string;\n carouselClassName?: string;\n slideClassName?: string;\n contentClassName?: string;\n mediaClassName?: string;\n arrowClassName?: string;\n equalizeOnMobile?: boolean;\n stretchMediaOnMobile?: boolean;\n}\n\n/**\n * Feature Showcase component with carousel navigation\n *\n * Displays feature content with media in a carousel format. Each slide shows\n * content (text, headings) alongside media (images, videos). Features mobile\n * height equalization for consistent slide heights and customizable styling.\n *\n * @example\n * ```tsx\n * <FeatureShowcase\n * items={[\n * {\n * content: <div><h3>Feature 1</h3><p>Description</p></div>,\n * mediaComponent: <img src=\"/feature1.jpg\" alt=\"Feature 1\" />\n * },\n * {\n * content: <div><h3>Feature 2</h3><p>Description</p></div>,\n * mediaComponent: <img src=\"/feature2.jpg\" alt=\"Feature 2\" />\n * }\n * ]}\n * />\n * ```\n */\nexport function FeatureShowcase({\n items,\n children,\n className,\n carouselClassName,\n slideClassName,\n contentClassName,\n mediaClassName,\n arrowClassName,\n equalizeOnMobile = true,\n stretchMediaOnMobile = true,\n}: FeatureShowcaseProps) {\n const baseArrowClassName =\n \"bottom-4 top-auto size-12 translate-y-0 rounded-full border border-current bg-transparent text-current shadow-sm focus:ring-current focus:ring-offset-2 focus:ring-offset-transparent hover:bg-current/10 md:bottom-6\";\n const [mobileSlideHeight, setMobileSlideHeight] = useState<number | null>(\n null\n );\n const slideRefs = useRef<Array<HTMLDivElement | null>>([]);\n const mediaWrapperClassName =\n equalizeOnMobile && stretchMediaOnMobile\n ? \"flex-1 min-h-0 md:flex-none\"\n : \"\";\n\n useEffect(() => {\n if (!equalizeOnMobile) {\n setMobileSlideHeight(null);\n return;\n }\n\n const updateHeights = () => {\n if (typeof window === \"undefined\") return;\n const isMobile = window.innerWidth < 768;\n\n if (!isMobile) {\n setMobileSlideHeight(null);\n return;\n }\n\n const heights = slideRefs.current\n .slice(0, items.length)\n .map((node) => node?.offsetHeight ?? 0);\n const maxHeight = Math.max(...heights, 0);\n\n if (maxHeight > 0) {\n setMobileSlideHeight((prev) =>\n prev === maxHeight ? prev : maxHeight\n );\n }\n };\n\n updateHeights();\n window.addEventListener(\"resize\", updateHeights);\n\n let resizeObserver: ResizeObserver | null = null;\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(updateHeights);\n slideRefs.current.slice(0, items.length).forEach((node) => {\n if (node) resizeObserver?.observe(node);\n });\n }\n\n return () => {\n window.removeEventListener(\"resize\", updateHeights);\n resizeObserver?.disconnect();\n };\n }, [equalizeOnMobile, items.length]);\n\n return (\n <div className={className}>\n {children}\n <Carousel className={carouselClassName}>\n <div className=\"pb-18 md:pb-24\">\n <CarouselContent className=\"ease-in\">\n {items.map((item, itemIndex) => (\n <CarouselItem key={`slide-${itemIndex}`}>\n <div\n ref={(node) => {\n slideRefs.current[itemIndex] = node;\n }}\n style={\n equalizeOnMobile && mobileSlideHeight\n ? { minHeight: mobileSlideHeight }\n : undefined\n }\n className={cn(\n \"flex flex-col gap-8 md:gap-14 md:flex-row md:items-center md:justify-between\",\n slideClassName\n )}\n >\n <div className={cn(\"w-full\", contentClassName)}>\n {item.content}\n </div>\n <div\n className={cn(\n \"w-full\",\n mediaWrapperClassName,\n mediaClassName\n )}\n >\n {item.mediaComponent}\n </div>\n </div>\n </CarouselItem>\n ))}\n </CarouselContent>\n </div>\n <CarouselPrevious\n className={cn(baseArrowClassName, \"left-4 md:left-6\", arrowClassName)}\n />\n <CarouselNext\n className={cn(baseArrowClassName, \"right-4 md:right-6\", arrowClassName)}\n />\n </Carousel>\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export { FeatureShowcaseItem, FeatureShowcaseProps } from './types.cjs';
|
|
4
|
+
|
|
5
|
+
interface FeatureShowcaseItem {
|
|
6
|
+
content: ReactNode;
|
|
7
|
+
mediaComponent: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
interface FeatureShowcaseProps {
|
|
10
|
+
items: FeatureShowcaseItem[];
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
carouselClassName?: string;
|
|
14
|
+
slideClassName?: string;
|
|
15
|
+
contentClassName?: string;
|
|
16
|
+
mediaClassName?: string;
|
|
17
|
+
arrowClassName?: string;
|
|
18
|
+
equalizeOnMobile?: boolean;
|
|
19
|
+
stretchMediaOnMobile?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Feature Showcase component with carousel navigation
|
|
23
|
+
*
|
|
24
|
+
* Displays feature content with media in a carousel format. Each slide shows
|
|
25
|
+
* content (text, headings) alongside media (images, videos). Features mobile
|
|
26
|
+
* height equalization for consistent slide heights and customizable styling.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <FeatureShowcase
|
|
31
|
+
* items={[
|
|
32
|
+
* {
|
|
33
|
+
* content: <div><h3>Feature 1</h3><p>Description</p></div>,
|
|
34
|
+
* mediaComponent: <img src="/feature1.jpg" alt="Feature 1" />
|
|
35
|
+
* },
|
|
36
|
+
* {
|
|
37
|
+
* content: <div><h3>Feature 2</h3><p>Description</p></div>,
|
|
38
|
+
* mediaComponent: <img src="/feature2.jpg" alt="Feature 2" />
|
|
39
|
+
* }
|
|
40
|
+
* ]}
|
|
41
|
+
* />
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function FeatureShowcase({ items, children, className, carouselClassName, slideClassName, contentClassName, mediaClassName, arrowClassName, equalizeOnMobile, stretchMediaOnMobile, }: FeatureShowcaseProps): react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
export { FeatureShowcase };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
export { FeatureShowcaseItem, FeatureShowcaseProps } from './types.js';
|
|
4
|
+
|
|
5
|
+
interface FeatureShowcaseItem {
|
|
6
|
+
content: ReactNode;
|
|
7
|
+
mediaComponent: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
interface FeatureShowcaseProps {
|
|
10
|
+
items: FeatureShowcaseItem[];
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
carouselClassName?: string;
|
|
14
|
+
slideClassName?: string;
|
|
15
|
+
contentClassName?: string;
|
|
16
|
+
mediaClassName?: string;
|
|
17
|
+
arrowClassName?: string;
|
|
18
|
+
equalizeOnMobile?: boolean;
|
|
19
|
+
stretchMediaOnMobile?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Feature Showcase component with carousel navigation
|
|
23
|
+
*
|
|
24
|
+
* Displays feature content with media in a carousel format. Each slide shows
|
|
25
|
+
* content (text, headings) alongside media (images, videos). Features mobile
|
|
26
|
+
* height equalization for consistent slide heights and customizable styling.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <FeatureShowcase
|
|
31
|
+
* items={[
|
|
32
|
+
* {
|
|
33
|
+
* content: <div><h3>Feature 1</h3><p>Description</p></div>,
|
|
34
|
+
* mediaComponent: <img src="/feature1.jpg" alt="Feature 1" />
|
|
35
|
+
* },
|
|
36
|
+
* {
|
|
37
|
+
* content: <div><h3>Feature 2</h3><p>Description</p></div>,
|
|
38
|
+
* mediaComponent: <img src="/feature2.jpg" alt="Feature 2" />
|
|
39
|
+
* }
|
|
40
|
+
* ]}
|
|
41
|
+
* />
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function FeatureShowcase({ items, children, className, carouselClassName, slideClassName, contentClassName, mediaClassName, arrowClassName, equalizeOnMobile, stretchMediaOnMobile, }: FeatureShowcaseProps): react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
export { FeatureShowcase };
|