@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
package/dist/registry.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/utils.ts","../components/ui/container.tsx","../components/ui/section.tsx","../components/blocks/about/alternating-blocks.tsx","../src/registry/blocks.ts"],"names":["twMerge","clsx","React","jsx","jsxs"],"mappings":"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","file":"registry.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 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","import React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Container } from \"./container\";\nimport type { SectionProps } from \"../../src/types\";\n\n/**\n * Background style variants\n * Uses standard Tailwind/shadcn CSS variables for theming\n */\nconst backgroundStyles = {\n white: \"bg-background text-foreground\",\n gray: \"bg-muted/30 text-foreground\",\n dark: \"bg-foreground text-background\",\n gradient: \"bg-gradient-to-br from-primary via-primary/90 to-foreground text-primary-foreground\",\n primary: \"bg-primary text-primary-foreground\",\n secondary: \"bg-secondary text-secondary-foreground\",\n muted: \"bg-muted text-muted-foreground\",\n};\n\n/**\n * Vertical spacing variants\n */\nconst spacingStyles = {\n sm: \"py-12 md:py-16\",\n md: \"py-16 md:py-24\",\n lg: \"py-20 md:py-32\",\n xl: \"py-24 md:py-40\",\n};\n\n/**\n * Section component for consistent page sections with optional title, subtitle, and background\n *\n * @example\n * ```tsx\n * <Section\n * title=\"Our Services\"\n * subtitle=\"What we offer\"\n * background=\"gray\"\n * spacing=\"lg\"\n * >\n * <div>Section content goes here</div>\n * </Section>\n * ```\n */\nexport const Section = React.forwardRef<HTMLElement, SectionProps>(\n (\n {\n id,\n title,\n subtitle,\n children,\n className,\n style,\n background = \"white\",\n spacing = \"lg\",\n ...props\n },\n ref\n ) => {\n return (\n <section\n ref={ref}\n id={id}\n className={cn(\n backgroundStyles[background],\n spacingStyles[spacing],\n className\n )}\n style={style}\n {...props}\n >\n <Container>\n {(title || subtitle) && (\n <div className=\"text-center mb-12 md:mb-16\">\n {subtitle && (\n <p className=\"text-sm font-semibold uppercase tracking-wider mb-2 text-primary\">\n {subtitle}\n </p>\n )}\n {title && (\n <h2 className=\"text-3xl md:text-4xl lg:text-5xl font-bold tracking-tight\">\n {title}\n </h2>\n )}\n </div>\n )}\n {children}\n </Container>\n </section>\n );\n }\n);\n\nSection.displayName = \"Section\";\n","import * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Section } from \"../../ui/section\";\nimport type { SectionBackground, SectionSpacing } from \"../../../src/types\";\n\nexport interface AlternatingBlockSection {\n content: React.ReactNode;\n media: React.ReactNode;\n mediaLeft?: boolean;\n}\n\nexport interface AlternatingBlocksProps {\n /**\n * Array of sections to display with alternating layout\n */\n sections: AlternatingBlockSection[];\n /**\n * Section title (optional)\n */\n title?: string;\n /**\n * Section subtitle/eyebrow (optional)\n */\n subtitle?: string;\n /**\n * Background style variant\n * @default \"white\"\n */\n background?: SectionBackground;\n /**\n * Vertical spacing variant\n * @default \"lg\"\n */\n spacing?: SectionSpacing;\n /**\n * Additional CSS classes for the Section wrapper\n */\n className?: string;\n /**\n * Additional CSS classes for the content container\n */\n contentClassName?: string;\n}\n\n/**\n * AlternatingBlocks component displays content sections with alternating media placement.\n * Uses the Section component for consistent spacing, backgrounds, and optional titles.\n *\n * @example\n * ```tsx\n * <AlternatingBlocks\n * title=\"Our Story\"\n * subtitle=\"About Us\"\n * background=\"gray\"\n * spacing=\"xl\"\n * sections={[\n * {\n * content: <div><h3>Title</h3><p>Description</p></div>,\n * media: <img src=\"...\" alt=\"...\" />,\n * mediaLeft: false\n * }\n * ]}\n * />\n * ```\n */\nexport function AlternatingBlocks({\n sections,\n title,\n subtitle,\n background = \"white\",\n spacing = \"lg\",\n className,\n contentClassName,\n}: AlternatingBlocksProps) {\n return (\n <Section\n title={title}\n subtitle={subtitle}\n background={background}\n spacing={spacing}\n className={className}\n >\n <div className={cn(\"mx-auto w-full max-w-[900px]\", contentClassName)}>\n <div className=\"space-y-12\">\n {sections?.map((section, index) => (\n <div\n key={index}\n className=\"grid items-center gap-8 md:grid-cols-2 md:gap-12\"\n >\n <div className={section.mediaLeft ? \"md:order-2\" : \"\"}>\n {section.content}\n </div>\n\n <div\n className={cn(\n \"aspect-4/3 overflow-hidden rounded-lg border\",\n section.mediaLeft ? \"md:order-1\" : \"\",\n )}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {section.media}\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n </Section>\n );\n}\n","/**\n * Semantic Block Registry\n *\n * This registry maps semantic concepts to available UI blocks for AI-driven\n * site generation. Each block entry contains:\n * - id: Unique identifier for the block\n * - name: Human-readable name\n * - description: What the block does and when to use it\n * - semanticTags: Array of semantic concepts this block represents\n * - category: Block category (about, features, cta, testimonials, etc.)\n * - component: Reference to the actual component\n * - props: TypeScript type for the component's props\n * - exampleUsage: Code example showing how to use the block\n */\n\nimport { AlternatingBlocks } from \"../../components/blocks/about/alternating-blocks\";\nimport type { AlternatingBlocksProps } from \"../../components/blocks/about/alternating-blocks\";\n\nexport interface BlockRegistryEntry<T = any> {\n id: string;\n name: string;\n description: string;\n semanticTags: string[];\n category: BlockCategory;\n component: React.ComponentType<T>;\n props: string;\n exampleUsage: string;\n}\n\nexport type BlockCategory =\n | \"about\"\n | \"features\"\n | \"cta\"\n | \"testimonials\"\n | \"services\"\n | \"hero\"\n | \"footer\"\n | \"header\"\n | \"pricing\"\n | \"team\"\n | \"stats\"\n | \"faq\"\n | \"contact\"\n | \"gallery\"\n | \"timeline\"\n | \"process\"\n | \"benefits\"\n | \"comparison\";\n\n/**\n * Block Registry - Central registry of all available UI blocks\n */\nexport const BLOCK_REGISTRY: Record<string, BlockRegistryEntry> = {\n \"alternating-blocks\": {\n id: \"alternating-blocks\",\n name: \"Alternating Content Blocks\",\n description:\n \"Display content sections with alternating left/right media placement. Ideal for storytelling, feature showcases, or company history sections.\",\n semanticTags: [\n \"about\",\n \"story\",\n \"history\",\n \"timeline\",\n \"features\",\n \"benefits\",\n \"alternating\",\n \"two-column\",\n \"content-media\",\n ],\n category: \"about\",\n component: AlternatingBlocks,\n props: \"AlternatingBlocksProps\",\n exampleUsage: `\n<AlternatingBlocks\n sections={[\n {\n content: (\n <div>\n <div className=\"flex items-center gap-2 mb-3\">\n <Lightbulb className=\"h-4 w-4 text-primary\" />\n <span className=\"text-sm font-medium text-muted-foreground\">\n The Origin\n </span>\n </div>\n <h3 className=\"mb-3 text-2xl font-semibold tracking-tight\">\n It started with frustration\n </h3>\n <p className=\"text-muted-foreground leading-relaxed\">\n We spent years watching teams drown in tools that promised to help\n but only added complexity. In 2018, we decided to build something better.\n </p>\n </div>\n ),\n media: <img src=\"...\" alt=\"...\" />,\n mediaLeft: false\n },\n {\n content: <div>...</div>,\n media: <img src=\"...\" alt=\"...\" />,\n mediaLeft: true\n }\n ]}\n/>\n `.trim(),\n },\n // Add more blocks here following this pattern\n};\n\n/**\n * Get blocks by semantic tag\n */\nexport function getBlocksBySemanticTag(tag: string): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY).filter((block) =>\n block.semanticTags.includes(tag)\n );\n}\n\n/**\n * Get blocks by category\n */\nexport function getBlocksByCategory(\n category: BlockCategory\n): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY).filter(\n (block) => block.category === category\n );\n}\n\n/**\n * Get block by ID\n */\nexport function getBlockById(id: string): BlockRegistryEntry | undefined {\n return BLOCK_REGISTRY[id];\n}\n\n/**\n * Get all available blocks\n */\nexport function getAllBlocks(): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY);\n}\n\n/**\n * Get all categories\n */\nexport function getAllCategories(): BlockCategory[] {\n return Array.from(\n new Set(Object.values(BLOCK_REGISTRY).map((block) => block.category))\n );\n}\n\n/**\n * Search blocks by query (searches name, description, and semantic tags)\n */\nexport function searchBlocks(query: string): BlockRegistryEntry[] {\n const lowercaseQuery = query.toLowerCase();\n return Object.values(BLOCK_REGISTRY).filter(\n (block) =>\n block.name.toLowerCase().includes(lowercaseQuery) ||\n block.description.toLowerCase().includes(lowercaseQuery) ||\n block.semanticTags.some((tag) => tag.toLowerCase().includes(lowercaseQuery))\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/ui/container.tsx","../components/ui/section.tsx","../components/blocks/about/alternating-blocks.tsx","../icons/arrow-left.tsx","../icons/arrow-right.tsx","../components/ui/button.tsx","../components/ui/carousel.tsx","../components/blocks/features/feature-showcase.tsx","../src/registry/blocks.ts"],"names":["twMerge","clsx","React","jsx","jsxs","cva","Slot","React3","useEmblaCarousel","api","useState","useRef","useEffect"],"mappings":"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","file":"registry.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 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","import React from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Container } from \"./container\";\nimport type { SectionProps } from \"../../src/types\";\n\n/**\n * Background style variants\n * Uses standard Tailwind/shadcn CSS variables for theming\n */\nconst backgroundStyles = {\n white: \"bg-background text-foreground\",\n gray: \"bg-muted/30 text-foreground\",\n dark: \"bg-foreground text-background\",\n gradient: \"bg-gradient-to-br from-primary via-primary/90 to-foreground text-primary-foreground\",\n primary: \"bg-primary text-primary-foreground\",\n secondary: \"bg-secondary text-secondary-foreground\",\n muted: \"bg-muted text-muted-foreground\",\n};\n\n/**\n * Vertical spacing variants\n */\nconst spacingStyles = {\n sm: \"py-12 md:py-16\",\n md: \"py-16 md:py-24\",\n lg: \"py-20 md:py-32\",\n xl: \"py-24 md:py-40\",\n};\n\n/**\n * Section component for consistent page sections with optional title, subtitle, and background\n *\n * @example\n * ```tsx\n * <Section\n * title=\"Our Services\"\n * subtitle=\"What we offer\"\n * background=\"gray\"\n * spacing=\"lg\"\n * >\n * <div>Section content goes here</div>\n * </Section>\n * ```\n */\nexport const Section = React.forwardRef<HTMLElement, SectionProps>(\n (\n {\n id,\n title,\n subtitle,\n children,\n className,\n style,\n background = \"white\",\n spacing = \"lg\",\n ...props\n },\n ref\n ) => {\n return (\n <section\n ref={ref}\n id={id}\n className={cn(\n backgroundStyles[background],\n spacingStyles[spacing],\n className\n )}\n style={style}\n {...props}\n >\n <Container>\n {(title || subtitle) && (\n <div className=\"text-center mb-12 md:mb-16\">\n {subtitle && (\n <p className=\"text-sm font-semibold uppercase tracking-wider mb-2 text-primary\">\n {subtitle}\n </p>\n )}\n {title && (\n <h2 className=\"text-3xl md:text-4xl lg:text-5xl font-bold tracking-tight\">\n {title}\n </h2>\n )}\n </div>\n )}\n {children}\n </Container>\n </section>\n );\n }\n);\n\nSection.displayName = \"Section\";\n","import * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Section } from \"../../ui/section\";\nimport type { SectionBackground, SectionSpacing } from \"../../../src/types\";\n\nexport interface AlternatingBlockSection {\n content: React.ReactNode;\n media: React.ReactNode;\n mediaLeft?: boolean;\n}\n\nexport interface AlternatingBlocksProps {\n /**\n * Array of sections to display with alternating layout\n */\n sections: AlternatingBlockSection[];\n /**\n * Section title (optional)\n */\n title?: string;\n /**\n * Section subtitle/eyebrow (optional)\n */\n subtitle?: string;\n /**\n * Background style variant\n * @default \"white\"\n */\n background?: SectionBackground;\n /**\n * Vertical spacing variant\n * @default \"lg\"\n */\n spacing?: SectionSpacing;\n /**\n * Additional CSS classes for the Section wrapper\n */\n className?: string;\n /**\n * Additional CSS classes for the content container\n */\n contentClassName?: string;\n}\n\n/**\n * AlternatingBlocks component displays content sections with alternating media placement.\n * Uses the Section component for consistent spacing, backgrounds, and optional titles.\n *\n * @example\n * ```tsx\n * <AlternatingBlocks\n * title=\"Our Story\"\n * subtitle=\"About Us\"\n * background=\"gray\"\n * spacing=\"xl\"\n * sections={[\n * {\n * content: <div><h3>Title</h3><p>Description</p></div>,\n * media: <img src=\"...\" alt=\"...\" />,\n * mediaLeft: false\n * }\n * ]}\n * />\n * ```\n */\nexport function AlternatingBlocks({\n sections,\n title,\n subtitle,\n background = \"white\",\n spacing = \"lg\",\n className,\n contentClassName,\n}: AlternatingBlocksProps) {\n return (\n <Section\n title={title}\n subtitle={subtitle}\n background={background}\n spacing={spacing}\n className={className}\n >\n <div className={cn(\"mx-auto w-full max-w-[900px]\", contentClassName)}>\n <div className=\"space-y-12\">\n {sections?.map((section, index) => (\n <div\n key={index}\n className=\"grid items-center gap-8 md:grid-cols-2 md:gap-12\"\n >\n <div className={section.mediaLeft ? \"md:order-2\" : \"\"}>\n {section.content}\n </div>\n\n <div\n className={cn(\n \"aspect-4/3 overflow-hidden rounded-lg border\",\n section.mediaLeft ? \"md:order-1\" : \"\",\n )}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {section.media}\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n </Section>\n );\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","/**\n * Semantic Block Registry\n *\n * This registry maps semantic concepts to available UI blocks for AI-driven\n * site generation. Each block entry contains:\n * - id: Unique identifier for the block\n * - name: Human-readable name\n * - description: What the block does and when to use it\n * - semanticTags: Array of semantic concepts this block represents\n * - category: Block category (about, features, cta, testimonials, etc.)\n * - component: Reference to the actual component\n * - props: TypeScript type for the component's props\n * - exampleUsage: Code example showing how to use the block\n */\n\nimport { AlternatingBlocks } from \"../../components/blocks/about/alternating-blocks\";\nimport type { AlternatingBlocksProps } from \"../../components/blocks/about/alternating-blocks\";\nimport { FeatureShowcase } from \"../../components/blocks/features/feature-showcase\";\nimport type { FeatureShowcaseProps } from \"../../components/blocks/features/feature-showcase\";\n\nexport interface BlockRegistryEntry<T = any> {\n id: string;\n name: string;\n description: string;\n semanticTags: string[];\n category: BlockCategory;\n component: React.ComponentType<T>;\n props: string;\n exampleUsage: string;\n}\n\nexport type BlockCategory =\n | \"about\"\n | \"features\"\n | \"cta\"\n | \"testimonials\"\n | \"services\"\n | \"hero\"\n | \"footer\"\n | \"header\"\n | \"pricing\"\n | \"team\"\n | \"stats\"\n | \"faq\"\n | \"contact\"\n | \"gallery\"\n | \"timeline\"\n | \"process\"\n | \"benefits\"\n | \"comparison\";\n\n/**\n * Block Registry - Central registry of all available UI blocks\n */\nexport const BLOCK_REGISTRY: Record<string, BlockRegistryEntry> = {\n \"alternating-blocks\": {\n id: \"alternating-blocks\",\n name: \"Alternating Content Blocks\",\n description:\n \"Display content sections with alternating left/right media placement. Ideal for storytelling, feature showcases, or company history sections.\",\n semanticTags: [\n \"about\",\n \"story\",\n \"history\",\n \"timeline\",\n \"features\",\n \"benefits\",\n \"alternating\",\n \"two-column\",\n \"content-media\",\n ],\n category: \"about\",\n component: AlternatingBlocks,\n props: \"AlternatingBlocksProps\",\n exampleUsage: `\n<AlternatingBlocks\n sections={[\n {\n content: (\n <div>\n <div className=\"flex items-center gap-2 mb-3\">\n <Lightbulb className=\"h-4 w-4 text-primary\" />\n <span className=\"text-sm font-medium text-muted-foreground\">\n The Origin\n </span>\n </div>\n <h3 className=\"mb-3 text-2xl font-semibold tracking-tight\">\n It started with frustration\n </h3>\n <p className=\"text-muted-foreground leading-relaxed\">\n We spent years watching teams drown in tools that promised to help\n but only added complexity. In 2018, we decided to build something better.\n </p>\n </div>\n ),\n media: <img src=\"...\" alt=\"...\" />,\n mediaLeft: false\n },\n {\n content: <div>...</div>,\n media: <img src=\"...\" alt=\"...\" />,\n mediaLeft: true\n }\n ]}\n/>\n `.trim(),\n },\n \"feature-showcase\": {\n id: \"feature-showcase\",\n name: \"Feature Showcase Carousel\",\n description:\n \"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.\",\n semanticTags: [\n \"features\",\n \"carousel\",\n \"showcase\",\n \"slider\",\n \"highlights\",\n \"product-features\",\n \"capabilities\",\n \"interactive\",\n \"media-gallery\",\n ],\n category: \"features\",\n component: FeatureShowcase,\n props: \"FeatureShowcaseProps\",\n exampleUsage: `\n<FeatureShowcase\n items={[\n {\n content: (\n <div>\n <span className=\"text-sm font-medium text-primary mb-2 block\">\n DESIGNED TO HELP YOU GROW\n </span>\n <h3 className=\"mb-4 text-3xl font-bold tracking-tight\">\n Powerful Analytics\n </h3>\n <p className=\"text-muted-foreground leading-relaxed\">\n Track every metric that matters with real-time dashboards\n and comprehensive reporting tools.\n </p>\n </div>\n ),\n mediaComponent: <img src=\"...\" alt=\"Analytics Dashboard\" className=\"rounded-lg\" />\n },\n {\n content: (\n <div>\n <span className=\"text-sm font-medium text-primary mb-2 block\">\n SEAMLESS INTEGRATION\n </span>\n <h3 className=\"mb-4 text-3xl font-bold tracking-tight\">\n Connect Anywhere\n </h3>\n <p className=\"text-muted-foreground leading-relaxed\">\n Integrate with your favorite tools and platforms in seconds.\n </p>\n </div>\n ),\n mediaComponent: <img src=\"...\" alt=\"Integrations\" className=\"rounded-lg\" />\n }\n ]}\n/>\n `.trim(),\n },\n // Add more blocks here following this pattern\n};\n\n/**\n * Get blocks by semantic tag\n */\nexport function getBlocksBySemanticTag(tag: string): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY).filter((block) =>\n block.semanticTags.includes(tag)\n );\n}\n\n/**\n * Get blocks by category\n */\nexport function getBlocksByCategory(\n category: BlockCategory\n): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY).filter(\n (block) => block.category === category\n );\n}\n\n/**\n * Get block by ID\n */\nexport function getBlockById(id: string): BlockRegistryEntry | undefined {\n return BLOCK_REGISTRY[id];\n}\n\n/**\n * Get all available blocks\n */\nexport function getAllBlocks(): BlockRegistryEntry[] {\n return Object.values(BLOCK_REGISTRY);\n}\n\n/**\n * Get all categories\n */\nexport function getAllCategories(): BlockCategory[] {\n return Array.from(\n new Set(Object.values(BLOCK_REGISTRY).map((block) => block.category))\n );\n}\n\n/**\n * Search blocks by query (searches name, description, and semantic tags)\n */\nexport function searchBlocks(query: string): BlockRegistryEntry[] {\n const lowercaseQuery = query.toLowerCase();\n return Object.values(BLOCK_REGISTRY).filter(\n (block) =>\n block.name.toLowerCase().includes(lowercaseQuery) ||\n block.description.toLowerCase().includes(lowercaseQuery) ||\n block.semanticTags.some((tag) => tag.toLowerCase().includes(lowercaseQuery))\n );\n}\n"]}
|
package/dist/registry.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import
|
|
3
|
+
import * as React3 from 'react';
|
|
4
|
+
import React3__default, { useState, useRef, useEffect } from 'react';
|
|
4
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
import useEmblaCarousel from 'embla-carousel-react';
|
|
7
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
8
|
+
import { cva } from 'class-variance-authority';
|
|
5
9
|
|
|
6
10
|
// lib/utils.ts
|
|
7
11
|
function cn(...inputs) {
|
|
@@ -16,7 +20,7 @@ var maxWidthStyles = {
|
|
|
16
20
|
"4xl": "max-w-[1536px]",
|
|
17
21
|
full: "max-w-full"
|
|
18
22
|
};
|
|
19
|
-
var Container =
|
|
23
|
+
var Container = React3__default.forwardRef(
|
|
20
24
|
({ children, maxWidth = "xl", className, as = "div", ...props }, ref) => {
|
|
21
25
|
const Component = as;
|
|
22
26
|
return /* @__PURE__ */ jsx(
|
|
@@ -50,7 +54,7 @@ var spacingStyles = {
|
|
|
50
54
|
lg: "py-20 md:py-32",
|
|
51
55
|
xl: "py-24 md:py-40"
|
|
52
56
|
};
|
|
53
|
-
var Section =
|
|
57
|
+
var Section = React3__default.forwardRef(
|
|
54
58
|
({
|
|
55
59
|
id,
|
|
56
60
|
title,
|
|
@@ -126,6 +130,383 @@ function AlternatingBlocks({
|
|
|
126
130
|
}
|
|
127
131
|
);
|
|
128
132
|
}
|
|
133
|
+
var ArrowLeft = ({
|
|
134
|
+
size = 24,
|
|
135
|
+
className,
|
|
136
|
+
strokeWidth = 2,
|
|
137
|
+
...props
|
|
138
|
+
}) => {
|
|
139
|
+
return /* @__PURE__ */ jsx(
|
|
140
|
+
"svg",
|
|
141
|
+
{
|
|
142
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
143
|
+
width: size,
|
|
144
|
+
height: size,
|
|
145
|
+
viewBox: "0 0 24 24",
|
|
146
|
+
fill: "none",
|
|
147
|
+
stroke: "currentColor",
|
|
148
|
+
strokeWidth,
|
|
149
|
+
strokeLinecap: "round",
|
|
150
|
+
strokeLinejoin: "round",
|
|
151
|
+
className,
|
|
152
|
+
...props,
|
|
153
|
+
children: /* @__PURE__ */ jsx("path", { d: "m12 19l-7-7l7-7m7 7H5" })
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
var ArrowRight = ({
|
|
158
|
+
size = 24,
|
|
159
|
+
className,
|
|
160
|
+
strokeWidth = 2,
|
|
161
|
+
...props
|
|
162
|
+
}) => {
|
|
163
|
+
return /* @__PURE__ */ 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__ */ jsx("path", { d: "M5 12h14m-7-7l7 7l-7 7" })
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
var buttonVariants = cva(
|
|
182
|
+
"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",
|
|
183
|
+
{
|
|
184
|
+
variants: {
|
|
185
|
+
variant: {
|
|
186
|
+
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))]",
|
|
187
|
+
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",
|
|
188
|
+
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",
|
|
189
|
+
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))]",
|
|
190
|
+
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",
|
|
191
|
+
link: "text-[var(--button-link-fg,hsl(var(--primary)))] underline-offset-4 hover:underline"
|
|
192
|
+
},
|
|
193
|
+
size: {
|
|
194
|
+
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)]",
|
|
195
|
+
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)]",
|
|
196
|
+
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)]",
|
|
197
|
+
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)]",
|
|
198
|
+
icon: "size-[var(--button-height-md,2.25rem)]",
|
|
199
|
+
"icon-sm": "size-[var(--button-height-sm,2rem)]",
|
|
200
|
+
"icon-lg": "size-[var(--button-height-lg,2.5rem)]"
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
defaultVariants: {
|
|
204
|
+
variant: "default",
|
|
205
|
+
size: "default"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
function Button({
|
|
210
|
+
className,
|
|
211
|
+
variant = "default",
|
|
212
|
+
size = "default",
|
|
213
|
+
asChild = false,
|
|
214
|
+
...props
|
|
215
|
+
}) {
|
|
216
|
+
const Comp = asChild ? Slot : "button";
|
|
217
|
+
return /* @__PURE__ */ jsx(
|
|
218
|
+
Comp,
|
|
219
|
+
{
|
|
220
|
+
"data-slot": "button",
|
|
221
|
+
"data-variant": variant,
|
|
222
|
+
"data-size": size,
|
|
223
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
224
|
+
...props
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
var CarouselContext = React3.createContext(null);
|
|
229
|
+
function useCarousel() {
|
|
230
|
+
const context = React3.useContext(CarouselContext);
|
|
231
|
+
if (!context) {
|
|
232
|
+
throw new Error("useCarousel must be used within a <Carousel />");
|
|
233
|
+
}
|
|
234
|
+
return context;
|
|
235
|
+
}
|
|
236
|
+
function Carousel({
|
|
237
|
+
orientation = "horizontal",
|
|
238
|
+
opts,
|
|
239
|
+
setApi,
|
|
240
|
+
plugins,
|
|
241
|
+
className,
|
|
242
|
+
children,
|
|
243
|
+
...props
|
|
244
|
+
}) {
|
|
245
|
+
const [carouselRef, api] = useEmblaCarousel(
|
|
246
|
+
{
|
|
247
|
+
...opts,
|
|
248
|
+
axis: orientation === "horizontal" ? "x" : "y"
|
|
249
|
+
},
|
|
250
|
+
plugins
|
|
251
|
+
);
|
|
252
|
+
const [canScrollPrev, setCanScrollPrev] = React3.useState(false);
|
|
253
|
+
const [canScrollNext, setCanScrollNext] = React3.useState(false);
|
|
254
|
+
const onSelect = React3.useCallback((api2) => {
|
|
255
|
+
if (!api2) return;
|
|
256
|
+
setCanScrollPrev(api2.canScrollPrev());
|
|
257
|
+
setCanScrollNext(api2.canScrollNext());
|
|
258
|
+
}, []);
|
|
259
|
+
const scrollPrev = React3.useCallback(() => {
|
|
260
|
+
api?.scrollPrev();
|
|
261
|
+
}, [api]);
|
|
262
|
+
const scrollNext = React3.useCallback(() => {
|
|
263
|
+
api?.scrollNext();
|
|
264
|
+
}, [api]);
|
|
265
|
+
const handleKeyDown = React3.useCallback(
|
|
266
|
+
(event) => {
|
|
267
|
+
if (event.key === "ArrowLeft") {
|
|
268
|
+
event.preventDefault();
|
|
269
|
+
scrollPrev();
|
|
270
|
+
} else if (event.key === "ArrowRight") {
|
|
271
|
+
event.preventDefault();
|
|
272
|
+
scrollNext();
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
[scrollPrev, scrollNext]
|
|
276
|
+
);
|
|
277
|
+
React3.useEffect(() => {
|
|
278
|
+
if (!api || !setApi) return;
|
|
279
|
+
setApi(api);
|
|
280
|
+
}, [api, setApi]);
|
|
281
|
+
React3.useEffect(() => {
|
|
282
|
+
if (!api) return;
|
|
283
|
+
onSelect(api);
|
|
284
|
+
api.on("reInit", onSelect);
|
|
285
|
+
api.on("select", onSelect);
|
|
286
|
+
return () => {
|
|
287
|
+
api?.off("select", onSelect);
|
|
288
|
+
};
|
|
289
|
+
}, [api, onSelect]);
|
|
290
|
+
return /* @__PURE__ */ jsx(
|
|
291
|
+
CarouselContext.Provider,
|
|
292
|
+
{
|
|
293
|
+
value: {
|
|
294
|
+
carouselRef,
|
|
295
|
+
api,
|
|
296
|
+
opts,
|
|
297
|
+
orientation: orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
|
298
|
+
scrollPrev,
|
|
299
|
+
scrollNext,
|
|
300
|
+
canScrollPrev,
|
|
301
|
+
canScrollNext
|
|
302
|
+
},
|
|
303
|
+
children: /* @__PURE__ */ jsx(
|
|
304
|
+
"div",
|
|
305
|
+
{
|
|
306
|
+
onKeyDownCapture: handleKeyDown,
|
|
307
|
+
className: cn("relative", className),
|
|
308
|
+
role: "region",
|
|
309
|
+
"aria-roledescription": "carousel",
|
|
310
|
+
"data-slot": "carousel",
|
|
311
|
+
...props,
|
|
312
|
+
children
|
|
313
|
+
}
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
function CarouselContent({ className, ...props }) {
|
|
319
|
+
const { carouselRef, orientation } = useCarousel();
|
|
320
|
+
return /* @__PURE__ */ jsx(
|
|
321
|
+
"div",
|
|
322
|
+
{
|
|
323
|
+
ref: carouselRef,
|
|
324
|
+
className: "overflow-hidden",
|
|
325
|
+
"data-slot": "carousel-content",
|
|
326
|
+
children: /* @__PURE__ */ jsx(
|
|
327
|
+
"div",
|
|
328
|
+
{
|
|
329
|
+
className: cn(
|
|
330
|
+
"flex",
|
|
331
|
+
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
|
332
|
+
className
|
|
333
|
+
),
|
|
334
|
+
...props
|
|
335
|
+
}
|
|
336
|
+
)
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
function CarouselItem({ className, ...props }) {
|
|
341
|
+
const { orientation } = useCarousel();
|
|
342
|
+
return /* @__PURE__ */ jsx(
|
|
343
|
+
"div",
|
|
344
|
+
{
|
|
345
|
+
role: "group",
|
|
346
|
+
"aria-roledescription": "slide",
|
|
347
|
+
"data-slot": "carousel-item",
|
|
348
|
+
className: cn(
|
|
349
|
+
"min-w-0 shrink-0 grow-0 basis-full",
|
|
350
|
+
orientation === "horizontal" ? "pl-4" : "pt-4",
|
|
351
|
+
className
|
|
352
|
+
),
|
|
353
|
+
...props
|
|
354
|
+
}
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
function CarouselPrevious({
|
|
358
|
+
className,
|
|
359
|
+
variant = "outline",
|
|
360
|
+
size = "icon",
|
|
361
|
+
...props
|
|
362
|
+
}) {
|
|
363
|
+
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
364
|
+
return /* @__PURE__ */ jsxs(
|
|
365
|
+
Button,
|
|
366
|
+
{
|
|
367
|
+
"data-slot": "carousel-previous",
|
|
368
|
+
variant,
|
|
369
|
+
size,
|
|
370
|
+
className: cn(
|
|
371
|
+
"absolute size-8 rounded-full",
|
|
372
|
+
orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
373
|
+
className
|
|
374
|
+
),
|
|
375
|
+
disabled: !canScrollPrev,
|
|
376
|
+
onClick: scrollPrev,
|
|
377
|
+
...props,
|
|
378
|
+
children: [
|
|
379
|
+
/* @__PURE__ */ jsx(ArrowLeft, {}),
|
|
380
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Previous slide" })
|
|
381
|
+
]
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
function CarouselNext({
|
|
386
|
+
className,
|
|
387
|
+
variant = "outline",
|
|
388
|
+
size = "icon",
|
|
389
|
+
...props
|
|
390
|
+
}) {
|
|
391
|
+
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
392
|
+
return /* @__PURE__ */ jsxs(
|
|
393
|
+
Button,
|
|
394
|
+
{
|
|
395
|
+
"data-slot": "carousel-next",
|
|
396
|
+
variant,
|
|
397
|
+
size,
|
|
398
|
+
className: cn(
|
|
399
|
+
"absolute size-8 rounded-full",
|
|
400
|
+
orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
401
|
+
className
|
|
402
|
+
),
|
|
403
|
+
disabled: !canScrollNext,
|
|
404
|
+
onClick: scrollNext,
|
|
405
|
+
...props,
|
|
406
|
+
children: [
|
|
407
|
+
/* @__PURE__ */ jsx(ArrowRight, {}),
|
|
408
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Next slide" })
|
|
409
|
+
]
|
|
410
|
+
}
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
function FeatureShowcase({
|
|
414
|
+
items,
|
|
415
|
+
children,
|
|
416
|
+
className,
|
|
417
|
+
carouselClassName,
|
|
418
|
+
slideClassName,
|
|
419
|
+
contentClassName,
|
|
420
|
+
mediaClassName,
|
|
421
|
+
arrowClassName,
|
|
422
|
+
equalizeOnMobile = true,
|
|
423
|
+
stretchMediaOnMobile = true
|
|
424
|
+
}) {
|
|
425
|
+
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";
|
|
426
|
+
const [mobileSlideHeight, setMobileSlideHeight] = useState(
|
|
427
|
+
null
|
|
428
|
+
);
|
|
429
|
+
const slideRefs = useRef([]);
|
|
430
|
+
const mediaWrapperClassName = equalizeOnMobile && stretchMediaOnMobile ? "flex-1 min-h-0 md:flex-none" : "";
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
if (!equalizeOnMobile) {
|
|
433
|
+
setMobileSlideHeight(null);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const updateHeights = () => {
|
|
437
|
+
if (typeof window === "undefined") return;
|
|
438
|
+
const isMobile = window.innerWidth < 768;
|
|
439
|
+
if (!isMobile) {
|
|
440
|
+
setMobileSlideHeight(null);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const heights = slideRefs.current.slice(0, items.length).map((node) => node?.offsetHeight ?? 0);
|
|
444
|
+
const maxHeight = Math.max(...heights, 0);
|
|
445
|
+
if (maxHeight > 0) {
|
|
446
|
+
setMobileSlideHeight(
|
|
447
|
+
(prev) => prev === maxHeight ? prev : maxHeight
|
|
448
|
+
);
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
updateHeights();
|
|
452
|
+
window.addEventListener("resize", updateHeights);
|
|
453
|
+
let resizeObserver = null;
|
|
454
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
455
|
+
resizeObserver = new ResizeObserver(updateHeights);
|
|
456
|
+
slideRefs.current.slice(0, items.length).forEach((node) => {
|
|
457
|
+
if (node) resizeObserver?.observe(node);
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
return () => {
|
|
461
|
+
window.removeEventListener("resize", updateHeights);
|
|
462
|
+
resizeObserver?.disconnect();
|
|
463
|
+
};
|
|
464
|
+
}, [equalizeOnMobile, items.length]);
|
|
465
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
466
|
+
children,
|
|
467
|
+
/* @__PURE__ */ jsxs(Carousel, { className: carouselClassName, children: [
|
|
468
|
+
/* @__PURE__ */ jsx("div", { className: "pb-18 md:pb-24", children: /* @__PURE__ */ jsx(CarouselContent, { className: "ease-in", children: items.map((item, itemIndex) => /* @__PURE__ */ jsx(CarouselItem, { children: /* @__PURE__ */ jsxs(
|
|
469
|
+
"div",
|
|
470
|
+
{
|
|
471
|
+
ref: (node) => {
|
|
472
|
+
slideRefs.current[itemIndex] = node;
|
|
473
|
+
},
|
|
474
|
+
style: equalizeOnMobile && mobileSlideHeight ? { minHeight: mobileSlideHeight } : void 0,
|
|
475
|
+
className: cn(
|
|
476
|
+
"flex flex-col gap-8 md:gap-14 md:flex-row md:items-center md:justify-between",
|
|
477
|
+
slideClassName
|
|
478
|
+
),
|
|
479
|
+
children: [
|
|
480
|
+
/* @__PURE__ */ jsx("div", { className: cn("w-full", contentClassName), children: item.content }),
|
|
481
|
+
/* @__PURE__ */ jsx(
|
|
482
|
+
"div",
|
|
483
|
+
{
|
|
484
|
+
className: cn(
|
|
485
|
+
"w-full",
|
|
486
|
+
mediaWrapperClassName,
|
|
487
|
+
mediaClassName
|
|
488
|
+
),
|
|
489
|
+
children: item.mediaComponent
|
|
490
|
+
}
|
|
491
|
+
)
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
) }, `slide-${itemIndex}`)) }) }),
|
|
495
|
+
/* @__PURE__ */ jsx(
|
|
496
|
+
CarouselPrevious,
|
|
497
|
+
{
|
|
498
|
+
className: cn(baseArrowClassName, "left-4 md:left-6", arrowClassName)
|
|
499
|
+
}
|
|
500
|
+
),
|
|
501
|
+
/* @__PURE__ */ jsx(
|
|
502
|
+
CarouselNext,
|
|
503
|
+
{
|
|
504
|
+
className: cn(baseArrowClassName, "right-4 md:right-6", arrowClassName)
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
] })
|
|
508
|
+
] });
|
|
509
|
+
}
|
|
129
510
|
|
|
130
511
|
// src/registry/blocks.ts
|
|
131
512
|
var BLOCK_REGISTRY = {
|
|
@@ -177,6 +558,64 @@ var BLOCK_REGISTRY = {
|
|
|
177
558
|
mediaLeft: true
|
|
178
559
|
}
|
|
179
560
|
]}
|
|
561
|
+
/>
|
|
562
|
+
`.trim()
|
|
563
|
+
},
|
|
564
|
+
"feature-showcase": {
|
|
565
|
+
id: "feature-showcase",
|
|
566
|
+
name: "Feature Showcase Carousel",
|
|
567
|
+
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.",
|
|
568
|
+
semanticTags: [
|
|
569
|
+
"features",
|
|
570
|
+
"carousel",
|
|
571
|
+
"showcase",
|
|
572
|
+
"slider",
|
|
573
|
+
"highlights",
|
|
574
|
+
"product-features",
|
|
575
|
+
"capabilities",
|
|
576
|
+
"interactive",
|
|
577
|
+
"media-gallery"
|
|
578
|
+
],
|
|
579
|
+
category: "features",
|
|
580
|
+
component: FeatureShowcase,
|
|
581
|
+
props: "FeatureShowcaseProps",
|
|
582
|
+
exampleUsage: `
|
|
583
|
+
<FeatureShowcase
|
|
584
|
+
items={[
|
|
585
|
+
{
|
|
586
|
+
content: (
|
|
587
|
+
<div>
|
|
588
|
+
<span className="text-sm font-medium text-primary mb-2 block">
|
|
589
|
+
DESIGNED TO HELP YOU GROW
|
|
590
|
+
</span>
|
|
591
|
+
<h3 className="mb-4 text-3xl font-bold tracking-tight">
|
|
592
|
+
Powerful Analytics
|
|
593
|
+
</h3>
|
|
594
|
+
<p className="text-muted-foreground leading-relaxed">
|
|
595
|
+
Track every metric that matters with real-time dashboards
|
|
596
|
+
and comprehensive reporting tools.
|
|
597
|
+
</p>
|
|
598
|
+
</div>
|
|
599
|
+
),
|
|
600
|
+
mediaComponent: <img src="..." alt="Analytics Dashboard" className="rounded-lg" />
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
content: (
|
|
604
|
+
<div>
|
|
605
|
+
<span className="text-sm font-medium text-primary mb-2 block">
|
|
606
|
+
SEAMLESS INTEGRATION
|
|
607
|
+
</span>
|
|
608
|
+
<h3 className="mb-4 text-3xl font-bold tracking-tight">
|
|
609
|
+
Connect Anywhere
|
|
610
|
+
</h3>
|
|
611
|
+
<p className="text-muted-foreground leading-relaxed">
|
|
612
|
+
Integrate with your favorite tools and platforms in seconds.
|
|
613
|
+
</p>
|
|
614
|
+
</div>
|
|
615
|
+
),
|
|
616
|
+
mediaComponent: <img src="..." alt="Integrations" className="rounded-lg" />
|
|
617
|
+
}
|
|
618
|
+
]}
|
|
180
619
|
/>
|
|
181
620
|
`.trim()
|
|
182
621
|
}
|