{ "name": "animated-image-grid", "type": "registry:ui", "registryDependencies": [], "dependencies": [], "devDependencies": [], "tailwind": {}, "cssVars": { "light": {}, "dark": {} }, "files": [ { "path": "animated-image-grid.tsx", "content": "import * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport './animated-image-grid.css';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst itemVariants = cva(\n 'animated-image-grid-item overflow-hidden transition-all duration-300',\n {\n variants: {\n variant: {\n default: 'rounded-lg border-2 border-primary/20 shadow-sm',\n circle: 'rounded-full border-4 border-white shadow-md',\n polaroid: 'rounded-sm bg-white p-2 pb-8 shadow-lg',\n minimal: 'rounded-md shadow-none border-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nexport interface AnimatedImageGridItem {\n id: string | number;\n src: string;\n alt?: string;\n}\n\nexport interface AnimatedImageGridProps\n extends\n React.HTMLAttributes,\n VariantProps {\n items: AnimatedImageGridItem[];\n gap?: string;\n size?: string;\n itemClassName?: string;\n imageClassName?: string;\n}\n\nexport const AnimatedImageGrid = React.forwardRef<\n HTMLDivElement,\n AnimatedImageGridProps\n>(\n (\n {\n className,\n items,\n gap,\n size,\n variant,\n itemClassName,\n imageClassName,\n style,\n ...props\n },\n ref\n ) => {\n // Inject the customizable gap and size variables if provided\n const customStyle = {\n ...(gap ? { '--grid-gap': gap } : {}),\n ...(size ? { '--grid-size': size } : {}),\n ...style,\n } as React.CSSProperties;\n\n return (\n \n {items.map((item, index) => (\n \n {/* eslint-disable-next-line @next/next/no-img-element */}\n \n \n ))}\n {/* Hidden filler element required to stretch the container height hack */}\n \n \n );\n }\n);\nAnimatedImageGrid.displayName = 'AnimatedImageGrid';\n", "type": "registry:ui" }, { "path": "animated-image-grid.tsx", "content": "import * as React from 'react';\nimport { cn } from '@/lib/utils';\nimport './animated-image-grid.css';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nconst itemVariants = cva(\n 'animated-image-grid-item overflow-hidden transition-all duration-300',\n {\n variants: {\n variant: {\n default: 'rounded-lg border-2 border-primary/20 shadow-sm',\n circle: 'rounded-full border-4 border-white shadow-md',\n polaroid: 'rounded-sm bg-white p-2 pb-8 shadow-lg',\n minimal: 'rounded-md shadow-none border-none',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nexport interface AnimatedImageGridItem {\n id: string | number;\n src: string;\n alt?: string;\n}\n\nexport interface AnimatedImageGridProps\n extends\n React.HTMLAttributes,\n VariantProps {\n items: AnimatedImageGridItem[];\n gap?: string;\n size?: string;\n itemClassName?: string;\n imageClassName?: string;\n}\n\nexport const AnimatedImageGrid = React.forwardRef<\n HTMLDivElement,\n AnimatedImageGridProps\n>(\n (\n {\n className,\n items,\n gap,\n size,\n variant,\n itemClassName,\n imageClassName,\n style,\n ...props\n },\n ref\n ) => {\n // Inject the customizable gap and size variables if provided\n const customStyle = {\n ...(gap ? { '--grid-gap': gap } : {}),\n ...(size ? { '--grid-size': size } : {}),\n ...style,\n } as React.CSSProperties;\n\n return (\n \n {items.map((item, index) => (\n \n {/* eslint-disable-next-line @next/next/no-img-element */}\n \n \n ))}\n {/* Hidden filler element required to stretch the container height hack */}\n \n \n );\n }\n);\nAnimatedImageGrid.displayName = 'AnimatedImageGrid';\n", "type": "registry:ui" }, { "path": "animated-image-grid.css", "content": "@reference \"../../app/globals.css\";\n\n.animated-image-grid {\n --animated-grid-gap: var(--grid-gap, 10px);\n --animated-grid-size: var(--grid-size, 130px);\n\n display: grid;\n grid-template-columns: repeat(auto-fill, var(--animated-grid-size));\n grid-auto-rows: var(--animated-grid-size);\n gap: var(--animated-grid-gap);\n justify-content: center;\n container-type: inline-size;\n}\n\n.animated-image-grid-item {\n grid-area: 1 / 1;\n width: var(--animated-grid-size);\n aspect-ratio: 1;\n box-sizing: border-box;\n\n /* Dynamically calculate the number of columns using the container's width */\n --n: round(\n down,\n (100cqw + var(--animated-grid-gap)) /\n (var(--animated-grid-size) + var(--animated-grid-gap))\n );\n\n /* Calculate row and column indices based on the injected --index custom property */\n --i: round(down, var(--index) / var(--n));\n --j: mod(var(--index), var(--n));\n\n /* Translate the item into its calculated position */\n translate: calc(var(--j) * (100% + var(--animated-grid-gap)))\n calc(var(--i) * (100% + var(--animated-grid-gap)));\n\n transition:\n 0.4s,\n scale 0.3s 0.4s,\n opacity 0.3s 0.3s,\n rotate 0.3s 0.3s;\n\n @starting-style {\n scale: 0;\n opacity: 0;\n rotate: -1turn;\n }\n}\n\n/* A hack to fix the grid container size, since all items are stacked at 1/1 */\n.animated-image-grid-filler {\n translate: 0;\n visibility: hidden;\n grid-row: calc(var(--i) + min(var(--j), 1));\n}\n", "type": "registry:ui" } ] }