@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.
Files changed (43) hide show
  1. package/dist/button.cjs +14 -13
  2. package/dist/button.cjs.map +1 -1
  3. package/dist/button.d.cts +1 -1
  4. package/dist/button.d.ts +1 -1
  5. package/dist/button.js +14 -13
  6. package/dist/button.js.map +1 -1
  7. package/dist/components.cjs +45 -15
  8. package/dist/components.cjs.map +1 -1
  9. package/dist/components.d.cts +1 -0
  10. package/dist/components.d.ts +1 -0
  11. package/dist/components.js +45 -16
  12. package/dist/components.js.map +1 -1
  13. package/dist/dynamic-icon.cjs +37 -0
  14. package/dist/dynamic-icon.cjs.map +1 -0
  15. package/dist/dynamic-icon.d.cts +46 -0
  16. package/dist/dynamic-icon.d.ts +46 -0
  17. package/dist/dynamic-icon.js +35 -0
  18. package/dist/dynamic-icon.js.map +1 -0
  19. package/dist/feature-showcase.cjs +418 -0
  20. package/dist/feature-showcase.cjs.map +1 -0
  21. package/dist/feature-showcase.d.cts +46 -0
  22. package/dist/feature-showcase.d.ts +46 -0
  23. package/dist/feature-showcase.js +394 -0
  24. package/dist/feature-showcase.js.map +1 -0
  25. package/dist/index.cjs +45 -15
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +2 -1
  28. package/dist/index.d.ts +2 -1
  29. package/dist/index.js +45 -16
  30. package/dist/index.js.map +1 -1
  31. package/dist/page-hero-banner.cjs +7 -2
  32. package/dist/page-hero-banner.cjs.map +1 -1
  33. package/dist/page-hero-banner.d.cts +1 -1
  34. package/dist/page-hero-banner.d.ts +1 -1
  35. package/dist/page-hero-banner.js +7 -2
  36. package/dist/page-hero-banner.js.map +1 -1
  37. package/dist/registry.cjs +461 -4
  38. package/dist/registry.cjs.map +1 -1
  39. package/dist/registry.js +442 -3
  40. package/dist/registry.js.map +1 -1
  41. package/dist/types.d.cts +68 -1
  42. package/dist/types.d.ts +68 -1
  43. package/package.json +12 -2
@@ -45,6 +45,8 @@ function PageHeroBanner({
45
45
  showOverlay = true,
46
46
  overlayOpacity = 0.6,
47
47
  contentMaxWidth = "4xl",
48
+ overlayClassName,
49
+ contentClassName,
48
50
  style,
49
51
  ...props
50
52
  }) {
@@ -90,7 +92,10 @@ function PageHeroBanner({
90
92
  showOverlay && /* @__PURE__ */ jsx(
91
93
  "div",
92
94
  {
93
- className: "absolute inset-0 bg-gradient-to-b from-black via-black to-black",
95
+ className: cn(
96
+ "absolute inset-0 bg-gradient-to-b from-black via-black to-black",
97
+ overlayClassName
98
+ ),
94
99
  style: { opacity: overlayOpacity }
95
100
  }
96
101
  ),
@@ -98,7 +103,7 @@ function PageHeroBanner({
98
103
  Container,
99
104
  {
100
105
  maxWidth: contentMaxWidth,
101
- className: "relative h-full flex items-center",
106
+ className: cn("relative h-full flex items-center", contentClassName),
102
107
  style: { minHeight },
103
108
  children: /* @__PURE__ */ jsx("div", { className: "relative text-background drop-shadow-lg py-16 md:py-24", children })
104
109
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/utils.ts","../components/ui/container.tsx","../components/ui/page-hero-banner.tsx"],"names":["jsx"],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACDA,IAAM,cAAA,GAAiB;AAAA,EACrB,EAAA,EAAI,iBAAA;AAAA,EACJ,EAAA,EAAI,iBAAA;AAAA,EACJ,EAAA,EAAI,iBAAA;AAAA,EACJ,EAAA,EAAI,iBAAA;AAAA,EACJ,KAAA,EAAO,kBAAA;AAAA,EACP,KAAA,EAAO,gBAAA;AAAA,EACP,IAAA,EAAM;AACR,CAAA;AAYO,IAAM,YAAY,KAAA,CAAM,UAAA;AAAA,EAC7B,CAAC,EAAE,QAAA,EAAU,QAAA,GAAW,IAAA,EAAM,SAAA,EAAW,EAAA,GAAK,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACvE,IAAA,MAAM,SAAA,GAAY,EAAA;AAClB,IAAA,uBACE,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,qCAAA;AAAA,UACA,eAAe,QAAQ,CAAA;AAAA,UACvB;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AACF,CAAA;AAEA,SAAA,CAAU,WAAA,GAAc,WAAA;ACrBjB,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAA,GAAM,aAAA;AAAA,EACN,QAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,OAAA,GAAU,OAAA;AAAA,EACV,SAAA,GAAY,OAAA;AAAA,EACZ,WAAA,GAAc,IAAA;AAAA,EACd,cAAA,GAAiB,GAAA;AAAA,EACjB,eAAA,GAAkB,KAAA;AAAA,EAClB,KAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAwB;AACtB,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,QAAA,EAAU;AAC1B,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AAEA,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,iCAAA,EAAmC,SAAS,CAAA;AAAA,MAC1D,KAAA,EAAO;AAAA,QACL,SAAA;AAAA,QACA,GAAG;AAAA,OACL;AAAA,MACC,GAAG,KAAA;AAAA,MAGH,QAAA,EAAA;AAAA,QAAA,QAAA,oBACCA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,GAAA;AAAA,YACA,OAAA;AAAA,YACA,SAAA,EAAU;AAAA;AAAA,SACZ;AAAA,QAID,4BACCA,GAAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,GAAA,EAAK,QAAA;AAAA,YACL,SAAA,EAAU,6CAAA;AAAA,YACV,QAAA,EAAQ,IAAA;AAAA,YACR,IAAA,EAAI,IAAA;AAAA,YACJ,KAAA,EAAK,IAAA;AAAA,YACL,WAAA,EAAW,IAAA;AAAA,YACX,OAAA,EAAQ;AAAA;AAAA,SACV;AAAA,QAID,+BACCA,GAAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,iEAAA;AAAA,YACV,KAAA,EAAO,EAAE,OAAA,EAAS,cAAA;AAAe;AAAA,SACnC;AAAA,wBAIFA,GAAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,QAAA,EAAU,eAAA;AAAA,YACV,SAAA,EAAU,mCAAA;AAAA,YACV,KAAA,EAAO,EAAE,SAAA,EAAU;AAAA,YAEnB,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0DACZ,QAAA,EACH;AAAA;AAAA;AACF;AAAA;AAAA,GACF;AAEJ","file":"page-hero-banner.js","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 React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport type { ContainerProps } from \"../../src/types\";\n\nconst maxWidthStyles = {\n sm: \"max-w-screen-sm\",\n md: \"max-w-screen-md\",\n lg: \"max-w-screen-lg\",\n xl: \"max-w-screen-xl\",\n \"2xl\": \"max-w-screen-2xl\",\n \"4xl\": \"max-w-[1536px]\",\n full: \"max-w-full\",\n};\n\n/**\n * Container component for consistent content width and centering\n *\n * @example\n * ```tsx\n * <Container maxWidth=\"xl\">\n * <h1>Page Content</h1>\n * </Container>\n * ```\n */\nexport const Container = React.forwardRef<HTMLDivElement, ContainerProps>(\n ({ children, maxWidth = \"xl\", className, as = \"div\", ...props }, ref) => {\n const Component = as as any;\n return (\n <Component\n ref={ref}\n className={cn(\n \"mx-auto w-full px-4 sm:px-6 lg:px-8\",\n maxWidthStyles[maxWidth],\n className\n )}\n {...props}\n >\n {children}\n </Component>\n );\n }\n);\n\nContainer.displayName = \"Container\";\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Container } from \"./container\";\nimport type { PageHeroBannerProps } from \"../../src/types\";\n\n/**\n * Page Hero Banner component for full-width hero sections with image or video backgrounds\n *\n * @example\n * ```tsx\n * <PageHeroBanner\n * imageUrl=\"https://example.com/hero.jpg\"\n * alt=\"Hero banner\"\n * minHeight=\"600px\"\n * >\n * <h1>Welcome to our site</h1>\n * <p>Discover amazing content</p>\n * </PageHeroBanner>\n * ```\n */\nexport function PageHeroBanner({\n imageUrl,\n videoUrl,\n alt = \"Hero banner\",\n children,\n className = \"\",\n loading = \"eager\",\n minHeight = \"500px\",\n showOverlay = true,\n overlayOpacity = 0.6,\n contentMaxWidth = \"4xl\",\n style,\n ...props\n}: PageHeroBannerProps) {\n if (!imageUrl && !videoUrl) {\n throw new Error(\"PageHeroBanner requires either imageUrl or videoUrl\");\n }\n\n if (imageUrl && videoUrl) {\n throw new Error(\n \"PageHeroBanner cannot have both imageUrl and videoUrl. Please provide only one.\",\n );\n }\n\n return (\n <div\n className={cn(\"relative w-full overflow-hidden\", className)}\n style={{\n minHeight,\n ...style,\n }}\n {...props}\n >\n {/* Image background */}\n {imageUrl && (\n <img\n src={imageUrl}\n alt={alt}\n loading={loading}\n className=\"absolute inset-0 w-full h-full object-cover\"\n />\n )}\n\n {/* Video background */}\n {videoUrl && (\n <video\n src={videoUrl}\n className=\"absolute inset-0 w-full h-full object-cover\"\n autoPlay\n loop\n muted\n playsInline\n preload=\"auto\"\n />\n )}\n\n {/* Gradient overlay */}\n {showOverlay && (\n <div\n className=\"absolute inset-0 bg-gradient-to-b from-black via-black to-black\"\n style={{ opacity: overlayOpacity }}\n />\n )}\n\n {/* Content */}\n <Container\n maxWidth={contentMaxWidth}\n className=\"relative h-full flex items-center\"\n style={{ minHeight }}\n >\n <div className=\"relative text-background drop-shadow-lg py-16 md:py-24\">\n {children}\n </div>\n </Container>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../lib/utils.ts","../components/ui/container.tsx","../components/ui/page-hero-banner.tsx"],"names":["jsx"],"mappings":"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","file":"page-hero-banner.js","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 React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport type { ContainerProps } from \"../../src/types\";\n\nconst maxWidthStyles = {\n sm: \"max-w-screen-sm\",\n md: \"max-w-screen-md\",\n lg: \"max-w-screen-lg\",\n xl: \"max-w-screen-xl\",\n \"2xl\": \"max-w-screen-2xl\",\n \"4xl\": \"max-w-[1536px]\",\n full: \"max-w-full\",\n};\n\n/**\n * Container component for consistent content width and centering\n *\n * @example\n * ```tsx\n * <Container maxWidth=\"xl\">\n * <h1>Page Content</h1>\n * </Container>\n * ```\n */\nexport const Container = React.forwardRef<HTMLDivElement, ContainerProps>(\n ({ children, maxWidth = \"xl\", className, as = \"div\", ...props }, ref) => {\n const Component = as as any;\n return (\n <Component\n ref={ref}\n className={cn(\n \"mx-auto w-full px-4 sm:px-6 lg:px-8\",\n maxWidthStyles[maxWidth],\n className\n )}\n {...props}\n >\n {children}\n </Component>\n );\n }\n);\n\nContainer.displayName = \"Container\";\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Container } from \"./container\";\nimport type { PageHeroBannerProps } from \"../../src/types\";\n\n/**\n * Page Hero Banner component for full-width hero sections with image or video backgrounds\n *\n * @example\n * ```tsx\n * <PageHeroBanner\n * imageUrl=\"https://example.com/hero.jpg\"\n * alt=\"Hero banner\"\n * minHeight=\"600px\"\n * >\n * <h1>Welcome to our site</h1>\n * <p>Discover amazing content</p>\n * </PageHeroBanner>\n * ```\n */\nexport function PageHeroBanner({\n imageUrl,\n videoUrl,\n alt = \"Hero banner\",\n children,\n className = \"\",\n loading = \"eager\",\n minHeight = \"500px\",\n showOverlay = true,\n overlayOpacity = 0.6,\n contentMaxWidth = \"4xl\",\n overlayClassName,\n contentClassName,\n style,\n ...props\n}: PageHeroBannerProps) {\n if (!imageUrl && !videoUrl) {\n throw new Error(\"PageHeroBanner requires either imageUrl or videoUrl\");\n }\n\n if (imageUrl && videoUrl) {\n throw new Error(\n \"PageHeroBanner cannot have both imageUrl and videoUrl. Please provide only one.\",\n );\n }\n\n return (\n <div\n className={cn(\"relative w-full overflow-hidden\", className)}\n style={{\n minHeight,\n ...style,\n }}\n {...props}\n >\n {/* Image background */}\n {imageUrl && (\n <img\n src={imageUrl}\n alt={alt}\n loading={loading}\n className=\"absolute inset-0 w-full h-full object-cover\"\n />\n )}\n\n {/* Video background */}\n {videoUrl && (\n <video\n src={videoUrl}\n className=\"absolute inset-0 w-full h-full object-cover\"\n autoPlay\n loop\n muted\n playsInline\n preload=\"auto\"\n />\n )}\n\n {/* Gradient overlay */}\n {showOverlay && (\n <div\n className={cn(\n \"absolute inset-0 bg-gradient-to-b from-black via-black to-black\",\n overlayClassName\n )}\n style={{ opacity: overlayOpacity }}\n />\n )}\n\n {/* Content */}\n <Container\n maxWidth={contentMaxWidth}\n className={cn(\"relative h-full flex items-center\", contentClassName)}\n style={{ minHeight }}\n >\n <div className=\"relative text-background drop-shadow-lg py-16 md:py-24\">\n {children}\n </div>\n </Container>\n </div>\n );\n}\n"]}
package/dist/registry.cjs CHANGED
@@ -2,12 +2,34 @@
2
2
 
3
3
  var clsx = require('clsx');
4
4
  var tailwindMerge = require('tailwind-merge');
5
- var React = require('react');
5
+ var React3 = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
+ var useEmblaCarousel = require('embla-carousel-react');
8
+ var reactSlot = require('@radix-ui/react-slot');
9
+ var classVarianceAuthority = require('class-variance-authority');
7
10
 
8
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
12
 
10
- var React__default = /*#__PURE__*/_interopDefault(React);
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 React3__namespace = /*#__PURE__*/_interopNamespace(React3);
32
+ var useEmblaCarousel__default = /*#__PURE__*/_interopDefault(useEmblaCarousel);
11
33
 
12
34
  // lib/utils.ts
13
35
  function cn(...inputs) {
@@ -22,7 +44,7 @@ var maxWidthStyles = {
22
44
  "4xl": "max-w-[1536px]",
23
45
  full: "max-w-full"
24
46
  };
25
- var Container = React__default.default.forwardRef(
47
+ var Container = React3__namespace.default.forwardRef(
26
48
  ({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
27
49
  const Component = as;
28
50
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -56,7 +78,7 @@ var spacingStyles = {
56
78
  lg: "py-20 md:py-32",
57
79
  xl: "py-24 md:py-40"
58
80
  };
59
- var Section = React__default.default.forwardRef(
81
+ var Section = React3__namespace.default.forwardRef(
60
82
  ({
61
83
  id,
62
84
  title,
@@ -132,6 +154,383 @@ function AlternatingBlocks({
132
154
  }
133
155
  );
134
156
  }
157
+ var ArrowLeft = ({
158
+ size = 24,
159
+ className,
160
+ strokeWidth = 2,
161
+ ...props
162
+ }) => {
163
+ return /* @__PURE__ */ jsxRuntime.jsx(
164
+ "svg",
165
+ {
166
+ xmlns: "http://www.w3.org/2000/svg",
167
+ width: size,
168
+ height: size,
169
+ viewBox: "0 0 24 24",
170
+ fill: "none",
171
+ stroke: "currentColor",
172
+ strokeWidth,
173
+ strokeLinecap: "round",
174
+ strokeLinejoin: "round",
175
+ className,
176
+ ...props,
177
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m12 19l-7-7l7-7m7 7H5" })
178
+ }
179
+ );
180
+ };
181
+ var ArrowRight = ({
182
+ size = 24,
183
+ className,
184
+ strokeWidth = 2,
185
+ ...props
186
+ }) => {
187
+ return /* @__PURE__ */ jsxRuntime.jsx(
188
+ "svg",
189
+ {
190
+ xmlns: "http://www.w3.org/2000/svg",
191
+ width: size,
192
+ height: size,
193
+ viewBox: "0 0 24 24",
194
+ fill: "none",
195
+ stroke: "currentColor",
196
+ strokeWidth,
197
+ strokeLinecap: "round",
198
+ strokeLinejoin: "round",
199
+ className,
200
+ ...props,
201
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14m-7-7l7 7l-7 7" })
202
+ }
203
+ );
204
+ };
205
+ var buttonVariants = classVarianceAuthority.cva(
206
+ "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",
207
+ {
208
+ variants: {
209
+ variant: {
210
+ 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))]",
211
+ 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",
212
+ 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",
213
+ 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))]",
214
+ 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",
215
+ link: "text-[var(--button-link-fg,hsl(var(--primary)))] underline-offset-4 hover:underline"
216
+ },
217
+ size: {
218
+ 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)]",
219
+ 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)]",
220
+ 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)]",
221
+ 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)]",
222
+ icon: "size-[var(--button-height-md,2.25rem)]",
223
+ "icon-sm": "size-[var(--button-height-sm,2rem)]",
224
+ "icon-lg": "size-[var(--button-height-lg,2.5rem)]"
225
+ }
226
+ },
227
+ defaultVariants: {
228
+ variant: "default",
229
+ size: "default"
230
+ }
231
+ }
232
+ );
233
+ function Button({
234
+ className,
235
+ variant = "default",
236
+ size = "default",
237
+ asChild = false,
238
+ ...props
239
+ }) {
240
+ const Comp = asChild ? reactSlot.Slot : "button";
241
+ return /* @__PURE__ */ jsxRuntime.jsx(
242
+ Comp,
243
+ {
244
+ "data-slot": "button",
245
+ "data-variant": variant,
246
+ "data-size": size,
247
+ className: cn(buttonVariants({ variant, size, className })),
248
+ ...props
249
+ }
250
+ );
251
+ }
252
+ var CarouselContext = React3__namespace.createContext(null);
253
+ function useCarousel() {
254
+ const context = React3__namespace.useContext(CarouselContext);
255
+ if (!context) {
256
+ throw new Error("useCarousel must be used within a <Carousel />");
257
+ }
258
+ return context;
259
+ }
260
+ function Carousel({
261
+ orientation = "horizontal",
262
+ opts,
263
+ setApi,
264
+ plugins,
265
+ className,
266
+ children,
267
+ ...props
268
+ }) {
269
+ const [carouselRef, api] = useEmblaCarousel__default.default(
270
+ {
271
+ ...opts,
272
+ axis: orientation === "horizontal" ? "x" : "y"
273
+ },
274
+ plugins
275
+ );
276
+ const [canScrollPrev, setCanScrollPrev] = React3__namespace.useState(false);
277
+ const [canScrollNext, setCanScrollNext] = React3__namespace.useState(false);
278
+ const onSelect = React3__namespace.useCallback((api2) => {
279
+ if (!api2) return;
280
+ setCanScrollPrev(api2.canScrollPrev());
281
+ setCanScrollNext(api2.canScrollNext());
282
+ }, []);
283
+ const scrollPrev = React3__namespace.useCallback(() => {
284
+ api?.scrollPrev();
285
+ }, [api]);
286
+ const scrollNext = React3__namespace.useCallback(() => {
287
+ api?.scrollNext();
288
+ }, [api]);
289
+ const handleKeyDown = React3__namespace.useCallback(
290
+ (event) => {
291
+ if (event.key === "ArrowLeft") {
292
+ event.preventDefault();
293
+ scrollPrev();
294
+ } else if (event.key === "ArrowRight") {
295
+ event.preventDefault();
296
+ scrollNext();
297
+ }
298
+ },
299
+ [scrollPrev, scrollNext]
300
+ );
301
+ React3__namespace.useEffect(() => {
302
+ if (!api || !setApi) return;
303
+ setApi(api);
304
+ }, [api, setApi]);
305
+ React3__namespace.useEffect(() => {
306
+ if (!api) return;
307
+ onSelect(api);
308
+ api.on("reInit", onSelect);
309
+ api.on("select", onSelect);
310
+ return () => {
311
+ api?.off("select", onSelect);
312
+ };
313
+ }, [api, onSelect]);
314
+ return /* @__PURE__ */ jsxRuntime.jsx(
315
+ CarouselContext.Provider,
316
+ {
317
+ value: {
318
+ carouselRef,
319
+ api,
320
+ opts,
321
+ orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
322
+ scrollPrev,
323
+ scrollNext,
324
+ canScrollPrev,
325
+ canScrollNext
326
+ },
327
+ children: /* @__PURE__ */ jsxRuntime.jsx(
328
+ "div",
329
+ {
330
+ onKeyDownCapture: handleKeyDown,
331
+ className: cn("relative", className),
332
+ role: "region",
333
+ "aria-roledescription": "carousel",
334
+ "data-slot": "carousel",
335
+ ...props,
336
+ children
337
+ }
338
+ )
339
+ }
340
+ );
341
+ }
342
+ function CarouselContent({ className, ...props }) {
343
+ const { carouselRef, orientation } = useCarousel();
344
+ return /* @__PURE__ */ jsxRuntime.jsx(
345
+ "div",
346
+ {
347
+ ref: carouselRef,
348
+ className: "overflow-hidden",
349
+ "data-slot": "carousel-content",
350
+ children: /* @__PURE__ */ jsxRuntime.jsx(
351
+ "div",
352
+ {
353
+ className: cn(
354
+ "flex",
355
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
356
+ className
357
+ ),
358
+ ...props
359
+ }
360
+ )
361
+ }
362
+ );
363
+ }
364
+ function CarouselItem({ className, ...props }) {
365
+ const { orientation } = useCarousel();
366
+ return /* @__PURE__ */ jsxRuntime.jsx(
367
+ "div",
368
+ {
369
+ role: "group",
370
+ "aria-roledescription": "slide",
371
+ "data-slot": "carousel-item",
372
+ className: cn(
373
+ "min-w-0 shrink-0 grow-0 basis-full",
374
+ orientation === "horizontal" ? "pl-4" : "pt-4",
375
+ className
376
+ ),
377
+ ...props
378
+ }
379
+ );
380
+ }
381
+ function CarouselPrevious({
382
+ className,
383
+ variant = "outline",
384
+ size = "icon",
385
+ ...props
386
+ }) {
387
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
388
+ return /* @__PURE__ */ jsxRuntime.jsxs(
389
+ Button,
390
+ {
391
+ "data-slot": "carousel-previous",
392
+ variant,
393
+ size,
394
+ className: cn(
395
+ "absolute size-8 rounded-full",
396
+ orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
397
+ className
398
+ ),
399
+ disabled: !canScrollPrev,
400
+ onClick: scrollPrev,
401
+ ...props,
402
+ children: [
403
+ /* @__PURE__ */ jsxRuntime.jsx(ArrowLeft, {}),
404
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Previous slide" })
405
+ ]
406
+ }
407
+ );
408
+ }
409
+ function CarouselNext({
410
+ className,
411
+ variant = "outline",
412
+ size = "icon",
413
+ ...props
414
+ }) {
415
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
416
+ return /* @__PURE__ */ jsxRuntime.jsxs(
417
+ Button,
418
+ {
419
+ "data-slot": "carousel-next",
420
+ variant,
421
+ size,
422
+ className: cn(
423
+ "absolute size-8 rounded-full",
424
+ orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
425
+ className
426
+ ),
427
+ disabled: !canScrollNext,
428
+ onClick: scrollNext,
429
+ ...props,
430
+ children: [
431
+ /* @__PURE__ */ jsxRuntime.jsx(ArrowRight, {}),
432
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Next slide" })
433
+ ]
434
+ }
435
+ );
436
+ }
437
+ function FeatureShowcase({
438
+ items,
439
+ children,
440
+ className,
441
+ carouselClassName,
442
+ slideClassName,
443
+ contentClassName,
444
+ mediaClassName,
445
+ arrowClassName,
446
+ equalizeOnMobile = true,
447
+ stretchMediaOnMobile = true
448
+ }) {
449
+ 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";
450
+ const [mobileSlideHeight, setMobileSlideHeight] = React3.useState(
451
+ null
452
+ );
453
+ const slideRefs = React3.useRef([]);
454
+ const mediaWrapperClassName = equalizeOnMobile && stretchMediaOnMobile ? "flex-1 min-h-0 md:flex-none" : "";
455
+ React3.useEffect(() => {
456
+ if (!equalizeOnMobile) {
457
+ setMobileSlideHeight(null);
458
+ return;
459
+ }
460
+ const updateHeights = () => {
461
+ if (typeof window === "undefined") return;
462
+ const isMobile = window.innerWidth < 768;
463
+ if (!isMobile) {
464
+ setMobileSlideHeight(null);
465
+ return;
466
+ }
467
+ const heights = slideRefs.current.slice(0, items.length).map((node) => node?.offsetHeight ?? 0);
468
+ const maxHeight = Math.max(...heights, 0);
469
+ if (maxHeight > 0) {
470
+ setMobileSlideHeight(
471
+ (prev) => prev === maxHeight ? prev : maxHeight
472
+ );
473
+ }
474
+ };
475
+ updateHeights();
476
+ window.addEventListener("resize", updateHeights);
477
+ let resizeObserver = null;
478
+ if (typeof ResizeObserver !== "undefined") {
479
+ resizeObserver = new ResizeObserver(updateHeights);
480
+ slideRefs.current.slice(0, items.length).forEach((node) => {
481
+ if (node) resizeObserver?.observe(node);
482
+ });
483
+ }
484
+ return () => {
485
+ window.removeEventListener("resize", updateHeights);
486
+ resizeObserver?.disconnect();
487
+ };
488
+ }, [equalizeOnMobile, items.length]);
489
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
490
+ children,
491
+ /* @__PURE__ */ jsxRuntime.jsxs(Carousel, { className: carouselClassName, children: [
492
+ /* @__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(
493
+ "div",
494
+ {
495
+ ref: (node) => {
496
+ slideRefs.current[itemIndex] = node;
497
+ },
498
+ style: equalizeOnMobile && mobileSlideHeight ? { minHeight: mobileSlideHeight } : void 0,
499
+ className: cn(
500
+ "flex flex-col gap-8 md:gap-14 md:flex-row md:items-center md:justify-between",
501
+ slideClassName
502
+ ),
503
+ children: [
504
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full", contentClassName), children: item.content }),
505
+ /* @__PURE__ */ jsxRuntime.jsx(
506
+ "div",
507
+ {
508
+ className: cn(
509
+ "w-full",
510
+ mediaWrapperClassName,
511
+ mediaClassName
512
+ ),
513
+ children: item.mediaComponent
514
+ }
515
+ )
516
+ ]
517
+ }
518
+ ) }, `slide-${itemIndex}`)) }) }),
519
+ /* @__PURE__ */ jsxRuntime.jsx(
520
+ CarouselPrevious,
521
+ {
522
+ className: cn(baseArrowClassName, "left-4 md:left-6", arrowClassName)
523
+ }
524
+ ),
525
+ /* @__PURE__ */ jsxRuntime.jsx(
526
+ CarouselNext,
527
+ {
528
+ className: cn(baseArrowClassName, "right-4 md:right-6", arrowClassName)
529
+ }
530
+ )
531
+ ] })
532
+ ] });
533
+ }
135
534
 
136
535
  // src/registry/blocks.ts
137
536
  var BLOCK_REGISTRY = {
@@ -183,6 +582,64 @@ var BLOCK_REGISTRY = {
183
582
  mediaLeft: true
184
583
  }
185
584
  ]}
585
+ />
586
+ `.trim()
587
+ },
588
+ "feature-showcase": {
589
+ id: "feature-showcase",
590
+ name: "Feature Showcase Carousel",
591
+ description: "Display feature content with media in an interactive carousel format. Each slide shows feature content alongside images or videos with smooth navigation. Features mobile height equalization for consistent appearance.",
592
+ semanticTags: [
593
+ "features",
594
+ "carousel",
595
+ "showcase",
596
+ "slider",
597
+ "highlights",
598
+ "product-features",
599
+ "capabilities",
600
+ "interactive",
601
+ "media-gallery"
602
+ ],
603
+ category: "features",
604
+ component: FeatureShowcase,
605
+ props: "FeatureShowcaseProps",
606
+ exampleUsage: `
607
+ <FeatureShowcase
608
+ items={[
609
+ {
610
+ content: (
611
+ <div>
612
+ <span className="text-sm font-medium text-primary mb-2 block">
613
+ DESIGNED TO HELP YOU GROW
614
+ </span>
615
+ <h3 className="mb-4 text-3xl font-bold tracking-tight">
616
+ Powerful Analytics
617
+ </h3>
618
+ <p className="text-muted-foreground leading-relaxed">
619
+ Track every metric that matters with real-time dashboards
620
+ and comprehensive reporting tools.
621
+ </p>
622
+ </div>
623
+ ),
624
+ mediaComponent: <img src="..." alt="Analytics Dashboard" className="rounded-lg" />
625
+ },
626
+ {
627
+ content: (
628
+ <div>
629
+ <span className="text-sm font-medium text-primary mb-2 block">
630
+ SEAMLESS INTEGRATION
631
+ </span>
632
+ <h3 className="mb-4 text-3xl font-bold tracking-tight">
633
+ Connect Anywhere
634
+ </h3>
635
+ <p className="text-muted-foreground leading-relaxed">
636
+ Integrate with your favorite tools and platforms in seconds.
637
+ </p>
638
+ </div>
639
+ ),
640
+ mediaComponent: <img src="..." alt="Integrations" className="rounded-lg" />
641
+ }
642
+ ]}
186
643
  />
187
644
  `.trim()
188
645
  }