2025-08-20 04:12:49 -06:00

13140 lines
1.3 MiB

/* eslint-disable @typescript-eslint/ban-ts-comment */
/* eslint-disable @typescript-eslint/no-explicit-any */
// @ts-nocheck
// This file is autogenerated by scripts/build-registry.mts
// Do not edit this file directly.
import * as React from 'react';
export const index: Record<string, any> = {
index: {
name: 'index',
description: '',
type: 'registry:style',
dependencies: [
'tw-animate-css',
'class-variance-authority',
'lucide-react',
],
devDependencies: undefined,
registryDependencies: ['utils'],
files: [],
keywords: [],
component: null,
command: 'https://animate-ui.com/r/index',
},
'bubble-background': {
name: 'bubble-background',
description:
'An interactive background featuring smoothly animated gradient bubbles, creating a playful, dynamic, and visually engaging backdrop.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/bubble/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/bubble.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport {\n motion,\n type SpringOptions,\n useMotionValue,\n useSpring,\n} from \'motion/react\';\n\nimport { cn } from \'@/lib/utils\';\n\ntype BubbleBackgroundProps = React.ComponentProps<\'div\'> & {\n interactive?: boolean;\n transition?: SpringOptions;\n colors?: {\n first: string;\n second: string;\n third: string;\n fourth: string;\n fifth: string;\n sixth: string;\n };\n};\n\nfunction BubbleBackground({\n ref,\n className,\n children,\n interactive = false,\n transition = { stiffness: 100, damping: 20 },\n colors = {\n first: \'18,113,255\',\n second: \'221,74,255\',\n third: \'0,220,255\',\n fourth: \'200,50,50\',\n fifth: \'180,180,50\',\n sixth: \'140,100,255\',\n },\n ...props\n}: BubbleBackgroundProps) {\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n const mouseX = useMotionValue(0);\n const mouseY = useMotionValue(0);\n const springX = useSpring(mouseX, transition);\n const springY = useSpring(mouseY, transition);\n\n React.useEffect(() => {\n if (!interactive) return;\n\n const currentContainer = containerRef.current;\n if (!currentContainer) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n const rect = currentContainer.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n mouseX.set(e.clientX - centerX);\n mouseY.set(e.clientY - centerY);\n };\n\n currentContainer?.addEventListener(\'mousemove\', handleMouseMove);\n return () =>\n currentContainer?.removeEventListener(\'mousemove\', handleMouseMove);\n }, [interactive, mouseX, mouseY]);\n\n return (\n <div\n ref={containerRef}\n data-slot="bubble-background"\n className={cn(\n \'relative size-full overflow-hidden bg-gradient-to-br from-violet-900 to-blue-900\',\n className,\n )}\n {...props}\n >\n <style>\n {`\n :root {\n --first-color: ${colors.first};\n --second-color: ${colors.second};\n --third-color: ${colors.third};\n --fourth-color: ${colors.fourth};\n --fifth-color: ${colors.fifth};\n --sixth-color: ${colors.sixth};\n }\n `}\n </style>\n\n <svg\n xmlns="http://www.w3.org/2000/svg"\n className="absolute top-0 left-0 w-0 h-0"\n >\n <defs>\n <filter id="goo">\n <feGaussianBlur\n in="SourceGraphic"\n stdDeviation="10"\n result="blur"\n />\n <feColorMatrix\n in="blur"\n mode="matrix"\n values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -8"\n result="goo"\n />\n <feBlend in="SourceGraphic" in2="goo" />\n </filter>\n </defs>\n </svg>\n\n <div\n className="absolute inset-0"\n style={{ filter: \'url(#goo) blur(40px)\' }}\n >\n <motion.div\n className="absolute rounded-full size-[80%] top-[10%] left-[10%] mix-blend-hard-light bg-[radial-gradient(circle_at_center,rgba(var(--first-color),0.8)_0%,rgba(var(--first-color),0)_50%)]"\n animate={{ y: [-50, 50, -50] }}\n transition={{ duration: 30, ease: \'easeInOut\', repeat: Infinity }}\n />\n\n <motion.div\n className="absolute inset-0 flex justify-center items-center origin-[calc(50%-400px)]"\n animate={{ rotate: 360 }}\n transition={{\n duration: 20,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n }}\n >\n <div className="rounded-full size-[80%] top-[10%] left-[10%] mix-blend-hard-light bg-[radial-gradient(circle_at_center,rgba(var(--second-color),0.8)_0%,rgba(var(--second-color),0)_50%)]" />\n </motion.div>\n\n <motion.div\n className="absolute inset-0 flex justify-center items-center origin-[calc(50%+400px)]"\n animate={{ rotate: 360 }}\n transition={{ duration: 40, ease: \'linear\', repeat: Infinity }}\n >\n <div className="absolute rounded-full size-[80%] bg-[radial-gradient(circle_at_center,rgba(var(--third-color),0.8)_0%,rgba(var(--third-color),0)_50%)] mix-blend-hard-light top-[calc(50%+200px)] left-[calc(50%-500px)]" />\n </motion.div>\n\n <motion.div\n className="absolute rounded-full size-[80%] top-[10%] left-[10%] mix-blend-hard-light bg-[radial-gradient(circle_at_center,rgba(var(--fourth-color),0.8)_0%,rgba(var(--fourth-color),0)_50%)] opacity-70"\n animate={{ x: [-50, 50, -50] }}\n transition={{ duration: 40, ease: \'easeInOut\', repeat: Infinity }}\n />\n\n <motion.div\n className="absolute inset-0 flex justify-center items-center origin-[calc(50%_-_800px)_calc(50%_+_200px)]"\n animate={{ rotate: 360 }}\n transition={{ duration: 20, ease: \'linear\', repeat: Infinity }}\n >\n <div className="absolute rounded-full size-[160%] mix-blend-hard-light bg-[radial-gradient(circle_at_center,rgba(var(--fifth-color),0.8)_0%,rgba(var(--fifth-color),0)_50%)] top-[calc(50%-80%)] left-[calc(50%-80%)]" />\n </motion.div>\n\n {interactive && (\n <motion.div\n className="absolute rounded-full size-full mix-blend-hard-light bg-[radial-gradient(circle_at_center,rgba(var(--sixth-color),0.8)_0%,rgba(var(--sixth-color),0)_50%)] opacity-70"\n style={{\n x: springX,\n y: springY,\n }}\n />\n )}\n </div>\n\n {children}\n </div>\n );\n}\n\nexport { BubbleBackground, type BubbleBackgroundProps };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/bubble/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bubble-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bubble-background',
},
'fireworks-background': {
name: 'fireworks-background',
description: 'A background component that displays a fireworks animation.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/fireworks/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/fireworks.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\nconst rand = (min: number, max: number): number =>\n Math.random() * (max - min) + min;\n\nconst randInt = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min) + min);\n\nconst randColor = (): string => `hsl(${randInt(0, 360)}, 100%, 50%)`;\n\ntype ParticleType = {\n x: number;\n y: number;\n color: string;\n speed: number;\n direction: number;\n vx: number;\n vy: number;\n gravity: number;\n friction: number;\n alpha: number;\n decay: number;\n size: number;\n update: () => void;\n draw: (ctx: CanvasRenderingContext2D) => void;\n isAlive: () => boolean;\n};\n\nfunction createParticle(\n x: number,\n y: number,\n color: string,\n speed: number,\n direction: number,\n gravity: number,\n friction: number,\n size: number,\n): ParticleType {\n const vx = Math.cos(direction) * speed;\n const vy = Math.sin(direction) * speed;\n const alpha = 1;\n const decay = rand(0.005, 0.02);\n\n return {\n x,\n y,\n color,\n speed,\n direction,\n vx,\n vy,\n gravity,\n friction,\n alpha,\n decay,\n size,\n update() {\n this.vx *= this.friction;\n this.vy *= this.friction;\n this.vy += this.gravity;\n this.x += this.vx;\n this.y += this.vy;\n this.alpha -= this.decay;\n },\n draw(ctx: CanvasRenderingContext2D) {\n ctx.save();\n ctx.globalAlpha = this.alpha;\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n ctx.fillStyle = this.color;\n ctx.fill();\n ctx.restore();\n },\n isAlive() {\n return this.alpha > 0;\n },\n };\n}\n\ntype FireworkType = {\n x: number;\n y: number;\n targetY: number;\n color: string;\n speed: number;\n size: number;\n angle: number;\n vx: number;\n vy: number;\n trail: { x: number; y: number }[];\n trailLength: number;\n exploded: boolean;\n update: () => boolean;\n explode: () => void;\n draw: (ctx: CanvasRenderingContext2D) => void;\n};\n\nfunction createFirework(\n x: number,\n y: number,\n targetY: number,\n color: string,\n speed: number,\n size: number,\n particleSpeed: { min: number; max: number } | number,\n particleSize: { min: number; max: number } | number,\n onExplode: (particles: ParticleType[]) => void,\n): FireworkType {\n const angle = -Math.PI / 2 + rand(-0.3, 0.3);\n const vx = Math.cos(angle) * speed;\n const vy = Math.sin(angle) * speed;\n const trail: { x: number; y: number }[] = [];\n const trailLength = randInt(10, 25);\n\n return {\n x,\n y,\n targetY,\n color,\n speed,\n size,\n angle,\n vx,\n vy,\n trail,\n trailLength,\n exploded: false,\n update() {\n this.trail.push({ x: this.x, y: this.y });\n if (this.trail.length > this.trailLength) {\n this.trail.shift();\n }\n this.x += this.vx;\n this.y += this.vy;\n this.vy += 0.02;\n if (this.vy >= 0 || this.y <= this.targetY) {\n this.explode();\n return false;\n }\n return true;\n },\n explode() {\n const numParticles = randInt(50, 150);\n const particles: ParticleType[] = [];\n for (let i = 0; i < numParticles; i++) {\n const particleAngle = rand(0, Math.PI * 2);\n const localParticleSpeed = getValueByRange(particleSpeed);\n const localParticleSize = getValueByRange(particleSize);\n particles.push(\n createParticle(\n this.x,\n this.y,\n this.color,\n localParticleSpeed,\n particleAngle,\n 0.05,\n 0.98,\n localParticleSize,\n ),\n );\n }\n onExplode(particles);\n },\n draw(ctx: CanvasRenderingContext2D) {\n ctx.save();\n ctx.beginPath();\n if (this.trail.length > 1) {\n ctx.moveTo(this.trail[0]?.x ?? this.x, this.trail[0]?.y ?? this.y);\n for (const point of this.trail) {\n ctx.lineTo(point.x, point.y);\n }\n } else {\n ctx.moveTo(this.x, this.y);\n ctx.lineTo(this.x, this.y);\n }\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.size;\n ctx.lineCap = 'round';\n ctx.stroke();\n ctx.restore();\n },\n };\n}\n\nfunction getValueByRange(range: { min: number; max: number } | number): number {\n if (typeof range === 'number') {\n return range;\n }\n return rand(range.min, range.max);\n}\n\nfunction getColor(color: string | string[] | undefined): string {\n if (Array.isArray(color)) {\n return color[randInt(0, color.length)] ?? randColor();\n }\n return color ?? randColor();\n}\n\ntype FireworksBackgroundProps = Omit<React.ComponentProps<'div'>, 'color'> & {\n canvasProps?: React.ComponentProps<'canvas'>;\n population?: number;\n color?: string | string[];\n fireworkSpeed?: { min: number; max: number } | number;\n fireworkSize?: { min: number; max: number } | number;\n particleSpeed?: { min: number; max: number } | number;\n particleSize?: { min: number; max: number } | number;\n};\n\nfunction FireworksBackground({\n ref,\n className,\n canvasProps,\n population = 1,\n color,\n fireworkSpeed = { min: 4, max: 8 },\n fireworkSize = { min: 2, max: 5 },\n particleSpeed = { min: 2, max: 7 },\n particleSize = { min: 1, max: 5 },\n ...props\n}: FireworksBackgroundProps) {\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n const canvas = canvasRef.current;\n const container = containerRef.current;\n if (!canvas || !container) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n\n let maxX = window.innerWidth;\n let ratio = container.offsetHeight / container.offsetWidth;\n let maxY = maxX * ratio;\n canvas.width = maxX;\n canvas.height = maxY;\n\n const setCanvasSize = () => {\n maxX = window.innerWidth;\n ratio = container.offsetHeight / container.offsetWidth;\n maxY = maxX * ratio;\n canvas.width = maxX;\n canvas.height = maxY;\n };\n window.addEventListener('resize', setCanvasSize);\n\n const explosions: ParticleType[] = [];\n const fireworks: FireworkType[] = [];\n\n const handleExplosion = (particles: ParticleType[]) => {\n explosions.push(...particles);\n };\n\n const launchFirework = () => {\n const x = rand(maxX * 0.1, maxX * 0.9);\n const y = maxY;\n const targetY = rand(maxY * 0.1, maxY * 0.4);\n const fireworkColor = getColor(color);\n const speed = getValueByRange(fireworkSpeed);\n const size = getValueByRange(fireworkSize);\n fireworks.push(\n createFirework(\n x,\n y,\n targetY,\n fireworkColor,\n speed,\n size,\n particleSpeed,\n particleSize,\n handleExplosion,\n ),\n );\n const timeout = rand(300, 800) / population;\n setTimeout(launchFirework, timeout);\n };\n\n launchFirework();\n\n let animationFrameId: number;\n const animate = () => {\n ctx.clearRect(0, 0, maxX, maxY);\n\n for (let i = fireworks.length - 1; i >= 0; i--) {\n const firework = fireworks[i];\n if (!firework?.update()) {\n fireworks.splice(i, 1);\n } else {\n firework.draw(ctx);\n }\n }\n\n for (let i = explosions.length - 1; i >= 0; i--) {\n const particle = explosions[i];\n particle?.update();\n if (particle?.isAlive()) {\n particle.draw(ctx);\n } else {\n explosions.splice(i, 1);\n }\n }\n\n animationFrameId = requestAnimationFrame(animate);\n };\n\n animate();\n\n const handleClick = (event: MouseEvent) => {\n const x = event.clientX;\n const y = maxY;\n const targetY = event.clientY;\n const fireworkColor = getColor(color);\n const speed = getValueByRange(fireworkSpeed);\n const size = getValueByRange(fireworkSize);\n fireworks.push(\n createFirework(\n x,\n y,\n targetY,\n fireworkColor,\n speed,\n size,\n particleSpeed,\n particleSize,\n handleExplosion,\n ),\n );\n };\n\n container.addEventListener('click', handleClick);\n\n return () => {\n window.removeEventListener('resize', setCanvasSize);\n container.removeEventListener('click', handleClick);\n cancelAnimationFrame(animationFrameId);\n };\n }, [\n population,\n color,\n fireworkSpeed,\n fireworkSize,\n particleSpeed,\n particleSize,\n ]);\n\n return (\n <div\n ref={containerRef}\n data-slot=\"fireworks-background\"\n className={cn('relative size-full overflow-hidden', className)}\n {...props}\n >\n <canvas\n {...canvasProps}\n ref={canvasRef}\n className={cn('absolute inset-0 size-full', canvasProps?.className)}\n />\n </div>\n );\n}\n\nexport { FireworksBackground, type FireworksBackgroundProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/fireworks/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fireworks-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/fireworks-background',
},
'gradient-background': {
name: 'gradient-background',
description:
'A background component featuring a subtle yet engaging animated gradient effect, smoothly transitioning colors to enhance visual depth.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/gradient/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/gradient.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { HTMLMotionProps, motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype GradientBackgroundProps = HTMLMotionProps<'div'> & {\n transition?: Transition;\n};\n\nfunction GradientBackground({\n className,\n transition = { duration: 15, ease: 'easeInOut', repeat: Infinity },\n ...props\n}: GradientBackgroundProps) {\n return (\n <motion.div\n data-slot=\"gradient-background\"\n className={cn(\n 'size-full bg-gradient-to-br from-blue-500 via-purple-500 to-pink-500 bg-[length:400%_400%]',\n className,\n )}\n animate={{\n backgroundPosition: ['0% 50%', '100% 50%', '0% 50%'],\n }}\n transition={transition}\n {...props}\n />\n );\n}\n\nexport { GradientBackground, type GradientBackgroundProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/gradient/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gradient-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gradient-background',
},
'hexagon-background': {
name: 'hexagon-background',
description:
'A background component featuring an interactive hexagon grid.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/hexagon/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/hexagon.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\ntype HexagonBackgroundProps = React.ComponentProps<'div'> & {\n children?: React.ReactNode;\n hexagonProps?: React.ComponentProps<'div'>;\n hexagonSize?: number; // value greater than 50\n hexagonMargin?: number;\n};\n\nfunction HexagonBackground({\n className,\n children,\n hexagonProps,\n hexagonSize = 75,\n hexagonMargin = 3,\n ...props\n}: HexagonBackgroundProps) {\n const hexagonWidth = hexagonSize;\n const hexagonHeight = hexagonSize * 1.1;\n const rowSpacing = hexagonSize * 0.8;\n const baseMarginTop = -36 - 0.275 * (hexagonSize - 100);\n const computedMarginTop = baseMarginTop + hexagonMargin;\n const oddRowMarginLeft = -(hexagonSize / 2);\n const evenRowMarginLeft = hexagonMargin / 2;\n\n const [gridDimensions, setGridDimensions] = React.useState({\n rows: 0,\n columns: 0,\n });\n\n const updateGridDimensions = React.useCallback(() => {\n const rows = Math.ceil(window.innerHeight / rowSpacing);\n const columns = Math.ceil(window.innerWidth / hexagonWidth) + 1;\n setGridDimensions({ rows, columns });\n }, [rowSpacing, hexagonWidth]);\n\n React.useEffect(() => {\n updateGridDimensions();\n window.addEventListener('resize', updateGridDimensions);\n return () => window.removeEventListener('resize', updateGridDimensions);\n }, [updateGridDimensions]);\n\n return (\n <div\n data-slot=\"hexagon-background\"\n className={cn(\n 'relative size-full overflow-hidden dark:bg-neutral-900 bg-neutral-100',\n className,\n )}\n {...props}\n >\n <style>{`:root { --hexagon-margin: ${hexagonMargin}px; }`}</style>\n <div className=\"absolute top-0 -left-0 size-full overflow-hidden\">\n {Array.from({ length: gridDimensions.rows }).map((_, rowIndex) => (\n <div\n key={`row-${rowIndex}`}\n style={{\n marginTop: computedMarginTop,\n marginLeft:\n ((rowIndex + 1) % 2 === 0\n ? evenRowMarginLeft\n : oddRowMarginLeft) - 10,\n }}\n className=\"inline-flex\"\n >\n {Array.from({ length: gridDimensions.columns }).map(\n (_, colIndex) => (\n <div\n key={`hexagon-${rowIndex}-${colIndex}`}\n {...hexagonProps}\n style={{\n width: hexagonWidth,\n height: hexagonHeight,\n marginLeft: hexagonMargin,\n ...hexagonProps?.style,\n }}\n className={cn(\n 'relative',\n '[clip-path:polygon(50%_0%,_100%_25%,_100%_75%,_50%_100%,_0%_75%,_0%_25%)]',\n \"before:content-[''] before:absolute before:top-0 before:left-0 before:w-full before:h-full dark:before:bg-neutral-950 before:bg-white before:opacity-100 before:transition-all before:duration-1000\",\n \"after:content-[''] after:absolute after:inset-[var(--hexagon-margin)] dark:after:bg-neutral-950 after:bg-white\",\n 'after:[clip-path:polygon(50%_0%,_100%_25%,_100%_75%,_50%_100%,_0%_75%,_0%_25%)]',\n 'hover:before:bg-neutral-200 dark:hover:before:bg-neutral-800 hover:before:opacity-100 hover:before:duration-0 dark:hover:after:bg-neutral-900 hover:after:bg-neutral-100 hover:after:opacity-100 hover:after:duration-0',\n hexagonProps?.className,\n )}\n />\n ),\n )}\n </div>\n ))}\n </div>\n {children}\n </div>\n );\n}\n\nexport { HexagonBackground, type HexagonBackgroundProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/hexagon/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'hexagon-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/hexagon-background',
},
'hole-background': {
name: 'hole-background',
description: 'A background with a hole animation effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/hole/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/hole.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype HoleBackgroundProps = React.ComponentProps<'div'> & {\n strokeColor?: string;\n numberOfLines?: number;\n numberOfDiscs?: number;\n particleRGBColor?: [number, number, number];\n};\n\nfunction HoleBackground({\n strokeColor = '#737373',\n numberOfLines = 50,\n numberOfDiscs = 50,\n particleRGBColor = [255, 255, 255],\n className,\n children,\n ...props\n}: HoleBackgroundProps) {\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\n const animationFrameIdRef = React.useRef<number>(0);\n const stateRef = React.useRef<any>({\n discs: [] as any[],\n lines: [] as any[],\n particles: [] as any[],\n clip: {},\n startDisc: {},\n endDisc: {},\n rect: { width: 0, height: 0 },\n render: { width: 0, height: 0, dpi: 1 },\n particleArea: {},\n linesCanvas: null,\n });\n\n const linear = (p: number) => p;\n const easeInExpo = (p: number) => (p === 0 ? 0 : Math.pow(2, 10 * (p - 1)));\n\n const tweenValue = React.useCallback(\n (start: number, end: number, p: number, ease: 'inExpo' | null = null) => {\n const delta = end - start;\n const easeFn = ease === 'inExpo' ? easeInExpo : linear;\n return start + delta * easeFn(p);\n },\n [],\n );\n\n const tweenDisc = React.useCallback(\n (disc: any) => {\n const { startDisc, endDisc } = stateRef.current;\n disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);\n disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, 'inExpo');\n disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);\n disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);\n },\n [tweenValue],\n );\n\n const setSize = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n stateRef.current.rect = { width: rect.width, height: rect.height };\n stateRef.current.render = {\n width: rect.width,\n height: rect.height,\n dpi: window.devicePixelRatio || 1,\n };\n canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;\n canvas.height =\n stateRef.current.render.height * stateRef.current.render.dpi;\n }, []);\n\n const setDiscs = React.useCallback(() => {\n const { width, height } = stateRef.current.rect;\n stateRef.current.discs = [];\n stateRef.current.startDisc = {\n x: width * 0.5,\n y: height * 0.45,\n w: width * 0.75,\n h: height * 0.7,\n };\n stateRef.current.endDisc = {\n x: width * 0.5,\n y: height * 0.95,\n w: 0,\n h: 0,\n };\n let prevBottom = height;\n stateRef.current.clip = {};\n for (let i = 0; i < numberOfDiscs; i++) {\n const p = i / numberOfDiscs;\n const disc = { p, x: 0, y: 0, w: 0, h: 0 };\n tweenDisc(disc);\n const bottom = disc.y + disc.h;\n if (bottom <= prevBottom) {\n stateRef.current.clip = { disc: { ...disc }, i };\n }\n prevBottom = bottom;\n stateRef.current.discs.push(disc);\n }\n const clipPath = new Path2D();\n const disc = stateRef.current.clip.disc;\n clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\n clipPath.rect(disc.x - disc.w, 0, disc.w * 2, disc.y);\n stateRef.current.clip.path = clipPath;\n }, [numberOfDiscs, tweenDisc]);\n\n const setLines = React.useCallback(() => {\n const { width, height } = stateRef.current.rect;\n stateRef.current.lines = [];\n const linesAngle = (Math.PI * 2) / numberOfLines;\n for (let i = 0; i < numberOfLines; i++) {\n stateRef.current.lines.push([]);\n }\n stateRef.current.discs.forEach((disc: any) => {\n for (let i = 0; i < numberOfLines; i++) {\n const angle = i * linesAngle;\n const p = {\n x: disc.x + Math.cos(angle) * disc.w,\n y: disc.y + Math.sin(angle) * disc.h,\n };\n stateRef.current.lines[i].push(p);\n }\n });\n const offCanvas = document.createElement('canvas');\n offCanvas.width = width;\n offCanvas.height = height;\n const ctx = offCanvas.getContext('2d');\n if (!ctx) return;\n stateRef.current.lines.forEach((line: any) => {\n ctx.save();\n let lineIsIn = false;\n line.forEach((p1: any, j: number) => {\n if (j === 0) return;\n const p0 = line[j - 1];\n if (\n !lineIsIn &&\n (ctx.isPointInPath(stateRef.current.clip.path, p1.x, p1.y) ||\n ctx.isPointInStroke(stateRef.current.clip.path, p1.x, p1.y))\n ) {\n lineIsIn = true;\n } else if (lineIsIn) {\n ctx.clip(stateRef.current.clip.path);\n }\n ctx.beginPath();\n ctx.moveTo(p0.x, p0.y);\n ctx.lineTo(p1.x, p1.y);\n ctx.strokeStyle = strokeColor;\n ctx.lineWidth = 2;\n ctx.stroke();\n ctx.closePath();\n });\n ctx.restore();\n });\n stateRef.current.linesCanvas = offCanvas;\n }, [numberOfLines, strokeColor]);\n\n const initParticle = React.useCallback(\n (start: boolean = false) => {\n const sx =\n stateRef.current.particleArea.sx +\n stateRef.current.particleArea.sw * Math.random();\n const ex =\n stateRef.current.particleArea.ex +\n stateRef.current.particleArea.ew * Math.random();\n const dx = ex - sx;\n const y = start\n ? stateRef.current.particleArea.h * Math.random()\n : stateRef.current.particleArea.h;\n const r = 0.5 + Math.random() * 4;\n const vy = 0.5 + Math.random();\n return {\n x: sx,\n sx,\n dx,\n y,\n vy,\n p: 0,\n r,\n c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${particleRGBColor[2]}, ${Math.random()})`,\n };\n },\n [particleRGBColor],\n );\n\n const setParticles = React.useCallback(() => {\n const { width, height } = stateRef.current.rect;\n stateRef.current.particles = [];\n const disc = stateRef.current.clip.disc;\n stateRef.current.particleArea = {\n sw: disc.w * 0.5,\n ew: disc.w * 2,\n h: height * 0.85,\n };\n stateRef.current.particleArea.sx =\n (width - stateRef.current.particleArea.sw) / 2;\n stateRef.current.particleArea.ex =\n (width - stateRef.current.particleArea.ew) / 2;\n const totalParticles = 100;\n for (let i = 0; i < totalParticles; i++) {\n stateRef.current.particles.push(initParticle(true));\n }\n }, [initParticle]);\n\n const drawDiscs = React.useCallback(\n (ctx: CanvasRenderingContext2D) => {\n ctx.strokeStyle = strokeColor;\n ctx.lineWidth = 2;\n const outerDisc = stateRef.current.startDisc;\n ctx.beginPath();\n ctx.ellipse(\n outerDisc.x,\n outerDisc.y,\n outerDisc.w,\n outerDisc.h,\n 0,\n 0,\n Math.PI * 2,\n );\n ctx.stroke();\n ctx.closePath();\n stateRef.current.discs.forEach((disc: any, i: number) => {\n if (i % 5 !== 0) return;\n if (disc.w < stateRef.current.clip.disc.w - 5) {\n ctx.save();\n ctx.clip(stateRef.current.clip.path);\n }\n ctx.beginPath();\n ctx.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\n ctx.stroke();\n ctx.closePath();\n if (disc.w < stateRef.current.clip.disc.w - 5) {\n ctx.restore();\n }\n });\n },\n [strokeColor],\n );\n\n const drawLines = React.useCallback((ctx: CanvasRenderingContext2D) => {\n if (stateRef.current.linesCanvas) {\n ctx.drawImage(stateRef.current.linesCanvas, 0, 0);\n }\n }, []);\n\n const drawParticles = React.useCallback((ctx: CanvasRenderingContext2D) => {\n ctx.save();\n ctx.clip(stateRef.current.clip.path);\n stateRef.current.particles.forEach((particle: any) => {\n ctx.fillStyle = particle.c;\n ctx.beginPath();\n ctx.rect(particle.x, particle.y, particle.r, particle.r);\n ctx.closePath();\n ctx.fill();\n });\n ctx.restore();\n }, []);\n\n const moveDiscs = React.useCallback(() => {\n stateRef.current.discs.forEach((disc: any) => {\n disc.p = (disc.p + 0.001) % 1;\n tweenDisc(disc);\n });\n }, [tweenDisc]);\n\n const moveParticles = React.useCallback(() => {\n stateRef.current.particles.forEach((particle: any, idx: number) => {\n particle.p = 1 - particle.y / stateRef.current.particleArea.h;\n particle.x = particle.sx + particle.dx * particle.p;\n particle.y -= particle.vy;\n if (particle.y < 0) {\n stateRef.current.particles[idx] = initParticle();\n }\n });\n }, [initParticle]);\n\n const tick = React.useCallback(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.save();\n ctx.scale(stateRef.current.render.dpi, stateRef.current.render.dpi);\n moveDiscs();\n moveParticles();\n drawDiscs(ctx);\n drawLines(ctx);\n drawParticles(ctx);\n ctx.restore();\n animationFrameIdRef.current = requestAnimationFrame(tick);\n }, [moveDiscs, moveParticles, drawDiscs, drawLines, drawParticles]);\n\n const init = React.useCallback(() => {\n setSize();\n setDiscs();\n setLines();\n setParticles();\n }, [setSize, setDiscs, setLines, setParticles]);\n\n React.useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n init();\n tick();\n const handleResize = () => {\n setSize();\n setDiscs();\n setLines();\n setParticles();\n };\n window.addEventListener('resize', handleResize);\n return () => {\n window.removeEventListener('resize', handleResize);\n cancelAnimationFrame(animationFrameIdRef.current);\n };\n }, [init, tick, setSize, setDiscs, setLines, setParticles]);\n\n return (\n <div\n data-slot=\"hole-background\"\n className={cn(\n 'relative size-full overflow-hidden',\n 'before:content-[\"\"] before:absolute before:top-1/2 before:left-1/2 before:block before:size-[140%] dark:before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,black_50%)] before:[background:radial-gradient(ellipse_at_50%_55%,transparent_10%,white_50%)] before:[transform:translate3d(-50%,-50%,0)]',\n 'after:content-[\"\"] after:absolute after:z-[5] after:top-1/2 after:left-1/2 after:block after:size-full after:[background:radial-gradient(ellipse_at_50%_75%,#a900ff_20%,transparent_75%)] after:[transform:translate3d(-50%,-50%,0)] after:mix-blend-overlay',\n className,\n )}\n {...props}\n >\n {children}\n <canvas\n ref={canvasRef}\n className=\"absolute inset-0 block size-full dark:opacity-20 opacity-10\"\n />\n <motion.div\n className={cn(\n 'absolute top-[-71.5%] left-1/2 z-[3] w-[30%] h-[140%] rounded-b-full blur-3xl opacity-75 dark:mix-blend-plus-lighter mix-blend-plus-darker [transform:translate3d(-50%,0,0)] [background-position:0%_100%] [background-size:100%_200%]',\n 'dark:[background:linear-gradient(20deg,#00f8f1,#ffbd1e20_16.5%,#fe848f_33%,#fe848f20_49.5%,#00f8f1_66%,#00f8f160_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%] [background:linear-gradient(20deg,#00f8f1,#ffbd1e40_16.5%,#fe848f_33%,#fe848f40_49.5%,#00f8f1_66%,#00f8f180_85.5%,#ffbd1e_100%)_0_100%_/_100%_200%]',\n )}\n animate={{ backgroundPosition: '0% 300%' }}\n transition={{ duration: 5, ease: 'linear', repeat: Infinity }}\n />\n <div className=\"absolute top-0 left-0 z-[7] size-full dark:[background:repeating-linear-gradient(transparent,transparent_1px,white_1px,white_2px)] mix-blend-overlay opacity-50\" />\n </div>\n );\n}\n\nexport { HoleBackground, type HoleBackgroundProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/hole/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'hole-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/hole-background',
},
'stars-background': {
name: 'stars-background',
description:
'A dark, interactive background featuring animated dots of varying sizes and speeds, simulating a dynamic and immersive starry space effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/backgrounds/stars/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/backgrounds/stars.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n type HTMLMotionProps,\n motion,\n type SpringOptions,\n type Transition,\n useMotionValue,\n useSpring,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype StarLayerProps = HTMLMotionProps<'div'> & {\n count: number;\n size: number;\n transition: Transition;\n starColor: string;\n};\n\nfunction generateStars(count: number, starColor: string) {\n const shadows: string[] = [];\n for (let i = 0; i < count; i++) {\n const x = Math.floor(Math.random() * 4000) - 2000;\n const y = Math.floor(Math.random() * 4000) - 2000;\n shadows.push(`${x}px ${y}px ${starColor}`);\n }\n return shadows.join(', ');\n}\n\nfunction StarLayer({\n count = 1000,\n size = 1,\n transition = { repeat: Infinity, duration: 50, ease: 'linear' },\n starColor = '#fff',\n className,\n ...props\n}: StarLayerProps) {\n const [boxShadow, setBoxShadow] = React.useState<string>('');\n\n React.useEffect(() => {\n setBoxShadow(generateStars(count, starColor));\n }, [count, starColor]);\n\n return (\n <motion.div\n data-slot=\"star-layer\"\n animate={{ y: [0, -2000] }}\n transition={transition}\n className={cn('absolute top-0 left-0 w-full h-[2000px]', className)}\n {...props}\n >\n <div\n className=\"absolute bg-transparent rounded-full\"\n style={{\n width: `${size}px`,\n height: `${size}px`,\n boxShadow: boxShadow,\n }}\n />\n <div\n className=\"absolute bg-transparent rounded-full top-[2000px]\"\n style={{\n width: `${size}px`,\n height: `${size}px`,\n boxShadow: boxShadow,\n }}\n />\n </motion.div>\n );\n}\n\ntype StarsBackgroundProps = React.ComponentProps<'div'> & {\n factor?: number;\n speed?: number;\n transition?: SpringOptions;\n starColor?: string;\n pointerEvents?: boolean;\n};\n\nfunction StarsBackground({\n children,\n className,\n factor = 0.05,\n speed = 50,\n transition = { stiffness: 50, damping: 20 },\n starColor = '#fff',\n pointerEvents = true,\n ...props\n}: StarsBackgroundProps) {\n const offsetX = useMotionValue(1);\n const offsetY = useMotionValue(1);\n\n const springX = useSpring(offsetX, transition);\n const springY = useSpring(offsetY, transition);\n\n const handleMouseMove = React.useCallback(\n (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {\n const centerX = window.innerWidth / 2;\n const centerY = window.innerHeight / 2;\n const newOffsetX = -(e.clientX - centerX) * factor;\n const newOffsetY = -(e.clientY - centerY) * factor;\n offsetX.set(newOffsetX);\n offsetY.set(newOffsetY);\n },\n [offsetX, offsetY, factor],\n );\n\n return (\n <div\n data-slot=\"stars-background\"\n className={cn(\n 'relative size-full overflow-hidden bg-[radial-gradient(ellipse_at_bottom,_#262626_0%,_#000_100%)]',\n className,\n )}\n onMouseMove={handleMouseMove}\n {...props}\n >\n <motion.div\n style={{ x: springX, y: springY }}\n className={cn({ 'pointer-events-none': !pointerEvents })}\n >\n <StarLayer\n count={1000}\n size={1}\n transition={{ repeat: Infinity, duration: speed, ease: 'linear' }}\n starColor={starColor}\n />\n <StarLayer\n count={400}\n size={2}\n transition={{\n repeat: Infinity,\n duration: speed * 2,\n ease: 'linear',\n }}\n starColor={starColor}\n />\n <StarLayer\n count={200}\n size={3}\n transition={{\n repeat: Infinity,\n duration: speed * 3,\n ease: 'linear',\n }}\n starColor={starColor}\n />\n </motion.div>\n {children}\n </div>\n );\n}\n\nexport {\n StarLayer,\n StarsBackground,\n type StarLayerProps,\n type StarsBackgroundProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/backgrounds/stars/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'stars-background';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/stars-background',
},
'base-accordion': {
name: 'base-accordion',
description: 'An easily stylable accordion component.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/accordion.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Accordion as AccordionPrimitive } from '@base-ui-components/react/accordion';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport { ChevronDown } from 'lucide-react';\n\ntype AccordionItemContextType = {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n};\n\nconst AccordionItemContext = React.createContext<\n AccordionItemContextType | undefined\n>(undefined);\n\nconst useAccordionItem = (): AccordionItemContextType => {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('useAccordionItem must be used within an AccordionItem');\n }\n return context;\n};\n\ntype AccordionProps = React.ComponentProps<typeof AccordionPrimitive.Root>;\n\nfunction Accordion(props: AccordionProps) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\ntype AccordionItemProps = React.ComponentProps<\n typeof AccordionPrimitive.Item\n> & {\n children: React.ReactNode;\n};\n\nfunction AccordionItem({ className, children, ...props }: AccordionItemProps) {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <AccordionItemContext.Provider value={{ isOpen, setIsOpen }}>\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn('border-b', className)}\n {...props}\n >\n {children}\n </AccordionPrimitive.Item>\n </AccordionItemContext.Provider>\n );\n}\n\ntype AccordionTriggerProps = React.ComponentProps<\n typeof AccordionPrimitive.Trigger\n> & {\n transition?: Transition;\n chevron?: boolean;\n};\n\nfunction AccordionTrigger({\n ref,\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n chevron = true,\n ...props\n}: AccordionTriggerProps) {\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => triggerRef.current as HTMLButtonElement);\n const { isOpen, setIsOpen } = useAccordionItem();\n\n React.useEffect(() => {\n const node = triggerRef.current;\n if (!node) return;\n const observer = new MutationObserver((mutationsList) => {\n mutationsList.forEach((mutation) => {\n if (mutation.attributeName === 'data-panel-open') {\n const currentState = node.getAttribute('data-panel-open');\n setIsOpen(currentState === '');\n }\n });\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-panel-open'],\n });\n const initialState = node.getAttribute('data-panel-open');\n setIsOpen(initialState === '');\n return () => observer.disconnect();\n }, [setIsOpen]);\n\n return (\n <AccordionPrimitive.Header data-slot=\"accordion-header\" className=\"flex\">\n <AccordionPrimitive.Trigger\n ref={triggerRef}\n data-slot=\"accordion-trigger\"\n className={cn(\n 'flex flex-1 text-start items-center justify-between py-4 font-medium hover:underline',\n className,\n )}\n {...props}\n >\n {children}\n\n {chevron && (\n <motion.div\n data-slot=\"accordion-trigger-chevron\"\n animate={{ rotate: isOpen ? 180 : 0 }}\n transition={transition}\n >\n <ChevronDown className=\"size-5 shrink-0\" />\n </motion.div>\n )}\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\ntype AccordionPanelProps = React.ComponentProps<\n typeof AccordionPrimitive.Panel\n> & {\n motionProps?: HTMLMotionProps<'div'>;\n transition?: Transition;\n};\n\nfunction AccordionPanel({\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n motionProps,\n ...props\n}: AccordionPanelProps) {\n const { isOpen } = useAccordionItem();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <AccordionPrimitive.Panel\n hidden={false}\n keepMounted\n render={\n <motion.div\n key=\"accordion-panel\"\n data-slot=\"accordion-panel\"\n initial={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n animate={{ height: 'auto', opacity: 1, '--mask-stop': '100%' }}\n exit={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n transition={transition}\n style={{\n maskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n WebkitMaskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n }}\n className=\"overflow-hidden\"\n {...motionProps}\n >\n <div className={cn('pb-4 pt-0 text-sm', className)}>\n {children}\n </div>\n </motion.div>\n }\n {...props}\n />\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionPanel,\n useAccordionItem,\n type AccordionItemContextType,\n type AccordionProps,\n type AccordionItemProps,\n type AccordionTriggerProps,\n type AccordionPanelProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/accordion/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-accordion';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-accordion',
},
'base-checkbox': {
name: 'base-checkbox',
description: 'An easily stylable checkbox component.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/checkbox.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { Checkbox as CheckboxPrimitive } from \'@base-ui-components/react/checkbox\';\nimport { type HTMLMotionProps, motion } from \'motion/react\';\n\nimport { cn } from \'@/lib/utils\';\n\ntype CheckboxProps = Omit<\n React.ComponentProps<typeof CheckboxPrimitive.Root>,\n \'render\'\n> & {\n motionProps?: HTMLMotionProps<\'button\'>;\n};\n\nfunction Checkbox({\n className,\n onCheckedChange,\n motionProps,\n ...props\n}: CheckboxProps) {\n const [isChecked, setIsChecked] = React.useState(\n props?.checked ?? props?.defaultChecked ?? false,\n );\n\n React.useEffect(() => {\n if (props?.checked !== undefined) setIsChecked(props.checked);\n }, [props?.checked]);\n\n const handleCheckedChange = React.useCallback(\n (checked: boolean, event: Event) => {\n setIsChecked(checked);\n onCheckedChange?.(checked, event);\n },\n [onCheckedChange],\n );\n\n return (\n <CheckboxPrimitive.Root\n data-slot="checkbox"\n className={cn(\n \'peer shrink-0 flex items-center justify-center outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 disabled:cursor-not-allowed disabled:opacity-50 transition-colors duration-500\',\n \'size-5 rounded-sm bg-input focus-visible:ring-offset-2 data-[checked]:bg-primary data-[checked]:text-primary-foreground\',\n className,\n )}\n {...props}\n onCheckedChange={handleCheckedChange}\n render={\n <motion.button\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n {...motionProps}\n />\n }\n >\n <CheckboxPrimitive.Indicator\n keepMounted\n data-slot="checkbox-indicator"\n className="flex items-center justify-center text-current transition-none"\n >\n <motion.svg\n xmlns="http://www.w3.org/2000/svg"\n fill="none"\n viewBox="0 0 24 24"\n strokeWidth="3.5"\n stroke="currentColor"\n className="size-3.5"\n initial="unchecked"\n animate={isChecked ? \'checked\' : \'unchecked\'}\n >\n <motion.path\n strokeLinecap="round"\n strokeLinejoin="round"\n d="M4.5 12.75l6 6 9-13.5"\n variants={{\n checked: {\n pathLength: 1,\n opacity: 1,\n transition: {\n duration: 0.2,\n delay: 0.2,\n },\n },\n unchecked: {\n pathLength: 0,\n opacity: 0,\n transition: {\n duration: 0.2,\n },\n },\n }}\n />\n </motion.svg>\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nCheckbox.displayName = CheckboxPrimitive.Root.displayName;\n\nexport { Checkbox, type CheckboxProps };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-checkbox';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-checkbox',
},
'base-popover': {
name: 'base-popover',
description: 'An accessible popup anchored to a button.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/popover.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Popover as PopoverPrimitive } from '@base-ui-components/react/popover';\nimport {\n AnimatePresence,\n HTMLMotionProps,\n motion,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype Side = React.ComponentPropsWithoutRef<\n typeof PopoverPrimitive.Positioner\n>['side'];\n\ntype Align = React.ComponentPropsWithoutRef<\n typeof PopoverPrimitive.Positioner\n>['align'];\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n case 'inline-start':\n return { x: 15 };\n case 'right':\n case 'inline-end':\n return { x: -15 };\n }\n};\n\ntype PopoverContextType = {\n isOpen: boolean;\n side?: Side;\n setSide?: (side: Side) => void;\n};\n\nconst PopoverContext = React.createContext<PopoverContextType | undefined>(\n undefined,\n);\n\nconst usePopover = (): PopoverContextType => {\n const context = React.useContext(PopoverContext);\n if (!context) {\n throw new Error('usePopover must be used within a Popover');\n }\n return context;\n};\n\ntype PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root>;\n\nfunction Popover(props: PopoverProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (\n open: boolean,\n event: Event | undefined,\n reason: Parameters<NonNullable<PopoverProps['onOpenChange']>>[2],\n ) => {\n setIsOpen(open);\n props.onOpenChange?.(open, event, reason);\n },\n [props],\n );\n\n return (\n <PopoverContext.Provider value={{ isOpen }}>\n <PopoverPrimitive.Root\n data-slot=\"popover\"\n {...props}\n onOpenChange={handleOpenChange}\n />\n </PopoverContext.Provider>\n );\n}\n\ntype PopoverTriggerProps = React.ComponentProps<\n typeof PopoverPrimitive.Trigger\n>;\n\nfunction PopoverTrigger(props: PopoverTriggerProps) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\ntype PopoverContentProps = Omit<\n React.ComponentProps<typeof PopoverPrimitive.Positioner>,\n 'render'\n> & {\n transition?: Transition;\n popupProps?: typeof PopoverPrimitive.Popup;\n motionProps?: HTMLMotionProps<'div'>;\n positionerClassName?: string;\n};\n\nfunction PopoverContent({\n children,\n align = 'center',\n side = 'bottom',\n sideOffset = 4,\n className,\n positionerClassName,\n popupProps,\n motionProps,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n ...props\n}: PopoverContentProps) {\n const { isOpen } = usePopover();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <PopoverPrimitive.Portal keepMounted data-slot=\"popover-portal\">\n <PopoverPrimitive.Positioner\n data-slot=\"popover-positioner\"\n align={align}\n side={side}\n sideOffset={sideOffset}\n className={cn('z-50', positionerClassName)}\n {...props}\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-popup\"\n {...popupProps}\n className={cn(\n 'w-72 rounded-lg border bg-popover p-4 text-popover-foreground shadow-md outline-hidden',\n className,\n )}\n render={\n <motion.div\n key=\"popover-content\"\n initial={{ opacity: 0, scale: 0.5, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.5, ...initialPosition }}\n transition={transition}\n {...motionProps}\n />\n }\n >\n {children}\n </PopoverPrimitive.Popup>\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n usePopover,\n type PopoverContextType,\n type PopoverProps,\n type PopoverTriggerProps,\n type PopoverContentProps,\n type Side,\n type Align,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-popover';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-popover',
},
'base-preview-card': {
name: 'base-preview-card',
description:
'A popup that appears when a link is hovered, showing a preview for sighted users.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/preview-card/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/preview-card.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { PreviewCard as PreviewCardPrimitives } from '@base-ui-components/react/preview-card';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype PreviewCardContextType = {\n isOpen: boolean;\n};\n\nconst PreviewCardContext = React.createContext<\n PreviewCardContextType | undefined\n>(undefined);\n\nconst usePreviewCard = (): PreviewCardContextType => {\n const context = React.useContext(PreviewCardContext);\n if (!context) {\n throw new Error('usePreviewCard must be used within a PreviewCard');\n }\n return context;\n};\n\ntype Side = React.ComponentPropsWithoutRef<\n typeof PreviewCardPrimitives.Positioner\n>['side'];\n\ntype Align = React.ComponentPropsWithoutRef<\n typeof PreviewCardPrimitives.Positioner\n>['align'];\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n case 'inline-start':\n return { x: 15 };\n case 'right':\n case 'inline-end':\n return { x: -15 };\n }\n};\n\ntype PreviewCardProps = React.ComponentProps<typeof PreviewCardPrimitives.Root>;\n\nfunction PreviewCard(props: PreviewCardProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (\n open: boolean,\n event: Event | undefined,\n reason: Parameters<NonNullable<PreviewCardProps['onOpenChange']>>[2],\n ) => {\n setIsOpen(open);\n props.onOpenChange?.(open, event, reason);\n },\n [props],\n );\n\n return (\n <PreviewCardContext.Provider value={{ isOpen }}>\n <PreviewCardPrimitives.Root\n data-slot=\"preview-card\"\n {...props}\n onOpenChange={handleOpenChange}\n />\n </PreviewCardContext.Provider>\n );\n}\n\ntype PreviewCardTriggerProps = React.ComponentProps<\n typeof PreviewCardPrimitives.Trigger\n>;\n\nfunction PreviewCardTrigger(props: PreviewCardTriggerProps) {\n return (\n <PreviewCardPrimitives.Trigger\n data-slot=\"preview-card-trigger\"\n {...props}\n />\n );\n}\n\ntype PreviewCardContentProps = React.ComponentProps<\n typeof PreviewCardPrimitives.Positioner\n> & {\n transition?: Transition;\n popupProps?: typeof PreviewCardPrimitives.Popup;\n motionProps?: HTMLMotionProps<'div'>;\n positionerClassName?: string;\n};\n\nfunction PreviewCardContent({\n className,\n popupProps,\n motionProps,\n positionerClassName,\n side = 'bottom',\n sideOffset = 10,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n children,\n ...props\n}: PreviewCardContentProps) {\n const { isOpen } = usePreviewCard();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <PreviewCardPrimitives.Portal\n keepMounted\n data-slot=\"preview-card-portal\"\n >\n <PreviewCardPrimitives.Positioner\n data-slot=\"preview-card-positioner\"\n side={side}\n sideOffset={sideOffset}\n className={cn('z-50', positionerClassName)}\n {...props}\n >\n <PreviewCardPrimitives.Popup\n data-slot=\"preview-card-popup\"\n {...popupProps}\n className={cn(\n 'w-64 rounded-lg border bg-popover p-4 text-popover-foreground shadow-md outline-none',\n className,\n )}\n render={\n <motion.div\n key=\"preview-card-content\"\n initial={{ opacity: 0, scale: 0.5, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.5, ...initialPosition }}\n transition={transition}\n {...motionProps}\n />\n }\n >\n {children}\n </PreviewCardPrimitives.Popup>\n </PreviewCardPrimitives.Positioner>\n </PreviewCardPrimitives.Portal>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n PreviewCard,\n PreviewCardTrigger,\n PreviewCardContent,\n usePreviewCard,\n type PreviewCardProps,\n type PreviewCardTriggerProps,\n type PreviewCardContentProps,\n type Side,\n type Align,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/preview-card/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-preview-card';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-preview-card',
},
'base-progress': {
name: 'base-progress',
description: 'Displays the status of a task that takes a long time.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/counting-number'],
files: [
{
path: 'registry/base/progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/progress.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Progress as ProgressPrimitives } from '@base-ui-components/react/progress';\nimport { motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n CountingNumber,\n type CountingNumberProps,\n} from '@/components/animate-ui/text/counting-number';\n\ntype ProgressContextType = {\n value: number | null;\n};\n\nconst ProgressContext = React.createContext<ProgressContextType | undefined>(\n undefined,\n);\n\nconst useProgress = (): ProgressContextType => {\n const context = React.useContext(ProgressContext);\n if (!context) {\n throw new Error('useProgress must be used within a Progress');\n }\n return context;\n};\n\ntype ProgressProps = React.ComponentProps<typeof ProgressPrimitives.Root>;\n\nconst Progress = ({ value, ...props }: ProgressProps) => {\n return (\n <ProgressContext.Provider value={{ value }}>\n <ProgressPrimitives.Root data-slot=\"progress\" value={value} {...props}>\n {props.children}\n </ProgressPrimitives.Root>\n </ProgressContext.Provider>\n );\n};\n\nconst MotionProgressIndicator = motion.create(ProgressPrimitives.Indicator);\n\ntype ProgressTrackProps = React.ComponentProps<\n typeof ProgressPrimitives.Track\n> & {\n transition?: Transition;\n};\n\nfunction ProgressTrack({\n className,\n transition = { type: 'spring', stiffness: 100, damping: 30 },\n ...props\n}: ProgressTrackProps) {\n const { value } = useProgress();\n\n return (\n <ProgressPrimitives.Track\n data-slot=\"progress-track\"\n className={cn(\n 'relative h-2 w-full overflow-hidden rounded-full bg-secondary',\n className,\n )}\n {...props}\n >\n <MotionProgressIndicator\n data-slot=\"progress-indicator\"\n className=\"h-full w-full flex-1 bg-primary rounded-full\"\n animate={{ width: `${value}%` }}\n transition={transition}\n />\n </ProgressPrimitives.Track>\n );\n}\n\ntype ProgressLabelProps = React.ComponentProps<typeof ProgressPrimitives.Label>;\n\nfunction ProgressLabel(props: ProgressLabelProps) {\n return <ProgressPrimitives.Label data-slot=\"progress-label\" {...props} />;\n}\n\ntype ProgressValueProps = Omit<\n React.ComponentProps<typeof ProgressPrimitives.Value>,\n 'render'\n> & {\n countingNumberProps?: CountingNumberProps;\n};\n\nfunction ProgressValue({ countingNumberProps, ...props }: ProgressValueProps) {\n const { value } = useProgress();\n\n return (\n <ProgressPrimitives.Value\n data-slot=\"progress-value\"\n render={\n <CountingNumber\n number={value ?? 0}\n transition={{ stiffness: 80, damping: 20 }}\n {...countingNumberProps}\n />\n }\n {...props}\n />\n );\n}\n\nexport {\n Progress,\n ProgressTrack,\n ProgressLabel,\n ProgressValue,\n useProgress,\n type ProgressProps,\n type ProgressTrackProps,\n type ProgressLabelProps,\n type ProgressValueProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/progress/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-progress';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-progress',
},
'base-switch': {
name: 'base-switch',
description: 'A control that indicates whether a setting is on or off.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/switch.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Switch as SwitchPrimitives } from '@base-ui-components/react/switch';\nimport { motion, type HTMLMotionProps } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype SwitchProps = Omit<\n React.ComponentProps<typeof SwitchPrimitives.Root>,\n 'render'\n> & {\n motionProps?: HTMLMotionProps<'button'>;\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n thumbIcon?: React.ReactNode;\n};\n\nfunction Switch({\n className,\n leftIcon,\n rightIcon,\n thumbIcon,\n onCheckedChange,\n motionProps,\n ...props\n}: SwitchProps) {\n const [isChecked, setIsChecked] = React.useState(\n props?.checked ?? props?.defaultChecked ?? false,\n );\n const [isTapped, setIsTapped] = React.useState(false);\n\n React.useEffect(() => {\n if (props?.checked !== undefined) setIsChecked(props.checked);\n }, [props?.checked]);\n\n const handleCheckedChange = React.useCallback(\n (checked: boolean, event: Event) => {\n setIsChecked(checked);\n onCheckedChange?.(checked, event);\n },\n [onCheckedChange],\n );\n\n return (\n <SwitchPrimitives.Root\n data-slot=\"switch\"\n {...props}\n onCheckedChange={handleCheckedChange}\n className={cn(\n 'peer relative inline-flex p-[3px] h-6 w-10 shrink-0 cursor-pointer items-center rounded-full transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[checked]:bg-primary data-[unchecked]:bg-input data-[checked]:justify-end data-[unchecked]:justify-start',\n className,\n )}\n render={\n <motion.button\n whileTap=\"tap\"\n initial={false}\n onTapStart={() => setIsTapped(true)}\n onTapCancel={() => setIsTapped(false)}\n onTap={() => setIsTapped(false)}\n {...motionProps}\n />\n }\n >\n {leftIcon && (\n <motion.div\n data-slot=\"switch-left-icon\"\n animate={\n isChecked ? { scale: 1, opacity: 1 } : { scale: 0, opacity: 0 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute top-1/2 -translate-y-1/2 dark:text-neutral-500 text-neutral-400 [&_svg]:size-3 left-1\"\n >\n {typeof leftIcon !== 'string' ? leftIcon : null}\n </motion.div>\n )}\n\n {rightIcon && (\n <motion.div\n data-slot=\"switch-right-icon\"\n animate={\n isChecked ? { scale: 0, opacity: 0 } : { scale: 1, opacity: 1 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute top-1/2 -translate-y-1/2 dark:text-neutral-400 text-neutral-500 [&_svg]:size-3 right-1\"\n >\n {typeof rightIcon !== 'string' ? rightIcon : null}\n </motion.div>\n )}\n\n <SwitchPrimitives.Thumb\n data-slot=\"switch-thumb\"\n render={\n <motion.div\n whileTap=\"tab\"\n className=\"relative pointer-events-none z-[1] [&_svg]:size-3 flex items-center justify-center rounded-full bg-background shadow-lg ring-0 dark:text-neutral-400 text-neutral-500\"\n layout\n transition={{ type: 'spring', stiffness: 300, damping: 25 }}\n style={{ width: 18, height: 18 }}\n animate={\n isTapped\n ? {\n width: 21,\n transition: { duration: 0.1 },\n }\n : { width: 18, transition: { duration: 0.1 } }\n }\n />\n }\n >\n {thumbIcon && typeof thumbIcon !== 'string' ? thumbIcon : null}\n </SwitchPrimitives.Thumb>\n </SwitchPrimitives.Root>\n );\n}\n\nSwitch.displayName = SwitchPrimitives.Root.displayName;\n\nexport { Switch, type SwitchProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-switch';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-switch',
},
'base-toggle-group': {
name: 'base-toggle-group',
description: 'Provides a shared state to a series of toggle buttons.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/toggle-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/toggle-group.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { ToggleGroup as ToggleGroupPrimitive } from '@base-ui-components/react/toggle-group';\nimport { Toggle as TogglePrimitive } from '@base-ui-components/react/toggle';\nimport {\n type HTMLMotionProps,\n type Transition,\n motion,\n AnimatePresence,\n} from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst toggleVariants = cva(\n \"cursor-pointer inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:text-muted-foreground text-accent-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[pressed]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none focus:outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n type: {\n single: '',\n multiple: 'data-[pressed]:bg-accent',\n },\n variant: {\n default: 'bg-transparent',\n outline: 'border border-input bg-transparent shadow-xs',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype ToggleGroupContextProps = VariantProps<typeof toggleVariants> & {\n type?: 'single' | 'multiple';\n transition?: Transition;\n activeClassName?: string;\n globalId: string;\n};\n\nconst ToggleGroupContext = React.createContext<\n ToggleGroupContextProps | undefined\n>(undefined);\n\nconst useToggleGroup = (): ToggleGroupContextProps => {\n const context = React.useContext(ToggleGroupContext);\n if (!context) {\n throw new Error('useToggleGroup must be used within a ToggleGroup');\n }\n return context;\n};\n\ntype ToggleGroupProps = React.ComponentProps<typeof ToggleGroupPrimitive> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n transition?: Transition;\n activeClassName?: string;\n };\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n transition = { type: 'spring', bounce: 0, stiffness: 200, damping: 25 },\n activeClassName,\n ...props\n}: ToggleGroupProps) {\n const globalId = React.useId();\n\n return (\n <ToggleGroupContext.Provider\n value={{\n variant,\n size,\n type: props.toggleMultiple ? 'multiple' : 'single',\n transition,\n activeClassName,\n globalId,\n }}\n >\n <ToggleGroupPrimitive\n data-slot=\"toggle-group\"\n className={cn(\n 'flex items-center justify-center gap-1 relative',\n className,\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive>\n </ToggleGroupContext.Provider>\n );\n}\n\ntype ToggleGroupItemProps = Omit<\n React.ComponentProps<typeof TogglePrimitive>,\n 'render'\n> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n children?: React.ReactNode;\n buttonProps?: HTMLMotionProps<'button'>;\n spanProps?: React.ComponentProps<'span'>;\n };\n\nfunction ToggleGroupItem({\n ref,\n className,\n children,\n variant,\n size,\n buttonProps,\n spanProps,\n ...props\n}: ToggleGroupItemProps) {\n const {\n activeClassName,\n transition,\n type,\n variant: contextVariant,\n size: contextSize,\n globalId,\n } = useToggleGroup();\n const itemRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => itemRef.current as HTMLButtonElement);\n const [isActive, setIsActive] = React.useState(false);\n\n React.useEffect(() => {\n const node = itemRef.current;\n if (!node) return;\n const observer = new MutationObserver(() => {\n setIsActive(node.getAttribute('data-pressed') === '');\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-pressed'],\n });\n setIsActive(node.getAttribute('data-pressed') === '');\n return () => observer.disconnect();\n }, [setIsActive]);\n\n return (\n <TogglePrimitive\n ref={itemRef}\n {...props}\n render={\n <motion.button\n data-slot=\"toggle-group-item\"\n initial={{ scale: 1 }}\n whileTap={{ scale: 0.9 }}\n {...buttonProps}\n className={cn('relative', buttonProps?.className)}\n >\n <span\n {...spanProps}\n {...(isActive ? { 'data-pressed': '' } : {})}\n className={cn(\n 'relative z-[1]',\n toggleVariants({\n variant: variant || contextVariant,\n size: size || contextSize,\n type,\n }),\n className,\n spanProps?.className,\n )}\n >\n {children}\n </span>\n\n <AnimatePresence initial={false}>\n {isActive && type === 'single' && (\n <motion.span\n layoutId={`active-toggle-group-item-${globalId}`}\n data-slot=\"active-toggle-group-item\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={transition}\n className={cn(\n 'absolute inset-0 z-0 rounded-md bg-muted',\n activeClassName,\n )}\n />\n )}\n </AnimatePresence>\n </motion.button>\n }\n />\n );\n}\n\nexport {\n ToggleGroup,\n ToggleGroupItem,\n type ToggleGroupProps,\n type ToggleGroupItemProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/toggle-group/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-toggle-group';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-toggle-group',
},
'base-tooltip': {
name: 'base-tooltip',
description:
'A popup that appears when an element is hovered or focused, showing a hint for sighted users.',
type: 'registry:ui',
dependencies: ['motion', '@base-ui-components/react'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/base/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/base/tooltip.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Tooltip as TooltipPrimitive } from '@base-ui-components/react/tooltip';\nimport {\n AnimatePresence,\n type HTMLMotionProps,\n motion,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype TooltipContextType = {\n isOpen: boolean;\n};\n\nconst TooltipContext = React.createContext<TooltipContextType | undefined>(\n undefined,\n);\n\nconst useTooltip = (): TooltipContextType => {\n const context = React.useContext(TooltipContext);\n if (!context) {\n throw new Error('useTooltip must be used within a Tooltip');\n }\n return context;\n};\n\ntype Side = React.ComponentPropsWithoutRef<\n typeof TooltipPrimitive.Positioner\n>['side'];\n\ntype Align = React.ComponentPropsWithoutRef<\n typeof TooltipPrimitive.Positioner\n>['align'];\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n case 'inline-start':\n return { x: 15 };\n case 'right':\n case 'inline-end':\n return { x: -15 };\n }\n};\n\ntype TooltipProviderProps = React.ComponentProps<\n typeof TooltipPrimitive.Provider\n>;\n\nfunction TooltipProvider(props: TooltipProviderProps) {\n return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" {...props} />;\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>;\n\nfunction Tooltip(props: TooltipProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (\n open: boolean,\n event: Event | undefined,\n reason: Parameters<NonNullable<TooltipProps['onOpenChange']>>[2],\n ) => {\n setIsOpen(open);\n props.onOpenChange?.(open, event, reason);\n },\n [props],\n );\n\n return (\n <TooltipContext.Provider value={{ isOpen }}>\n <TooltipPrimitive.Root\n data-slot=\"tooltip\"\n {...props}\n onOpenChange={handleOpenChange}\n />\n </TooltipContext.Provider>\n );\n}\n\ntype TooltipTriggerProps = React.ComponentProps<\n typeof TooltipPrimitive.Trigger\n>;\n\nfunction TooltipTrigger(props: TooltipTriggerProps) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\ntype TooltipContentProps = React.ComponentProps<\n typeof TooltipPrimitive.Positioner\n> & {\n transition?: Transition;\n popupProps?: typeof TooltipPrimitive.Popup;\n motionProps?: HTMLMotionProps<'div'>;\n positionerClassName?: string;\n arrow?: boolean;\n};\n\nfunction TooltipContent({\n className,\n popupProps,\n motionProps,\n positionerClassName,\n side = 'top',\n sideOffset = 10,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n arrow = true,\n children,\n ...props\n}: TooltipContentProps) {\n const { isOpen } = useTooltip();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <TooltipPrimitive.Portal keepMounted data-slot=\"tooltip-portal\">\n <TooltipPrimitive.Positioner\n data-slot=\"tooltip-positioner\"\n side={side}\n sideOffset={sideOffset}\n className={cn('z-50', positionerClassName)}\n {...props}\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-popup\"\n {...popupProps}\n className={cn(\n 'relative bg-primary text-primary-foreground shadow-md w-fit rounded-md px-3 py-1.5 text-sm text-balance',\n className,\n )}\n render={\n <motion.div\n key=\"tooltip-content\"\n initial={{ opacity: 0, scale: 0.5, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.5, ...initialPosition }}\n transition={transition}\n {...motionProps}\n />\n }\n >\n {children}\n\n {arrow && (\n <TooltipPrimitive.Arrow\n data-slot=\"tooltip-content-arrow\"\n className=\"bg-primary fill-primary z-50 size-2.5 data-[side='bottom']:-top-[4px] data-[side='right']:-left-[4px] data-[side='left']:-right-[4px] data-[side='inline-start']:-right-[4px] data-[side='inline-end']:-left-[4px] rotate-45 rounded-[2px]\"\n />\n )}\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n TooltipProvider,\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n useTooltip,\n type TooltipContextType,\n type TooltipProviderProps,\n type TooltipProps,\n type TooltipTriggerProps,\n type TooltipContentProps,\n type Side,\n type Align,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/base/tooltip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-tooltip';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-tooltip',
},
'copy-button': {
name: 'copy-button',
description: 'A button with a copy to clipboard animation.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react', 'class-variance-authority'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/copy/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/copy.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { AnimatePresence, HTMLMotionProps, motion } from 'motion/react';\nimport { CheckIcon, CopyIcon } from 'lucide-react';\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 cursor-pointer rounded-md transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none 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:\n 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',\n muted: 'bg-muted text-muted-foreground',\n destructive:\n 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n },\n size: {\n default: 'size-8 rounded-lg [&_svg]:size-4',\n sm: 'size-6 [&_svg]:size-3',\n md: 'size-10 rounded-lg [&_svg]:size-5',\n lg: 'size-12 rounded-xl [&_svg]:size-6',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype CopyButtonProps = Omit<HTMLMotionProps<'button'>, 'children' | 'onCopy'> &\n VariantProps<typeof buttonVariants> & {\n content?: string;\n delay?: number;\n onCopy?: (content: string) => void;\n isCopied?: boolean;\n onCopyChange?: (isCopied: boolean) => void;\n };\n\nfunction CopyButton({\n content,\n className,\n size,\n variant,\n delay = 3000,\n onClick,\n onCopy,\n isCopied,\n onCopyChange,\n ...props\n}: CopyButtonProps) {\n const [localIsCopied, setLocalIsCopied] = React.useState(isCopied ?? false);\n const Icon = localIsCopied ? CheckIcon : CopyIcon;\n\n React.useEffect(() => {\n setLocalIsCopied(isCopied ?? false);\n }, [isCopied]);\n\n const handleIsCopied = React.useCallback(\n (isCopied: boolean) => {\n setLocalIsCopied(isCopied);\n onCopyChange?.(isCopied);\n },\n [onCopyChange],\n );\n\n const handleCopy = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (isCopied) return;\n if (content) {\n navigator.clipboard\n .writeText(content)\n .then(() => {\n handleIsCopied(true);\n setTimeout(() => handleIsCopied(false), delay);\n onCopy?.(content);\n })\n .catch((error) => {\n console.error('Error copying command', error);\n });\n }\n onClick?.(e);\n },\n [isCopied, content, delay, onClick, onCopy, handleIsCopied],\n );\n\n return (\n <motion.button\n data-slot=\"copy-button\"\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n className={cn(buttonVariants({ variant, size }), className)}\n onClick={handleCopy}\n {...props}\n >\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={localIsCopied ? 'check' : 'copy'}\n data-slot=\"copy-button-icon\"\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n exit={{ scale: 0 }}\n transition={{ duration: 0.15 }}\n >\n <Icon />\n </motion.span>\n </AnimatePresence>\n </motion.button>\n );\n}\n\nexport { CopyButton, buttonVariants, type CopyButtonProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/copy/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'copy-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/copy-button',
},
'flip-button': {
name: 'flip-button',
description:
'A clickable button featuring a smooth flipping animation triggered on hover.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/flip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/flip.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n type HTMLMotionProps,\n type Transition,\n type Variant,\n motion,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype FlipDirection = 'top' | 'bottom' | 'left' | 'right';\n\ntype FlipButtonProps = HTMLMotionProps<'button'> & {\n frontText: string;\n backText: string;\n transition?: Transition;\n frontClassName?: string;\n backClassName?: string;\n from?: FlipDirection;\n};\n\nconst DEFAULT_SPAN_CLASS_NAME =\n 'absolute inset-0 flex items-center justify-center rounded-lg';\n\nfunction FlipButton({\n frontText,\n backText,\n transition = { type: 'spring', stiffness: 280, damping: 20 },\n className,\n frontClassName,\n backClassName,\n from = 'top',\n ...props\n}: FlipButtonProps) {\n const isVertical = from === 'top' || from === 'bottom';\n const rotateAxis = isVertical ? 'rotateX' : 'rotateY';\n\n const frontOffset = from === 'top' || from === 'left' ? '50%' : '-50%';\n const backOffset = from === 'top' || from === 'left' ? '-50%' : '50%';\n\n const buildVariant = (\n opacity: number,\n rotation: number,\n offset: string | null = null,\n ): Variant => ({\n opacity,\n [rotateAxis]: rotation,\n ...(isVertical && offset !== null ? { y: offset } : {}),\n ...(!isVertical && offset !== null ? { x: offset } : {}),\n });\n\n const frontVariants = {\n initial: buildVariant(1, 0, '0%'),\n hover: buildVariant(0, 90, frontOffset),\n };\n\n const backVariants = {\n initial: buildVariant(0, 90, backOffset),\n hover: buildVariant(1, 0, '0%'),\n };\n\n return (\n <motion.button\n data-slot=\"flip-button\"\n initial=\"initial\"\n whileHover=\"hover\"\n whileTap={{ scale: 0.95 }}\n className={cn(\n 'relative inline-block h-10 px-4 py-2 text-sm font-medium cursor-pointer perspective-[1000px] focus:outline-none',\n className,\n )}\n {...props}\n >\n <motion.span\n data-slot=\"flip-button-front\"\n variants={frontVariants}\n transition={transition}\n className={cn(\n DEFAULT_SPAN_CLASS_NAME,\n 'bg-muted text-black dark:text-white',\n frontClassName,\n )}\n >\n {frontText}\n </motion.span>\n <motion.span\n data-slot=\"flip-button-back\"\n variants={backVariants}\n transition={transition}\n className={cn(\n DEFAULT_SPAN_CLASS_NAME,\n 'bg-primary text-primary-foreground',\n backClassName,\n )}\n >\n {backText}\n </motion.span>\n <span className=\"invisible\">{frontText}</span>\n </motion.button>\n );\n}\n\nexport { FlipButton, type FlipButtonProps, type FlipDirection };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/flip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'flip-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/flip-button',
},
'github-stars-button': {
name: 'github-stars-button',
description:
'A clickable button that links to a GitHub repository and displays the number of stars.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/sliding-number'],
files: [
{
path: 'registry/buttons/github-stars/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/github-stars.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Star } from 'lucide-react';\nimport {\n motion,\n AnimatePresence,\n useMotionValue,\n useSpring,\n useInView,\n type HTMLMotionProps,\n type SpringOptions,\n type UseInViewOptions,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport { SlidingNumber } from '@/components/animate-ui/text/sliding-number';\n\ntype FormatNumberResult = { number: string[]; unit: string };\n\nfunction formatNumber(num: number, formatted: boolean): FormatNumberResult {\n if (formatted) {\n if (num < 1000) {\n return { number: [num.toString()], unit: '' };\n }\n const units = ['k', 'M', 'B', 'T'];\n let unitIndex = 0;\n let n = num;\n while (n >= 1000 && unitIndex < units.length) {\n n /= 1000;\n unitIndex++;\n }\n const finalNumber = Math.floor(n).toString();\n return { number: [finalNumber], unit: units[unitIndex - 1] ?? '' };\n } else {\n return { number: num.toLocaleString('en-US').split(','), unit: '' };\n }\n}\n\ntype GitHubStarsButtonProps = HTMLMotionProps<'a'> & {\n username: string;\n repo: string;\n transition?: SpringOptions;\n formatted?: boolean;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n};\n\nfunction GitHubStarsButton({\n ref,\n username,\n repo,\n transition = { stiffness: 90, damping: 50 },\n formatted = false,\n inView = false,\n inViewOnce = true,\n inViewMargin = '0px',\n className,\n ...props\n}: GitHubStarsButtonProps) {\n const motionVal = useMotionValue(0);\n const springVal = useSpring(motionVal, transition);\n const motionNumberRef = React.useRef(0);\n const isCompletedRef = React.useRef(false);\n const [, forceRender] = React.useReducer((x) => x + 1, 0);\n const [stars, setStars] = React.useState(0);\n const [isCompleted, setIsCompleted] = React.useState(false);\n const [displayParticles, setDisplayParticles] = React.useState(false);\n const [isLoading, setIsLoading] = React.useState(true);\n\n const repoUrl = React.useMemo(\n () => `https://github.com/${username}/${repo}`,\n [username, repo],\n );\n\n React.useEffect(() => {\n fetch(`https://api.github.com/repos/${username}/${repo}`)\n .then((response) => response.json())\n .then((data) => {\n if (data && typeof data.stargazers_count === 'number') {\n setStars(data.stargazers_count);\n }\n })\n .catch(console.error)\n .finally(() => setIsLoading(false));\n }, [username, repo]);\n\n const handleDisplayParticles = React.useCallback(() => {\n setDisplayParticles(true);\n setTimeout(() => setDisplayParticles(false), 1500);\n }, []);\n\n const localRef = React.useRef<HTMLAnchorElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLAnchorElement);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isComponentInView = !inView || inViewResult;\n\n React.useEffect(() => {\n const unsubscribe = springVal.on('change', (latest: number) => {\n const newValue = Math.round(latest);\n if (motionNumberRef.current !== newValue) {\n motionNumberRef.current = newValue;\n forceRender();\n }\n if (stars !== 0 && newValue >= stars && !isCompletedRef.current) {\n isCompletedRef.current = true;\n setIsCompleted(true);\n handleDisplayParticles();\n }\n });\n return () => unsubscribe();\n }, [springVal, stars, handleDisplayParticles]);\n\n React.useEffect(() => {\n if (stars > 0 && isComponentInView) motionVal.set(stars);\n }, [motionVal, stars, isComponentInView]);\n\n const fillPercentage = Math.min(100, (motionNumberRef.current / stars) * 100);\n const formattedResult = formatNumber(motionNumberRef.current, formatted);\n const ghostFormattedNumber = formatNumber(stars, formatted);\n\n const renderNumberSegments = (\n segments: string[],\n unit: string,\n isGhost: boolean,\n ) => (\n <span\n className={cn(\n 'flex items-center gap-px',\n isGhost ? 'invisible' : 'absolute top-0 left-0',\n )}\n >\n {segments.map((segment, index) => (\n <React.Fragment key={index}>\n {Array.from(segment).map((digit, digitIndex) => (\n <SlidingNumber key={`${index}-${digitIndex}`} number={+digit} />\n ))}\n </React.Fragment>\n ))}\n\n {formatted && unit && <span className=\"leading-[1]\">{unit}</span>}\n </span>\n );\n\n const handleClick = React.useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n e.preventDefault();\n handleDisplayParticles();\n setTimeout(() => window.open(repoUrl, '_blank'), 500);\n },\n [handleDisplayParticles, repoUrl],\n );\n\n if (isLoading) return null;\n\n return (\n <motion.a\n ref={localRef}\n href={repoUrl}\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n onClick={handleClick}\n className={cn(\n \"flex items-center gap-2 text-sm bg-primary text-primary-foreground rounded-lg px-4 py-2 h-10 has-[>svg]:px-3 cursor-pointer whitespace-nowrap font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-[18px] 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 className,\n )}\n {...props}\n >\n <svg role=\"img\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n </svg>\n <span>GitHub Stars</span>\n <div className=\"relative inline-flex size-[18px] shrink-0\">\n <Star\n className=\"fill-muted-foreground text-muted-foreground\"\n size={18}\n aria-hidden=\"true\"\n />\n <Star\n className=\"absolute top-0 left-0 text-yellow-500 fill-yellow-500\"\n aria-hidden=\"true\"\n style={{\n clipPath: `inset(${100 - (isCompleted ? fillPercentage : fillPercentage - 10)}% 0 0 0)`,\n }}\n />\n <AnimatePresence>\n {displayParticles && (\n <>\n <motion.div\n className=\"absolute inset-0 rounded-full\"\n style={{\n background:\n 'radial-gradient(circle, rgba(255,215,0,0.4) 0%, rgba(255,215,0,0) 70%)',\n }}\n initial={{ scale: 1.2, opacity: 0 }}\n animate={{ scale: [1.2, 1.8, 1.2], opacity: [0, 0.3, 0] }}\n transition={{ duration: 1.2, ease: 'easeInOut' }}\n />\n <motion.div\n className=\"absolute inset-0 rounded-full\"\n style={{ boxShadow: '0 0 10px 2px rgba(255,215,0,0.6)' }}\n initial={{ scale: 1, opacity: 0 }}\n animate={{ scale: [1, 1.5], opacity: [0.8, 0] }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n />\n {[...Array(6)].map((_, i) => (\n <motion.div\n key={i}\n className=\"absolute w-1 h-1 rounded-full bg-yellow-500\"\n initial={{ x: '50%', y: '50%', scale: 0, opacity: 0 }}\n animate={{\n x: `calc(50% + ${Math.cos((i * Math.PI) / 3) * 30}px)`,\n y: `calc(50% + ${Math.sin((i * Math.PI) / 3) * 30}px)`,\n scale: [0, 1, 0],\n opacity: [0, 1, 0],\n }}\n transition={{\n duration: 0.8,\n delay: i * 0.05,\n ease: 'easeOut',\n }}\n />\n ))}\n </>\n )}\n </AnimatePresence>\n </div>\n <span className=\"relative inline-flex\">\n {renderNumberSegments(\n ghostFormattedNumber.number,\n ghostFormattedNumber.unit,\n true,\n )}\n {renderNumberSegments(\n formattedResult.number,\n formattedResult.unit,\n false,\n )}\n </span>\n </motion.a>\n );\n}\n\nexport { GitHubStarsButton, type GitHubStarsButtonProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/github-stars/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'github-stars-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/github-stars-button',
},
'icon-button': {
name: 'icon-button',
description: 'An icon button that displays particles when clicked.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/icon/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/icon.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n AnimatePresence,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\nconst sizes = {\n default: 'size-8 [&_svg]:size-5',\n sm: 'size-6 [&_svg]:size-4',\n md: 'size-10 [&_svg]:size-6',\n lg: 'size-12 [&_svg]:size-7',\n};\n\ntype IconButtonProps = Omit<HTMLMotionProps<'button'>, 'color'> & {\n icon: React.ElementType;\n active?: boolean;\n className?: string;\n animate?: boolean;\n size?: keyof typeof sizes;\n color?: [number, number, number];\n transition?: Transition;\n};\n\nfunction IconButton({\n icon: Icon,\n className,\n active = false,\n animate = true,\n size = 'default',\n color = [59, 130, 246],\n transition = { type: 'spring', stiffness: 300, damping: 15 },\n ...props\n}: IconButtonProps) {\n return (\n <motion.button\n data-slot=\"icon-button\"\n className={cn(\n `group/icon-button cursor-pointer relative inline-flex size-10 shrink-0 rounded-full hover:bg-[var(--icon-button-color)]/10 active:bg-[var(--icon-button-color)]/20 text-[var(--icon-button-color)]`,\n sizes[size],\n className,\n )}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n style={\n {\n '--icon-button-color': `rgb(${color[0]}, ${color[1]}, ${color[2]})`,\n } as React.CSSProperties\n }\n {...props}\n >\n <motion.div\n className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 stroke-muted-foreground group-hover/icon-button:stroke-[var(--icon-button-color)]\"\n aria-hidden=\"true\"\n >\n <Icon\n className={\n active ? 'fill-[var(--icon-button-color)]' : 'fill-transparent'\n }\n />\n </motion.div>\n\n <AnimatePresence mode=\"wait\">\n {active && (\n <motion.div\n className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-[var(--icon-button-color)] fill-[var(--icon-button-color)]\"\n aria-hidden=\"true\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0 }}\n transition={transition}\n >\n <Icon />\n </motion.div>\n )}\n </AnimatePresence>\n\n <AnimatePresence>\n {animate && active && (\n <>\n <motion.div\n className=\"absolute inset-0 z-10 rounded-full \"\n style={{\n background: `radial-gradient(circle, rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.4) 0%, rgba(${color[0]}, ${color[1]}, ${color[2]}, 0) 70%)`,\n }}\n initial={{ scale: 1.2, opacity: 0 }}\n animate={{ scale: [1.2, 1.8, 1.2], opacity: [0, 0.3, 0] }}\n transition={{ duration: 1.2, ease: 'easeInOut' }}\n />\n <motion.div\n className=\"absolute inset-0 z-10 rounded-full\"\n style={{\n boxShadow: `0 0 10px 2px rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.6)`,\n }}\n initial={{ scale: 1, opacity: 0 }}\n animate={{ scale: [1, 1.5], opacity: [0.8, 0] }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n />\n {[...Array(6)].map((_, i) => (\n <motion.div\n key={i}\n className=\"absolute w-1 h-1 rounded-full bg-[var(--icon-button-color)]\"\n initial={{ x: '50%', y: '50%', scale: 0, opacity: 0 }}\n animate={{\n x: `calc(50% + ${Math.cos((i * Math.PI) / 3) * 30}px)`,\n y: `calc(50% + ${Math.sin((i * Math.PI) / 3) * 30}px)`,\n scale: [0, 1, 0],\n opacity: [0, 1, 0],\n }}\n transition={{ duration: 0.8, delay: i * 0.05, ease: 'easeOut' }}\n />\n ))}\n </>\n )}\n </AnimatePresence>\n </motion.button>\n );\n}\n\nexport { IconButton, sizes, type IconButtonProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/icon/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'icon-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/icon-button',
},
'input-button': {
name: 'input-button',
description: 'A button that shows an input when clicked.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/input/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/input.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n AnimatePresence,\n HTMLMotionProps,\n motion,\n Transition,\n} from 'motion/react';\nimport { ArrowRight } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ntype InputButtonContextType = {\n showInput: boolean;\n setShowInput: React.Dispatch<React.SetStateAction<boolean>>;\n transition: Transition;\n id: string;\n};\nconst InputButtonContext = React.createContext<\n InputButtonContextType | undefined\n>(undefined);\n\nconst useInputButton = (): InputButtonContextType => {\n const context = React.useContext(InputButtonContext);\n if (!context) {\n throw new Error('useInputButton must be used within a InputButton');\n }\n return context;\n};\n\ntype InputButtonProviderProps = React.ComponentProps<'div'> &\n Partial<InputButtonContextType>;\n\nfunction InputButtonProvider({\n className,\n transition = { type: 'spring', stiffness: 300, damping: 20 },\n showInput,\n setShowInput,\n id,\n ...props\n}: InputButtonProviderProps) {\n const localId = React.useId();\n const [localShowInput, setLocalShowInput] = React.useState(false);\n\n return (\n <InputButtonContext.Provider\n value={{\n showInput: showInput ?? localShowInput,\n setShowInput: setShowInput ?? setLocalShowInput,\n transition,\n id: id ?? localId,\n }}\n >\n <div\n data-slot=\"input-button-provider\"\n className={cn(\n 'relative w-fit flex items-center justify-center h-10',\n (showInput || localShowInput) && 'w-full max-w-[400px]',\n className,\n )}\n {...props}\n />\n </InputButtonContext.Provider>\n );\n}\n\ntype InputButtonProps = HTMLMotionProps<'div'>;\n\nfunction InputButton({ className, ...props }: InputButtonProps) {\n return (\n <motion.div\n data-slot=\"input-button\"\n className={cn('flex size-full', className)}\n {...props}\n />\n );\n}\n\ntype InputButtonActionProps = HTMLMotionProps<'button'>;\n\nfunction InputButtonAction({ className, ...props }: InputButtonActionProps) {\n const { transition, setShowInput, id } = useInputButton();\n\n return (\n <motion.button\n data-slot=\"input-button-action\"\n className={cn(\n 'bg-background text-sm whitespace-nowrap disabled:pointer-events-none disabled:opacity-50 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 rounded-full border text-background-foreground cursor-pointer pl-4 pr-12 size-full font-medium',\n className,\n )}\n layoutId={`input-button-action-${id}`}\n transition={transition}\n onClick={() => setShowInput((prev) => !prev)}\n {...props}\n />\n );\n}\n\ntype InputButtonSubmitProps = HTMLMotionProps<'button'> & {\n icon?: React.ElementType;\n};\n\nfunction InputButtonSubmit({\n className,\n children,\n icon: Icon = ArrowRight,\n ...props\n}: InputButtonSubmitProps) {\n const { transition, showInput, setShowInput, id } = useInputButton();\n\n return (\n <motion.button\n data-slot=\"input-button-submit\"\n layoutId={`input-button-submit-${id}`}\n transition={transition}\n className={cn(\n \"z-[1] [&_svg:not([class*='size-'])]:size-4 cursor-pointer disabled:pointer-events-none disabled:opacity-50 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 whitespace-nowrap bg-primary hover:bg-primary/90 transition-colors text-primary-foreground rounded-full text-sm flex items-center justify-center font-medium absolute inset-y-1 right-1\",\n showInput ? 'px-4' : 'aspect-square',\n className,\n )}\n onClick={() => setShowInput((prev) => !prev)}\n {...props}\n >\n {showInput ? (\n <motion.span\n key=\"show-button\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.2 }}\n >\n {children}\n </motion.span>\n ) : (\n <motion.span\n key=\"show-icon\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.2 }}\n >\n <Icon className=\"size-4\" />\n </motion.span>\n )}\n </motion.button>\n );\n}\n\ntype InputButtonInputProps = React.ComponentProps<'input'>;\n\nfunction InputButtonInput({ className, ...props }: InputButtonInputProps) {\n const { transition, showInput, id } = useInputButton();\n\n return (\n <AnimatePresence>\n {showInput && (\n <div className=\"absolute inset-0 size-full flex items-center justify-center\">\n <motion.div\n layoutId={`input-button-input-${id}`}\n className=\"size-full flex items-center bg-background rounded-full relative\"\n transition={transition}\n >\n <input\n data-slot=\"input-button-input\"\n className={cn(\n 'size-full selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground inset-0 pl-4 focus-visible:border-ring border focus-visible:ring-ring/50 focus-visible:ring-[3px] pr-32 py-2 text-sm bg-background rounded-full focus:outline-none absolute shrink-0 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive disabled:pointer-events-none disabled:cursor-not-allowed',\n className,\n )}\n {...props}\n />\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n InputButton,\n InputButtonProvider,\n InputButtonAction,\n InputButtonSubmit,\n InputButtonInput,\n useInputButton,\n type InputButtonProps,\n type InputButtonProviderProps,\n type InputButtonActionProps,\n type InputButtonSubmitProps,\n type InputButtonInputProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/input/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'input-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/input-button',
},
'liquid-button': {
name: 'liquid-button',
description:
'A clickable button featuring a dynamic, fluid-like animation effect upon hover, creating an engaging, liquid-inspired interaction.',
type: 'registry:ui',
dependencies: ['motion', 'class-variance-authority'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/liquid/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/liquid.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type HTMLMotionProps } from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst buttonVariants = cva(\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium cursor-pointer overflow-hidden 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 [background:_linear-gradient(var(--liquid-button-color)_0_0)_no-repeat_calc(200%-var(--liquid-button-fill,0%))_100%/200%_var(--liquid-button-fill,0.2em)] hover:[--liquid-button-fill:100%] hover:[--liquid-button-delay:0.3s] [transition:_background_0.3s_var(--liquid-button-delay,0s),_color_0.3s_var(--liquid-button-delay,0s),_background-position_0.3s_calc(0.3s_-_var(--liquid-button-delay,0s))] focus:outline-none\",\n {\n variants: {\n variant: {\n default:\n 'text-primary hover:text-primary-foreground !bg-muted [--liquid-button-color:var(--primary)]',\n outline:\n 'border !bg-background dark:!bg-input/30 dark:border-input [--liquid-button-color:var(--primary)]',\n secondary:\n 'text-secondary hover:text-secondary-foreground !bg-muted [--liquid-button-color:var(--secondary)]',\n },\n size: {\n default: 'h-10 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-9 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-12 rounded-xl px-8 has-[>svg]:px-6',\n icon: 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype LiquidButtonProps = HTMLMotionProps<'button'> &\n VariantProps<typeof buttonVariants>;\n\nfunction LiquidButton({\n className,\n variant,\n size,\n ...props\n}: LiquidButtonProps) {\n return (\n <motion.button\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { LiquidButton, type LiquidButtonProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/liquid/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'liquid-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/liquid-button',
},
'ripple-button': {
name: 'ripple-button',
description:
'A clickable button featuring a ripple animation effect on click.',
type: 'registry:ui',
dependencies: ['motion', 'class-variance-authority'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/buttons/ripple/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/buttons/ripple.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { type HTMLMotionProps, motion, type Transition } from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst buttonVariants = cva(\n \"relative overflow-hidden cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg 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-primary text-primary-foreground hover:bg-primary/90',\n destructive:\n 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',\n outline:\n 'border bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost:\n 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n },\n size: {\n default: 'h-10 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-9 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-11 px-8 has-[>svg]:px-6',\n icon: 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nconst rippleVariants = cva('absolute rounded-full size-5 pointer-events-none', {\n variants: {\n variant: {\n default: 'bg-primary-foreground',\n destructive: 'bg-destructive',\n outline: 'bg-input',\n secondary: 'bg-secondary',\n ghost: 'bg-accent',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n});\n\ntype Ripple = {\n id: number;\n x: number;\n y: number;\n};\n\ntype RippleButtonProps = HTMLMotionProps<'button'> & {\n children: React.ReactNode;\n rippleClassName?: string;\n scale?: number;\n transition?: Transition;\n} & VariantProps<typeof buttonVariants>;\n\nfunction RippleButton({\n ref,\n children,\n onClick,\n className,\n rippleClassName,\n variant,\n size,\n scale = 10,\n transition = { duration: 0.6, ease: 'easeOut' },\n ...props\n}: RippleButtonProps) {\n const [ripples, setRipples] = React.useState<Ripple[]>([]);\n const buttonRef = React.useRef<HTMLButtonElement>(null);\n React.useImperativeHandle(ref, () => buttonRef.current as HTMLButtonElement);\n\n const createRipple = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n const button = buttonRef.current;\n if (!button) return;\n\n const rect = button.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n const newRipple: Ripple = {\n id: Date.now(),\n x,\n y,\n };\n\n setRipples((prev) => [...prev, newRipple]);\n\n setTimeout(() => {\n setRipples((prev) => prev.filter((r) => r.id !== newRipple.id));\n }, 600);\n },\n [],\n );\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n createRipple(event);\n if (onClick) {\n onClick(event);\n }\n },\n [createRipple, onClick],\n );\n\n return (\n <motion.button\n ref={buttonRef}\n data-slot=\"ripple-button\"\n onClick={handleClick}\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n >\n {children}\n {ripples.map((ripple) => (\n <motion.span\n key={ripple.id}\n initial={{ scale: 0, opacity: 0.5 }}\n animate={{ scale, opacity: 0 }}\n transition={transition}\n className={cn(\n rippleVariants({ variant, className: rippleClassName }),\n )}\n style={{\n top: ripple.y - 10,\n left: ripple.x - 10,\n }}\n />\n ))}\n </motion.button>\n );\n}\n\nexport { RippleButton, type RippleButtonProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/buttons/ripple/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'ripple-button';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/ripple-button',
},
'avatar-group': {
name: 'avatar-group',
description:
'An animated avatar group that displays overlapping user images and smoothly shifts each avatar forward on hover to highlight it.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/tooltip'],
files: [
{
path: 'registry/components/avatar-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/avatar-group.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n type TooltipProps,\n type TooltipContentProps,\n} from '@/components/animate-ui/components/tooltip';\n\ntype AvatarProps = TooltipProps & {\n children: React.ReactNode;\n zIndex: number;\n transition: Transition;\n translate: string | number;\n};\n\nfunction AvatarContainer({\n children,\n zIndex,\n transition,\n translate,\n ...props\n}: AvatarProps) {\n return (\n <Tooltip {...props}>\n <TooltipTrigger>\n <motion.div\n data-slot=\"avatar-container\"\n initial=\"initial\"\n whileHover=\"hover\"\n whileTap=\"hover\"\n className=\"relative\"\n style={{ zIndex }}\n >\n <motion.div\n variants={{\n initial: { y: 0 },\n hover: { y: translate },\n }}\n transition={transition}\n >\n {children}\n </motion.div>\n </motion.div>\n </TooltipTrigger>\n </Tooltip>\n );\n}\n\ntype AvatarGroupTooltipProps = TooltipContentProps;\n\nfunction AvatarGroupTooltip(props: AvatarGroupTooltipProps) {\n return <TooltipContent {...props} />;\n}\n\ntype AvatarGroupProps = Omit<React.ComponentProps<'div'>, 'translate'> & {\n children: React.ReactElement[];\n transition?: Transition;\n invertOverlap?: boolean;\n translate?: string | number;\n tooltipProps?: Omit<TooltipProps, 'children'>;\n};\n\nfunction AvatarGroup({\n ref,\n children,\n className,\n transition = { type: 'spring', stiffness: 300, damping: 17 },\n invertOverlap = false,\n translate = '-30%',\n tooltipProps = { side: 'top', sideOffset: 24 },\n ...props\n}: AvatarGroupProps) {\n return (\n <TooltipProvider openDelay={0} closeDelay={0}>\n <div\n ref={ref}\n data-slot=\"avatar-group\"\n className={cn('flex flex-row -space-x-2 items-center h-8', className)}\n {...props}\n >\n {children?.map((child, index) => (\n <AvatarContainer\n key={index}\n zIndex={\n invertOverlap ? React.Children.count(children) - index : index\n }\n transition={transition}\n translate={translate}\n {...tooltipProps}\n >\n {child}\n </AvatarContainer>\n ))}\n </div>\n </TooltipProvider>\n );\n}\n\nexport {\n AvatarGroup,\n AvatarGroupTooltip,\n type AvatarGroupProps,\n type AvatarGroupTooltipProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/avatar-group/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group',
},
'avatar-group-mask': {
name: 'avatar-group-mask',
description:
'An animated avatar group that displays overlapping user images with a mask effect and smoothly shifts each avatar forward on hover to highlight it.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/tooltip'],
files: [
{
path: 'registry/components/avatar-group-mask/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/avatar-group-mask.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n type TooltipProps,\n type TooltipContentProps,\n} from '@/components/animate-ui/components/tooltip';\n\ntype Align = 'start' | 'center' | 'end';\n\ntype AvatarProps = TooltipProps & {\n children: React.ReactNode;\n align?: Align;\n invertOverlap?: boolean;\n};\n\nfunction AvatarContainer({\n children,\n align,\n invertOverlap,\n ...props\n}: AvatarProps) {\n return (\n <Tooltip {...props}>\n <TooltipTrigger>\n <span\n data-slot=\"avatar-container\"\n className={cn(\n align === 'start'\n ? 'items-start'\n : align === 'center'\n ? 'items-center'\n : 'items-end',\n 'relative grid w-[var(--avatar-size)] aspect-[1/calc(1+var(--avatar-mask-ratio))]',\n '[&_[data-slot=avatar]]:size-[var(--avatar-size)] [&_[data-slot=avatar]]:rounded-full',\n invertOverlap\n ? cn(\n '[&:not(:first-of-type)]:[--circle:calc(((var(--avatar-border)*2)+var(--avatar-size))*0.5)]',\n '[&:not(:first-of-type)]:mask-[radial-gradient(var(--circle)_var(--circle)_at_calc(var(--circle)-var(--avatar-column-size)-var(--avatar-border))_50%_,#0000_calc(var(--circle)-0.5px),#fff_var(--circle))]',\n '[&:not(:first-of-type)]:mask-size-[100%_100%]',\n '[&:not(:first-of-type)]:mask-position-[0_calc(var(--avatar-size)*var(--avatar-mask-base))]',\n '[&:not(:first-of-type)]:transition-[mask-position] [&:not(:first-of-type)]:duration-300 [&:not(:first-of-type)]:ease-in-out',\n '[&:hover+&]:mask-position-[0_calc(var(--avatar-size)_-_calc(var(--avatar-size)*(var(--avatar-mask-factor)+var(--avatar-mask-offset))))]',\n )\n : cn(\n '[&:not(:last-of-type)]:[--circle:calc(((var(--avatar-border)*2)+var(--avatar-size))*0.5)]',\n '[&:not(:last-of-type)]:mask-[radial-gradient(var(--circle)_var(--circle)_at_calc(var(--circle)+var(--avatar-column-size)-var(--avatar-border))_50%_,#0000_calc(var(--circle)-0.5px),#fff_var(--circle))]',\n '[&:not(:last-of-type)]:mask-size-[100%_100%]',\n '[&:not(:last-of-type)]:mask-position-[0_calc(var(--avatar-size)*var(--avatar-mask-base))]',\n '[&:not(:last-of-type)]:transition-[mask-position] [&:not(:last-of-type)]:duration-300 [&:not(:last-of-type)]:ease-in-out',\n '[&:has(+&:hover)]:mask-position-[0_calc(var(--avatar-size)_-_calc(var(--avatar-size)*(var(--avatar-mask-factor)+var(--avatar-mask-offset))))]',\n ),\n '[&>span]:transition-[translate] [&>span]:duration-300 [&>span]:ease-in-out',\n '[&:hover_span:first-of-type]:translate-y-[var(--avatar-translate-pct)]',\n )}\n >\n {children}\n </span>\n </TooltipTrigger>\n </Tooltip>\n );\n}\n\ntype AvatarGroupTooltipProps = TooltipContentProps;\n\nfunction AvatarGroupTooltip(props: AvatarGroupTooltipProps) {\n return <TooltipContent {...props} />;\n}\n\ntype AvatarGroupProps = Omit<React.ComponentProps<'div'>, 'translate'> & {\n children: React.ReactElement[];\n invertOverlap?: boolean;\n translate?: number;\n size?: string | number;\n border?: string | number;\n columnSize?: string | number;\n align?: Align;\n tooltipProps?: Omit<TooltipProps, 'children'>;\n};\n\nfunction AvatarGroup({\n ref,\n children,\n className,\n invertOverlap = false,\n size = '43px',\n border = '3px',\n columnSize = '37px',\n align = 'end',\n translate = -30,\n tooltipProps = { side: 'top', sideOffset: 12 },\n ...props\n}: AvatarGroupProps) {\n const maskRatio = Math.abs(translate / 100);\n const alignOffset =\n align === 'start' ? 0 : align === 'center' ? maskRatio / 2 : maskRatio;\n const maskBase = alignOffset - maskRatio / 2;\n const maskFactor = 1 - alignOffset + maskRatio / 2;\n\n return (\n <TooltipProvider openDelay={0} closeDelay={0}>\n <div\n ref={ref}\n data-slot=\"avatar-group\"\n style={\n {\n '--avatar-size': size,\n '--avatar-border': border,\n '--avatar-column-size': columnSize,\n '--avatar-translate-pct': `${translate}%`,\n '--avatar-mask-offset': -(translate / 100),\n '--avatar-mask-ratio': maskRatio,\n '--avatar-mask-base': maskBase,\n '--avatar-mask-factor': maskFactor,\n '--avatar-columns': React.Children.count(children),\n } as React.CSSProperties\n }\n className=\"h-[var(--avatar-size)] w-[calc(var(--avatar-column-size)*(var(--avatar-columns))+calc(var(--avatar-size)-var(--avatar-column-size)))]\"\n >\n <span\n className={cn(\n 'grid h-[var(--avatar-size)] grid-cols-[repeat(var(--avatar-columns),var(--avatar-column-size))]',\n align === 'start'\n ? 'content-start'\n : align === 'center'\n ? 'content-center'\n : 'content-end',\n className,\n )}\n {...props}\n >\n {children?.map((child, index) => (\n <AvatarContainer\n key={index}\n invertOverlap={invertOverlap}\n {...tooltipProps}\n align={align}\n >\n {child}\n </AvatarContainer>\n ))}\n </span>\n </div>\n </TooltipProvider>\n );\n}\n\nexport {\n AvatarGroup,\n AvatarGroupTooltip,\n type AvatarGroupProps,\n type AvatarGroupTooltipProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/avatar-group-mask/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group-mask';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group-mask',
},
'code-editor': {
name: 'code-editor',
description:
'A code editor component featuring syntax highlighting and animation.',
type: 'registry:ui',
dependencies: ['motion', 'shiki'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/copy-button'],
files: [
{
path: 'registry/components/code-editor/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/code-editor.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { useInView, type UseInViewOptions } from 'motion/react';\nimport { useTheme } from 'next-themes';\n\nimport { cn } from '@/lib/utils';\nimport { CopyButton } from '@/components/animate-ui/buttons/copy';\n\ntype CodeEditorProps = Omit<React.ComponentProps<'div'>, 'onCopy'> & {\n children: string;\n lang: string;\n themes?: {\n light: string;\n dark: string;\n };\n duration?: number;\n delay?: number;\n header?: boolean;\n dots?: boolean;\n icon?: React.ReactNode;\n cursor?: boolean;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n copyButton?: boolean;\n writing?: boolean;\n title?: string;\n onDone?: () => void;\n onCopy?: (content: string) => void;\n};\n\nfunction CodeEditor({\n children: code,\n lang,\n themes = {\n light: 'github-light',\n dark: 'github-dark',\n },\n duration = 5,\n delay = 0,\n className,\n header = true,\n dots = true,\n icon,\n cursor = false,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n copyButton = false,\n writing = true,\n title,\n onDone,\n onCopy,\n ...props\n}: CodeEditorProps) {\n const { resolvedTheme } = useTheme();\n\n const editorRef = React.useRef<HTMLDivElement>(null);\n const [visibleCode, setVisibleCode] = React.useState('');\n const [highlightedCode, setHighlightedCode] = React.useState('');\n const [isDone, setIsDone] = React.useState(false);\n\n const inViewResult = useInView(editorRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n React.useEffect(() => {\n if (!visibleCode.length || !isInView) return;\n\n const loadHighlightedCode = async () => {\n try {\n const { codeToHtml } = await import('shiki');\n\n const highlighted = await codeToHtml(visibleCode, {\n lang,\n themes: {\n light: themes.light,\n dark: themes.dark,\n },\n defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light',\n });\n\n setHighlightedCode(highlighted);\n } catch (e) {\n console.error(`Language \"${lang}\" could not be loaded.`, e);\n }\n };\n\n loadHighlightedCode();\n }, [\n lang,\n themes,\n writing,\n isInView,\n duration,\n delay,\n visibleCode,\n resolvedTheme,\n ]);\n\n React.useEffect(() => {\n if (!writing) {\n setVisibleCode(code);\n onDone?.();\n return;\n }\n\n if (!code.length || !isInView) return;\n\n const characters = Array.from(code);\n let index = 0;\n const totalDuration = duration * 1000;\n const interval = totalDuration / characters.length;\n let intervalId: NodeJS.Timeout;\n\n const timeout = setTimeout(() => {\n intervalId = setInterval(() => {\n if (index < characters.length) {\n setVisibleCode((prev) => {\n const currentIndex = index;\n index += 1;\n return prev + characters[currentIndex];\n });\n editorRef.current?.scrollTo({\n top: editorRef.current?.scrollHeight,\n behavior: 'smooth',\n });\n } else {\n clearInterval(intervalId);\n setIsDone(true);\n onDone?.();\n }\n }, interval);\n }, delay * 1000);\n\n return () => {\n clearTimeout(timeout);\n clearInterval(intervalId);\n };\n }, [code, duration, delay, isInView, writing, onDone]);\n\n return (\n <div\n data-slot=\"code-editor\"\n className={cn(\n 'relative bg-muted/50 w-[600px] h-[400px] border border-border overflow-hidden flex flex-col rounded-xl',\n className,\n )}\n {...props}\n >\n {header ? (\n <div className=\"bg-muted border-b border-border/75 dark:border-border/50 relative flex flex-row items-center justify-between gap-y-2 h-10 px-4\">\n {dots && (\n <div className=\"flex flex-row gap-x-2\">\n <div className=\"size-2 rounded-full bg-red-500\"></div>\n <div className=\"size-2 rounded-full bg-yellow-500\"></div>\n <div className=\"size-2 rounded-full bg-green-500\"></div>\n </div>\n )}\n\n {title && (\n <div\n className={cn(\n 'flex flex-row items-center gap-2',\n dots &&\n 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2',\n )}\n >\n {icon ? (\n <div\n className=\"text-muted-foreground [&_svg]:size-3.5\"\n dangerouslySetInnerHTML={\n typeof icon === 'string' ? { __html: icon } : undefined\n }\n >\n {typeof icon !== 'string' ? icon : null}\n </div>\n ) : null}\n <figcaption className=\"flex-1 truncate text-muted-foreground text-[13px]\">\n {title}\n </figcaption>\n </div>\n )}\n\n {copyButton ? (\n <CopyButton\n content={code}\n size=\"sm\"\n variant=\"ghost\"\n className=\"-me-2 bg-transparent hover:bg-black/5 dark:hover:bg-white/10\"\n onCopy={onCopy}\n />\n ) : null}\n </div>\n ) : (\n copyButton && (\n <CopyButton\n content={code}\n size=\"sm\"\n variant=\"ghost\"\n className=\"absolute right-2 top-2 z-[2] backdrop-blur-md bg-transparent hover:bg-black/5 dark:hover:bg-white/10\"\n onCopy={onCopy}\n />\n )\n )}\n <div\n ref={editorRef}\n className=\"h-[calc(100%-2.75rem)] w-full text-sm p-4 font-mono relative overflow-auto flex-1\"\n >\n <div\n className={cn(\n '[&>pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]',\n cursor &&\n !isDone &&\n \"[&_.line:last-of-type::after]:content-['|'] [&_.line:last-of-type::after]:animate-pulse [&_.line:last-of-type::after]:inline-block [&_.line:last-of-type::after]:w-[1ch] [&_.line:last-of-type::after]:-translate-px\",\n )}\n dangerouslySetInnerHTML={{ __html: highlightedCode }}\n />\n </div>\n </div>\n );\n}\n\nexport { CodeEditor, type CodeEditorProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/code-editor/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'code-editor';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/code-editor',
},
'code-tabs': {
name: 'code-tabs',
description: 'A tabs component that displays code for different languages.',
type: 'registry:ui',
dependencies: ['shiki'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/tabs',
'https://animate-ui.com/r/copy-button',
],
files: [
{
path: 'registry/components/code-tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/code-tabs.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { useTheme } from 'next-themes';\n\nimport { cn } from '@/lib/utils';\nimport {\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n TabsContents,\n type TabsProps,\n} from '@/components/animate-ui/components/tabs';\nimport { CopyButton } from '@/components/animate-ui/buttons/copy';\n\ntype CodeTabsProps = {\n codes: Record<string, string>;\n lang?: string;\n themes?: {\n light: string;\n dark: string;\n };\n copyButton?: boolean;\n onCopy?: (content: string) => void;\n} & Omit<TabsProps, 'children'>;\n\nfunction CodeTabs({\n codes,\n lang = 'bash',\n themes = {\n light: 'github-light',\n dark: 'github-dark',\n },\n className,\n defaultValue,\n value,\n onValueChange,\n copyButton = true,\n onCopy,\n ...props\n}: CodeTabsProps) {\n const { resolvedTheme } = useTheme();\n\n const [highlightedCodes, setHighlightedCodes] = React.useState<Record<\n string,\n string\n > | null>(null);\n const [selectedCode, setSelectedCode] = React.useState<string>(\n value ?? defaultValue ?? Object.keys(codes)[0] ?? '',\n );\n\n React.useEffect(() => {\n async function loadHighlightedCode() {\n try {\n const { codeToHtml } = await import('shiki');\n const newHighlightedCodes: Record<string, string> = {};\n\n for (const [command, val] of Object.entries(codes)) {\n const highlighted = await codeToHtml(val, {\n lang,\n themes: {\n light: themes.light,\n dark: themes.dark,\n },\n defaultColor: resolvedTheme === 'dark' ? 'dark' : 'light',\n });\n\n newHighlightedCodes[command] = highlighted;\n }\n\n setHighlightedCodes(newHighlightedCodes);\n } catch (error) {\n console.error('Error highlighting codes', error);\n setHighlightedCodes(codes);\n }\n }\n loadHighlightedCode();\n }, [resolvedTheme, lang, themes.light, themes.dark, codes]);\n\n return (\n <Tabs\n data-slot=\"install-tabs\"\n className={cn(\n 'w-full gap-0 bg-muted/50 rounded-xl border overflow-hidden',\n className,\n )}\n {...props}\n value={selectedCode}\n onValueChange={(val) => {\n setSelectedCode(val);\n onValueChange?.(val);\n }}\n >\n <TabsList\n data-slot=\"install-tabs-list\"\n className=\"w-full relative justify-between rounded-none h-10 bg-muted border-b border-border/75 dark:border-border/50 text-current py-0 px-4\"\n activeClassName=\"rounded-none shadow-none bg-transparent after:content-[''] after:absolute after:inset-x-0 after:h-0.5 after:bottom-0 dark:after:bg-white after:bg-black after:rounded-t-full\"\n >\n <div className=\"flex gap-x-3 h-full\">\n {highlightedCodes &&\n Object.keys(highlightedCodes).map((code) => (\n <TabsTrigger\n key={code}\n value={code}\n className=\"text-muted-foreground data-[state=active]:text-current px-0\"\n >\n {code}\n </TabsTrigger>\n ))}\n </div>\n\n {copyButton && highlightedCodes && (\n <CopyButton\n content={codes[selectedCode]}\n size=\"sm\"\n variant=\"ghost\"\n className=\"-me-2 bg-transparent hover:bg-black/5 dark:hover:bg-white/10\"\n onCopy={onCopy}\n />\n )}\n </TabsList>\n <TabsContents data-slot=\"install-tabs-contents\">\n {highlightedCodes &&\n Object.entries(highlightedCodes).map(([code, val]) => (\n <TabsContent\n data-slot=\"install-tabs-content\"\n key={code}\n className=\"w-full text-sm flex items-center p-4 overflow-auto\"\n value={code}\n >\n <div\n className=\"[&>pre,_&_code]:!bg-transparent [&>pre,_&_code]:[background:transparent_!important] [&>pre,_&_code]:border-none [&_code]:!text-[13px]\"\n dangerouslySetInnerHTML={{ __html: val }}\n />\n </TabsContent>\n ))}\n </TabsContents>\n </Tabs>\n );\n}\n\nexport { CodeTabs, type CodeTabsProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/code-tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'code-tabs';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/code-tabs',
},
counter: {
name: 'counter',
description:
'A numeric input control featuring increment and decrement buttons, smoothly animating number transitions using the SlidingNumber component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['button', 'https://animate-ui.com/r/sliding-number'],
files: [
{
path: 'registry/components/counter/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/counter.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type HTMLMotionProps, type Transition } from 'motion/react';\n\nimport {\n SlidingNumber,\n type SlidingNumberProps,\n} from '@/components/animate-ui/text/sliding-number';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\ntype CounterProps = HTMLMotionProps<'div'> & {\n number: number;\n setNumber: (number: number) => void;\n slidingNumberProps?: Omit<SlidingNumberProps, 'number'>;\n buttonProps?: Omit<React.ComponentProps<typeof Button>, 'onClick'>;\n transition?: Transition;\n};\n\nfunction Counter({\n number,\n setNumber,\n className,\n slidingNumberProps,\n buttonProps,\n transition = { type: 'spring', bounce: 0, stiffness: 300, damping: 30 },\n ...props\n}: CounterProps) {\n return (\n <motion.div\n data-slot=\"counter\"\n layout\n transition={transition}\n className={cn(\n 'flex items-center gap-x-2 p-1 rounded-xl bg-neutral-100 dark:bg-neutral-800',\n className,\n )}\n {...props}\n >\n <motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>\n <Button\n size=\"icon\"\n {...buttonProps}\n onClick={() => setNumber(number - 1)}\n className={cn(\n 'bg-white dark:bg-neutral-950 hover:bg-white/70 dark:hover:bg-neutral-950/70 text-neutral-950 dark:text-white text-2xl font-light pb-[3px]',\n buttonProps?.className,\n )}\n >\n -\n </Button>\n </motion.div>\n\n <SlidingNumber\n number={number}\n {...slidingNumberProps}\n className={cn('text-lg', slidingNumberProps?.className)}\n />\n\n <motion.div whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>\n <Button\n size=\"icon\"\n {...buttonProps}\n onClick={() => setNumber(number + 1)}\n className={cn(\n 'bg-white dark:bg-neutral-950 hover:bg-white/70 dark:hover:bg-neutral-950/70 text-neutral-950 dark:text-white text-2xl font-light pb-[3px]',\n buttonProps?.className,\n )}\n >\n +\n </Button>\n </motion.div>\n </motion.div>\n );\n}\n\nexport { Counter, type CounterProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/counter/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counter';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counter',
},
cursor: {
name: 'cursor',
description:
'An animated cursor component that allows you to customize both the cursor and cursor follow elements with smooth animations.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/components/cursor/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/cursor.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n useMotionValue,\n useSpring,\n AnimatePresence,\n type HTMLMotionProps,\n type SpringOptions,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype CursorContextType = {\n cursorPos: { x: number; y: number };\n isActive: boolean;\n containerRef: React.RefObject<HTMLDivElement | null>;\n cursorRef: React.RefObject<HTMLDivElement | null>;\n};\n\nconst CursorContext = React.createContext<CursorContextType | undefined>(\n undefined,\n);\n\nconst useCursor = (): CursorContextType => {\n const context = React.useContext(CursorContext);\n if (!context) {\n throw new Error('useCursor must be used within a CursorProvider');\n }\n return context;\n};\n\ntype CursorProviderProps = React.ComponentProps<'div'> & {\n children: React.ReactNode;\n};\n\nfunction CursorProvider({ ref, children, ...props }: CursorProviderProps) {\n const [cursorPos, setCursorPos] = React.useState({ x: 0, y: 0 });\n const [isActive, setIsActive] = React.useState(false);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const cursorRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (!containerRef.current) return;\n\n const parent = containerRef.current.parentElement;\n if (!parent) return;\n\n if (getComputedStyle(parent).position === 'static') {\n parent.style.position = 'relative';\n }\n\n const handleMouseMove = (e: MouseEvent) => {\n const rect = parent.getBoundingClientRect();\n setCursorPos({ x: e.clientX - rect.left, y: e.clientY - rect.top });\n setIsActive(true);\n };\n const handleMouseLeave = () => setIsActive(false);\n\n parent.addEventListener('mousemove', handleMouseMove);\n parent.addEventListener('mouseleave', handleMouseLeave);\n\n return () => {\n parent.removeEventListener('mousemove', handleMouseMove);\n parent.removeEventListener('mouseleave', handleMouseLeave);\n };\n }, []);\n\n return (\n <CursorContext.Provider\n value={{ cursorPos, isActive, containerRef, cursorRef }}\n >\n <div ref={containerRef} data-slot=\"cursor-provider\" {...props}>\n {children}\n </div>\n </CursorContext.Provider>\n );\n}\n\ntype CursorProps = HTMLMotionProps<'div'> & {\n children: React.ReactNode;\n};\n\nfunction Cursor({ ref, children, className, style, ...props }: CursorProps) {\n const { cursorPos, isActive, containerRef, cursorRef } = useCursor();\n React.useImperativeHandle(ref, () => cursorRef.current as HTMLDivElement);\n\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n React.useEffect(() => {\n const parentElement = containerRef.current?.parentElement;\n\n if (parentElement && isActive) parentElement.style.cursor = 'none';\n\n return () => {\n if (parentElement) parentElement.style.cursor = 'default';\n };\n }, [containerRef, cursorPos, isActive]);\n\n React.useEffect(() => {\n x.set(cursorPos.x);\n y.set(cursorPos.y);\n }, [cursorPos, x, y]);\n\n return (\n <AnimatePresence>\n {isActive && (\n <motion.div\n ref={cursorRef}\n data-slot=\"cursor\"\n className={cn(\n 'transform-[translate(-50%,-50%)] pointer-events-none z-[9999] absolute',\n className,\n )}\n style={{ top: y, left: x, ...style }}\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n {...props}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\ntype Align =\n | 'top'\n | 'top-left'\n | 'top-right'\n | 'bottom'\n | 'bottom-left'\n | 'bottom-right'\n | 'left'\n | 'right'\n | 'center';\n\ntype CursorFollowProps = HTMLMotionProps<'div'> & {\n sideOffset?: number;\n align?: Align;\n transition?: SpringOptions;\n children: React.ReactNode;\n};\n\nfunction CursorFollow({\n ref,\n sideOffset = 15,\n align = 'bottom-right',\n children,\n className,\n style,\n transition = { stiffness: 500, damping: 50, bounce: 0 },\n ...props\n}: CursorFollowProps) {\n const { cursorPos, isActive, cursorRef } = useCursor();\n const cursorFollowRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(\n ref,\n () => cursorFollowRef.current as HTMLDivElement,\n );\n\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springX = useSpring(x, transition);\n const springY = useSpring(y, transition);\n\n const calculateOffset = React.useCallback(() => {\n const rect = cursorFollowRef.current?.getBoundingClientRect();\n const width = rect?.width ?? 0;\n const height = rect?.height ?? 0;\n\n let newOffset;\n\n switch (align) {\n case 'center':\n newOffset = { x: width / 2, y: height / 2 };\n break;\n case 'top':\n newOffset = { x: width / 2, y: height + sideOffset };\n break;\n case 'top-left':\n newOffset = { x: width + sideOffset, y: height + sideOffset };\n break;\n case 'top-right':\n newOffset = { x: -sideOffset, y: height + sideOffset };\n break;\n case 'bottom':\n newOffset = { x: width / 2, y: -sideOffset };\n break;\n case 'bottom-left':\n newOffset = { x: width + sideOffset, y: -sideOffset };\n break;\n case 'bottom-right':\n newOffset = { x: -sideOffset, y: -sideOffset };\n break;\n case 'left':\n newOffset = { x: width + sideOffset, y: height / 2 };\n break;\n case 'right':\n newOffset = { x: -sideOffset, y: height / 2 };\n break;\n default:\n newOffset = { x: 0, y: 0 };\n }\n\n return newOffset;\n }, [align, sideOffset]);\n\n React.useEffect(() => {\n const offset = calculateOffset();\n const cursorRect = cursorRef.current?.getBoundingClientRect();\n const cursorWidth = cursorRect?.width ?? 20;\n const cursorHeight = cursorRect?.height ?? 20;\n\n x.set(cursorPos.x - offset.x + cursorWidth / 2);\n y.set(cursorPos.y - offset.y + cursorHeight / 2);\n }, [calculateOffset, cursorPos, cursorRef, x, y]);\n\n return (\n <AnimatePresence>\n {isActive && (\n <motion.div\n ref={cursorFollowRef}\n data-slot=\"cursor-follow\"\n className={cn(\n 'transform-[translate(-50%,-50%)] pointer-events-none z-[9998] absolute',\n className,\n )}\n style={{ top: springY, left: springX, ...style }}\n initial={{ scale: 0, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0, opacity: 0 }}\n {...props}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n CursorProvider,\n Cursor,\n CursorFollow,\n useCursor,\n type CursorContextType,\n type CursorProviderProps,\n type CursorProps,\n type CursorFollowProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/cursor/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cursor';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cursor',
},
files: {
name: 'files',
description:
'A component that allows you to display a list of files and folders.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/motion-highlight',
'https://animate-ui.com/r/radix-accordion',
],
files: [
{
path: 'registry/components/files/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/files.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport { FileIcon, FolderIcon, FolderOpenIcon } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionItemProps,\n AccordionTrigger,\n AccordionTriggerProps,\n useAccordionItem,\n} from '@/components/animate-ui/radix/accordion';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype FileButtonProps = React.ComponentProps<'div'> & {\n icons?: {\n close: React.ReactNode;\n open: React.ReactNode;\n };\n icon?: React.ReactNode;\n open?: boolean;\n sideComponent?: React.ReactNode;\n};\n\nfunction FileButton({\n children,\n className,\n icons,\n icon,\n open,\n sideComponent,\n ...props\n}: FileButtonProps) {\n return (\n <MotionHighlightItem className=\"size-full\">\n <div\n data-slot=\"file-button\"\n className={cn(\n 'flex items-center truncate gap-2 p-2 h-10 relative z-10 rounded-lg w-full cursor-default',\n className,\n )}\n {...props}\n >\n <span className=\"flex [&_svg]:size-4 [&_svg]:shrink-0 items-center gap-2 shrink-1 truncate\">\n {icon\n ? typeof icon !== 'string'\n ? icon\n : null\n : icons && (\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={open ? 'open' : 'close'}\n initial={{ scale: 0.9 }}\n animate={{ scale: 1 }}\n exit={{ scale: 0.9 }}\n transition={{ duration: 0.15 }}\n >\n {open\n ? typeof icons.open !== 'string'\n ? icons.open\n : null\n : typeof icons.close !== 'string'\n ? icons.close\n : null}\n </motion.span>\n </AnimatePresence>\n )}\n <span className=\"shrink-1 text-sm block truncate break-words\">\n {children}\n </span>\n </span>\n {sideComponent}\n </div>\n </MotionHighlightItem>\n );\n}\n\ntype FilesProps = React.ComponentProps<'div'> & {\n children: React.ReactNode;\n activeClassName?: string;\n defaultOpen?: string[];\n open?: string[];\n onOpenChange?: (open: string[]) => void;\n};\n\nfunction Files({\n children,\n className,\n activeClassName,\n defaultOpen,\n open,\n onOpenChange,\n ...props\n}: FilesProps) {\n return (\n <div\n data-slot=\"files\"\n className={cn(\n 'relative size-full rounded-xl border bg-background overflow-auto',\n className,\n )}\n {...props}\n >\n <MotionHighlight\n controlledItems\n mode=\"parent\"\n hover\n className={cn(\n 'bg-muted rounded-lg pointer-events-none',\n activeClassName,\n )}\n >\n <Accordion\n type=\"multiple\"\n className=\"p-2\"\n defaultValue={defaultOpen}\n value={open}\n onValueChange={onOpenChange}\n >\n {children}\n </Accordion>\n </MotionHighlight>\n </div>\n );\n}\n\ntype FolderTriggerProps = AccordionTriggerProps & {\n sideComponent?: React.ReactNode;\n};\n\nfunction FolderTrigger({\n children,\n className,\n sideComponent,\n ...props\n}: FolderTriggerProps) {\n const { isOpen } = useAccordionItem();\n\n return (\n <AccordionTrigger\n data-slot=\"folder-trigger\"\n className=\"h-auto py-0 hover:no-underline font-normal relative z-10 max-w-full\"\n {...props}\n chevron={false}\n >\n <FileButton\n open={isOpen}\n icons={{ open: <FolderOpenIcon />, close: <FolderIcon /> }}\n className={className}\n sideComponent={sideComponent}\n >\n {children}\n </FileButton>\n </AccordionTrigger>\n );\n}\n\ntype FolderProps = Omit<\n AccordionItemProps,\n 'value' | 'onValueChange' | 'defaultValue' | 'children'\n> & {\n children?: React.ReactNode;\n name: string;\n open?: string[];\n onOpenChange?: (open: string[]) => void;\n defaultOpen?: string[];\n sideComponent?: React.ReactNode;\n};\n\nfunction Folder({\n children,\n className,\n name,\n open,\n defaultOpen,\n onOpenChange,\n sideComponent,\n ...props\n}: FolderProps) {\n return (\n <AccordionItem\n data-slot=\"folder\"\n value={name}\n className=\"relative border-b-0\"\n {...props}\n >\n <FolderTrigger className={className} sideComponent={sideComponent}>\n {name}\n </FolderTrigger>\n {children && (\n <AccordionContent className=\"relative pb-0 !ml-7 before:absolute before:-left-3 before:inset-y-0 before:w-px before:h-full before:bg-border\">\n <Accordion\n type=\"multiple\"\n defaultValue={defaultOpen}\n value={open}\n onValueChange={onOpenChange}\n >\n {children}\n </Accordion>\n </AccordionContent>\n )}\n </AccordionItem>\n );\n}\n\ntype FileProps = Omit<React.ComponentProps<'div'>, 'children'> & {\n name: string;\n sideComponent?: React.ReactNode;\n};\n\nfunction File({ name, className, sideComponent, ...props }: FileProps) {\n return (\n <FileButton\n data-slot=\"file\"\n icon={<FileIcon />}\n className={className}\n sideComponent={sideComponent}\n {...props}\n >\n {name}\n </FileButton>\n );\n}\n\nexport {\n Files,\n Folder,\n File,\n type FilesProps,\n type FolderProps,\n type FileProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/files/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'files';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/files',
},
'liquid-glass': {
name: 'liquid-glass',
description:
'A component that allows you to display a liquid glass effect, inspired by iOS26.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/components/liquid-glass/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/liquid-glass.tsx',
content:
'import * as React from \'react\';\nimport { cn } from \'@/lib/utils\';\n\nconst DEFAULT_COMPONENT = \'div\';\n\ntype LiquidGlassProps<T extends React.ElementType = typeof DEFAULT_COMPONENT> =\n {\n as?: T;\n radius?: number;\n blur?: number;\n childClassName?: string;\n } & React.ComponentProps<T>;\n\nfunction LiquidGlass<T extends React.ElementType = typeof DEFAULT_COMPONENT>({\n as,\n children,\n className,\n radius = 25,\n blur = 0,\n childClassName,\n ref,\n ...props\n}: LiquidGlassProps<T>) {\n const Component = as || DEFAULT_COMPONENT;\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n const rx = radius;\n const [size, setSize] = React.useState<{ width: string; height: string }>({\n width: \'0\',\n height: \'0\',\n });\n\n const viewBox = React.useMemo(\n () => `0 0 ${size.width} ${size.height}`,\n [size.width, size.height],\n );\n\n const calculateSize = React.useCallback(() => {\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect();\n setSize({\n width: rect.width.toString(),\n height: rect.height.toString(),\n });\n }\n }, []);\n\n React.useEffect(() => {\n calculateSize();\n }, [calculateSize, children, className, childClassName, radius]);\n\n return (\n <Component\n className={cn(\'relative overflow-hidden\', className)}\n style={{ borderRadius: `${rx}px` }}\n ref={containerRef}\n {...props}\n >\n <svg className="hidden">\n <filter\n id="glass-distortion"\n x="0%"\n y="0%"\n width={size.width}\n height={size.height}\n filterUnits="objectBoundingBox"\n >\n <feTurbulence\n type="fractalNoise"\n baseFrequency="0.001 0.005"\n numOctaves="1"\n seed="17"\n result="turbulence"\n />\n\n <feComponentTransfer in="turbulence" result="mapped">\n <feFuncR type="gamma" amplitude="1" exponent="10" offset="0.5" />\n <feFuncG type="gamma" amplitude="0" exponent="1" offset="0" />\n <feFuncB type="gamma" amplitude="0" exponent="1" offset="0.5" />\n </feComponentTransfer>\n\n <feGaussianBlur in="turbulence" stdDeviation="3" result="softMap" />\n\n <feSpecularLighting\n in="softMap"\n surfaceScale="5"\n specularConstant="1"\n specularExponent="100"\n lightingColor="white"\n result="specLight"\n >\n <fePointLight x="-200" y="-200" z="300" />\n </feSpecularLighting>\n\n <feComposite\n in="specLight"\n operator="arithmetic"\n k1="0"\n k2="1"\n k3="1"\n k4="0"\n result="litImage"\n />\n\n <feDisplacementMap\n in="SourceGraphic"\n in2="softMap"\n scale="200"\n xChannelSelector="R"\n yChannelSelector="G"\n />\n </filter>\n </svg>\n\n <span\n className="flex items-center justify-center w-full h-full"\n style={{\n backdropFilter: `blur(${blur}px) url(#displacementFilter4)`,\n boxShadow: \'inset 0 0 1px 0 rgba(255, 255, 255, 0.5)\',\n borderRadius: `${rx}px`,\n }}\n >\n <span\n className="relative flex overflow-hidden transition-all duration-400 ease-in-out"\n style={{\n borderRadius: `${rx}px`,\n }}\n >\n <span\n className="absolute z-0 inset-0 overflow-hidden isolate [filter:url(#glass-distortion)]"\n style={{\n borderRadius: `${rx}px`,\n }}\n />\n <span\n className="z-[1] absolute inset-0"\n style={{\n borderRadius: `${rx}px`,\n }}\n />\n <span className="relative z-[3] w-full h-full">\n <span\n className={cn(\n \'flex items-center justify-center gap-2 w-full p-2\',\n childClassName,\n )}\n >\n {children}\n </span>\n <svg\n width={size.width}\n height={size.height}\n viewBox={viewBox}\n xmlns="http://www.w3.org/2000/svg"\n className="hidden"\n >\n <filter\n id="displacementFilter4"\n x="0"\n y="0"\n width={size.width}\n height={size.height}\n filterUnits="userSpaceOnUse"\n >\n <feImage\n href={`data:image/svg+xml,%3Csvg width=\'${size.width}\' height=\'${size.height}\' viewBox=\'${viewBox}\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%230001\' /%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%23FFF\' style=\'filter:blur(5px)\' /%3E%3C/svg%3E`}\n x="0%"\n y="0%"\n width={size.width}\n height={size.height}\n result="thing9"\n />\n <feImage\n href={`data:image/svg+xml,%3Csvg width=\'${size.width}\' height=\'${size.height}\' viewBox=\'${viewBox}\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%23FFF1\' style=\'filter:blur(15px)\' /%3E%3C/svg%3E`}\n x="0%"\n y="0%"\n width={size.width}\n height={size.height}\n result="thing0"\n />\n <feImage\n href={`data:image/svg+xml,%3Csvg width=\'${size.width}\' height=\'${size.height}\' viewBox=\'${viewBox}\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%23000\' /%3E%3C/svg%3E`}\n x="0%"\n y="0%"\n width={size.width}\n height={size.height}\n result="thing1"\n />\n <feImage\n href={`data:image/svg+xml,%3Csvg width=\'${size.width}\' height=\'${size.height}\' viewBox=\'${viewBox}\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cdefs%3E%3ClinearGradient id=\'gradient1\' x1=\'0%25\' y1=\'0%25\' x2=\'100%25\' y2=\'0%25\'%3E%3Cstop offset=\'0%25\' stop-color=\'%23000\'/%3E%3Cstop offset=\'100%25\' stop-color=\'%2300F\'/%3E%3C/linearGradient%3E%3ClinearGradient id=\'gradient2\' x1=\'0%25\' y1=\'0%25\' x2=\'0%25\' y2=\'100%25\'%3E%3Cstop offset=\'0%25\' stop-color=\'%23000\'/%3E%3Cstop offset=\'100%25\' stop-color=\'%230F0\'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect x=\'0\' y=\'0\' width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%237F7F7F\' /%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%23000\' /%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'url(%23gradient1)\' style=\'mix-blend-mode: screen\' /%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'url(%23gradient2)\' style=\'mix-blend-mode: screen\' /%3E%3Crect width=\'${size.width}\' height=\'${size.height}\' rx=\'${rx}\' fill=\'%237F7F7FBB\' style=\'filter:blur(5px)\' /%3E%3C/svg%3E`}\n x="0%"\n y="0%"\n width={size.width}\n height={size.height}\n result="thing2"\n />\n <feDisplacementMap\n in2="thing2"\n in="SourceGraphic"\n scale="-148"\n xChannelSelector="B"\n yChannelSelector="G"\n />\n <feColorMatrix\n type="matrix"\n values="1 0 0 0 0\n 0 0 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0"\n result="disp1"\n />\n <feDisplacementMap\n in2="thing2"\n in="SourceGraphic"\n scale="-150"\n xChannelSelector="B"\n yChannelSelector="G"\n />\n <feColorMatrix\n type="matrix"\n values="0 0 0 0 0\n 0 1 0 0 0\n 0 0 0 0 0\n 0 0 0 1 0"\n result="disp2"\n />\n <feDisplacementMap\n in2="thing2"\n in="SourceGraphic"\n scale="-152"\n xChannelSelector="B"\n yChannelSelector="G"\n />\n <feColorMatrix\n type="matrix"\n values="0 0 0 0 0\n 0 0 0 0 0\n 0 0 1 0 0\n 0 0 0 1 0"\n result="disp3"\n />\n <feBlend in2="disp2" mode="screen" />\n <feBlend in2="disp1" mode="screen" />\n <feGaussianBlur stdDeviation="0.7" />\n <feBlend in2="thing0" mode="screen" />\n <feBlend in2="thing9" mode="multiply" />\n <feComposite in2="thing1" operator="in" />\n </filter>\n </svg>\n </span>\n </span>\n </span>\n </Component>\n );\n}\n\nLiquidGlass.displayName = \'LiquidGlass\';\n\nexport { LiquidGlass, type LiquidGlassProps };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/liquid-glass/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'liquid-glass';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/liquid-glass',
},
'motion-grid': {
name: 'motion-grid',
description: 'A grid that displays animations in a grid.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/components/motion-grid/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/motion-grid.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { type HTMLMotionProps, motion } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype FrameDot = [number, number];\ntype Frame = FrameDot[];\ntype Frames = Frame[];\n\ntype MotionGridProps = {\n gridSize: [number, number];\n frames: Frames;\n duration?: number;\n animate?: boolean;\n cellClassName?: string;\n cellProps?: HTMLMotionProps<'div'>;\n cellActiveClassName?: string;\n cellInactiveClassName?: string;\n} & React.ComponentProps<'div'>;\n\nconst MotionGrid = ({\n gridSize,\n frames,\n duration = 200,\n animate = true,\n cellClassName,\n cellProps,\n cellActiveClassName,\n cellInactiveClassName,\n className,\n style,\n ...props\n}: MotionGridProps) => {\n const [index, setIndex] = React.useState(0);\n const intervalRef = React.useRef<NodeJS.Timeout | null>(null);\n\n React.useEffect(() => {\n if (!animate || frames.length === 0) return;\n intervalRef.current = setInterval(\n () => setIndex((i) => (i + 1) % frames.length),\n duration,\n );\n return () => clearInterval(intervalRef.current!);\n }, [frames.length, duration, animate]);\n\n const [cols, rows] = gridSize;\n\n const active = new Set<number>(\n frames[index]?.map(([x, y]) => y * cols + x) ?? [],\n );\n\n return (\n <div\n className={cn('grid w-fit gap-0.5', className)}\n style={{\n ...style,\n gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,\n gridAutoRows: '1fr',\n }}\n {...props}\n >\n {Array.from({ length: cols * rows }).map((_, i) => (\n <motion.div\n key={i}\n className={cn(\n 'size-3 rounded-full aspect-square',\n active.has(i)\n ? cn('bg-primary scale-110', cellActiveClassName)\n : cn('bg-muted scale-100', cellInactiveClassName),\n cellClassName,\n )}\n {...cellProps}\n transition={{ duration, ease: 'easeInOut' }}\n />\n ))}\n </div>\n );\n};\n\nexport {\n MotionGrid,\n type MotionGridProps,\n type FrameDot,\n type Frame,\n type Frames,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/motion-grid/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-grid';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-grid',
},
'pin-list': {
name: 'pin-list',
description: 'Pin List Component',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: [],
files: [
{
path: 'registry/components/pin-list/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/pin-list.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Pin } from 'lucide-react';\nimport {\n motion,\n LayoutGroup,\n AnimatePresence,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\nimport { cn } from '@/lib/utils';\n\ntype PinListItem = {\n id: number;\n name: string;\n info: string;\n icon: React.ElementType;\n pinned: boolean;\n};\n\ntype PinListProps = {\n items: PinListItem[];\n labels?: {\n pinned?: string;\n unpinned?: string;\n };\n transition?: Transition;\n labelMotionProps?: HTMLMotionProps<'p'>;\n className?: string;\n labelClassName?: string;\n pinnedSectionClassName?: string;\n unpinnedSectionClassName?: string;\n zIndexResetDelay?: number;\n} & HTMLMotionProps<'div'>;\n\nfunction PinList({\n items,\n labels = { pinned: 'Pinned Items', unpinned: 'All Items' },\n transition = { stiffness: 320, damping: 20, mass: 0.8, type: 'spring' },\n labelMotionProps = {\n initial: { opacity: 0 },\n animate: { opacity: 1 },\n exit: { opacity: 0 },\n transition: { duration: 0.22, ease: 'easeInOut' },\n },\n className,\n labelClassName,\n pinnedSectionClassName,\n unpinnedSectionClassName,\n zIndexResetDelay = 500,\n ...props\n}: PinListProps) {\n const [listItems, setListItems] = React.useState(items);\n const [togglingGroup, setTogglingGroup] = React.useState<\n 'pinned' | 'unpinned' | null\n >(null);\n\n const pinned = listItems.filter((u) => u.pinned);\n const unpinned = listItems.filter((u) => !u.pinned);\n\n const toggleStatus = (id: number) => {\n const item = listItems.find((u) => u.id === id);\n if (!item) return;\n\n setTogglingGroup(item.pinned ? 'pinned' : 'unpinned');\n setListItems((prev) => {\n const idx = prev.findIndex((u) => u.id === id);\n if (idx === -1) return prev;\n const updated = [...prev];\n const [item] = updated.splice(idx, 1);\n if (!item) return prev;\n const toggled = { ...item, pinned: !item.pinned };\n if (toggled.pinned) updated.push(toggled);\n else updated.unshift(toggled);\n return updated;\n });\n // Reset group z-index after the animation duration (keep in sync with animation timing)\n setTimeout(() => setTogglingGroup(null), zIndexResetDelay);\n };\n\n return (\n <motion.div className={cn('space-y-10', className)} {...props}>\n <LayoutGroup>\n <div>\n <AnimatePresence>\n {pinned.length > 0 && (\n <motion.p\n layout\n key=\"pinned-label\"\n className={cn(\n 'font-medium px-3 text-neutral-500 dark:text-neutral-300 text-sm mb-2',\n labelClassName,\n )}\n {...labelMotionProps}\n >\n {labels.pinned}\n </motion.p>\n )}\n </AnimatePresence>\n {pinned.length > 0 && (\n <div\n className={cn(\n 'space-y-3 relative',\n togglingGroup === 'pinned' ? 'z-5' : 'z-10',\n pinnedSectionClassName,\n )}\n >\n {pinned.map((item) => (\n <motion.div\n key={item.id}\n layoutId={`item-${item.id}`}\n onClick={() => toggleStatus(item.id)}\n transition={transition}\n className=\"flex items-center justify-between gap-5 rounded-2xl bg-neutral-200 dark:bg-neutral-800 p-2\"\n >\n <div className=\"flex items-center gap-2\">\n <div className=\"rounded-lg bg-background p-2\">\n <item.icon className=\"size-5 text-neutral-500 dark:text-neutral-400\" />\n </div>\n <div>\n <div className=\"text-sm font-semibold\">{item.name}</div>\n <div className=\"text-xs text-neutral-500 dark:text-neutral-400 font-medium\">\n {item.info}\n </div>\n </div>\n </div>\n <div className=\"flex items-center justify-center size-8 rounded-full bg-neutral-400 dark:bg-neutral-600\">\n <Pin className=\"size-4 text-white fill-white\" />\n </div>\n </motion.div>\n ))}\n </div>\n )}\n </div>\n\n <div>\n <AnimatePresence>\n {unpinned.length > 0 && (\n <motion.p\n layout\n key=\"all-label\"\n className={cn(\n 'font-medium px-3 text-neutral-500 dark:text-neutral-300 text-sm mb-2',\n labelClassName,\n )}\n {...labelMotionProps}\n >\n {labels.unpinned}\n </motion.p>\n )}\n </AnimatePresence>\n {unpinned.length > 0 && (\n <div\n className={cn(\n 'space-y-3 relative',\n togglingGroup === 'unpinned' ? 'z-5' : 'z-10',\n unpinnedSectionClassName,\n )}\n >\n {unpinned.map((item) => (\n <motion.div\n key={item.id}\n layoutId={`item-${item.id}`}\n onClick={() => toggleStatus(item.id)}\n transition={transition}\n className=\"flex items-center justify-between gap-5 rounded-2xl bg-neutral-200 dark:bg-neutral-800 p-2 group\"\n >\n <div className=\"flex items-center gap-2\">\n <div className=\"rounded-lg bg-background p-2\">\n <item.icon className=\"size-5 text-neutral-500 dark:text-neutral-400\" />\n </div>\n <div>\n <div className=\"text-sm font-semibold\">{item.name}</div>\n <div className=\"text-xs text-neutral-500 dark:text-neutral-400 font-medium\">\n {item.info}\n </div>\n </div>\n </div>\n <div className=\"flex items-center justify-center size-8 rounded-full bg-neutral-400 dark:bg-neutral-600 opacity-0 group-hover:opacity-100 transition-opacity duration-250\">\n <Pin className=\"size-4 text-white\" />\n </div>\n </motion.div>\n ))}\n </div>\n )}\n </div>\n </LayoutGroup>\n </motion.div>\n );\n}\n\nexport { PinList, type PinListProps, type PinListItem };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/pin-list/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pin-list';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pin-list',
},
'scroll-progress': {
name: 'scroll-progress',
description:
'A scroll progress component that displays the progress of the scroll.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/components/scroll-progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/scroll-progress.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n type HTMLMotionProps,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype ScrollProgressProps = React.ComponentProps<'div'> & {\n progressProps?: HTMLMotionProps<'div'>;\n};\n\nfunction ScrollProgress({\n ref,\n className,\n children,\n progressProps,\n ...props\n}: ScrollProgressProps) {\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n const { scrollYProgress } = useScroll(\n children ? { container: containerRef } : undefined,\n );\n\n const scaleX = useSpring(scrollYProgress, {\n stiffness: 250,\n damping: 40,\n bounce: 0,\n });\n\n return (\n <>\n <motion.div\n data-slot=\"scroll-progress\"\n {...progressProps}\n style={{ scaleX }}\n className={cn(\n 'fixed z-50 top-0 inset-x-0 h-1 bg-blue-500 origin-left',\n progressProps?.className,\n )}\n />\n {containerRef && (\n <div\n ref={containerRef}\n data-slot=\"scroll-progress-container\"\n className={cn('overflow-y-auto h-full', className)}\n {...props}\n >\n {children}\n </div>\n )}\n </>\n );\n}\n\nexport { ScrollProgress, type ScrollProgressProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/scroll-progress/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'scroll-progress';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/scroll-progress',
},
'spring-element': {
name: 'spring-element',
description:
'A flexible, animated spring component that attaches a draggable element (avatar, text, icon, or any React node) to its origin with a spring line.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: [],
files: [
{
path: 'registry/components/spring-element/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/spring-element.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n type HTMLMotionProps,\n motion,\n useMotionValue,\n useSpring,\n} from 'motion/react';\nimport { cn } from '@/lib/utils';\n\nconst generateSpringPath = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n springConfig: {\n coilCount?: number;\n amplitudeMin?: number;\n amplitudeMax?: number;\n curveRatioMin?: number;\n curveRatioMax?: number;\n bezierOffset?: number;\n } = {},\n) => {\n const {\n coilCount = 8,\n amplitudeMin = 8,\n amplitudeMax = 20,\n curveRatioMin = 0.5,\n curveRatioMax = 1,\n bezierOffset = 8,\n } = springConfig;\n\n const dx = x2 - x1;\n const dy = y2 - y1;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist < 2) return `M${x1},${y1}`;\n const d = dist / coilCount;\n const h = Math.max(0.8, 1 - (dist - 40) / 200);\n const amplitude = Math.max(\n amplitudeMin,\n Math.min(amplitudeMax, amplitudeMax * h),\n );\n const curveRatio =\n dist <= 40\n ? curveRatioMax\n : dist <= 120\n ? curveRatioMax - ((dist - 40) / 80) * (curveRatioMax - curveRatioMin)\n : curveRatioMin;\n const ux = dx / dist,\n uy = dy / dist;\n const perpX = -uy,\n perpY = ux;\n\n let path = [];\n for (let i = 0; i < coilCount; i++) {\n const sx = x1 + ux * (i * d);\n const sy = y1 + uy * (i * d);\n const ex = x1 + ux * ((i + 1) * d);\n const ey = y1 + uy * ((i + 1) * d);\n\n const mx = x1 + ux * ((i + 0.5) * d) + perpX * amplitude;\n const my = y1 + uy * ((i + 0.5) * d) + perpY * amplitude;\n\n const c1x = sx + d * curveRatio * ux;\n const c1y = sy + d * curveRatio * uy;\n const c2x = mx + ux * bezierOffset;\n const c2y = my + uy * bezierOffset;\n const c3x = mx - ux * bezierOffset;\n const c3y = my - uy * bezierOffset;\n const c4x = ex - d * curveRatio * ux;\n const c4y = ey - d * curveRatio * uy;\n\n if (i === 0) path.push(`M${sx},${sy}`);\n else path.push(`L${sx},${sy}`);\n path.push(`C${c1x},${c1y} ${c2x},${c2y} ${mx},${my}`);\n path.push(`C${c3x},${c3y} ${c4x},${c4y} ${ex},${ey}`);\n }\n return path.join(' ');\n};\n\nfunction useMotionValueValue(mv: any) {\n return React.useSyncExternalStore(\n (callback) => {\n const unsub = mv.on('change', callback);\n return unsub;\n },\n () => mv.get(),\n () => mv.get(),\n );\n}\n\ntype SpringAvatarProps = {\n children: React.ReactElement;\n className?: string;\n springClassName?: string;\n dragElastic?: number;\n springConfig?: { stiffness?: number; damping?: number };\n springPathConfig?: {\n coilCount?: number;\n amplitudeMin?: number;\n amplitudeMax?: number;\n curveRatioMin?: number;\n curveRatioMax?: number;\n bezierOffset?: number;\n };\n} & HTMLMotionProps<'div'>;\n\nfunction SpringElement({\n ref,\n children,\n className,\n springClassName,\n dragElastic = 0.2,\n springConfig = { stiffness: 200, damping: 16 },\n springPathConfig = {},\n ...props\n}: SpringAvatarProps) {\n const x = useMotionValue(0);\n const y = useMotionValue(0);\n\n const springX = useSpring(x, {\n stiffness: springConfig.stiffness,\n damping: springConfig.damping,\n });\n const springY = useSpring(y, {\n stiffness: springConfig.stiffness,\n damping: springConfig.damping,\n });\n\n const sx = useMotionValueValue(springX);\n const sy = useMotionValueValue(springY);\n\n const childRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => childRef.current as HTMLDivElement);\n const [center, setCenter] = React.useState({ x: 0, y: 0 });\n const [isDragging, setIsDragging] = React.useState(false);\n\n React.useLayoutEffect(() => {\n function update() {\n if (childRef.current) {\n const rect = childRef.current.getBoundingClientRect();\n setCenter({\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n });\n }\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n };\n }, []);\n\n React.useEffect(() => {\n if (isDragging) {\n document.body.style.cursor = 'grabbing';\n } else {\n document.body.style.cursor = 'default';\n }\n }, [isDragging]);\n\n const path = generateSpringPath(\n center.x,\n center.y,\n center.x + sx,\n center.y + sy,\n springPathConfig,\n );\n\n return (\n <>\n <svg\n width=\"100vw\"\n height=\"100vh\"\n className=\"fixed inset-0 w-screen h-screen pointer-events-none z-40 inset-0\"\n >\n <path\n d={path}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn(\n 'stroke-2 stroke-neutral-900 dark:stroke-neutral-100 fill-none',\n springClassName,\n )}\n />\n </svg>\n <motion.div\n ref={childRef}\n className={cn(\n 'z-50',\n isDragging ? 'cursor-grabbing' : 'cursor-grab',\n className,\n )}\n style={{\n x: springX,\n y: springY,\n }}\n drag\n dragElastic={dragElastic}\n dragMomentum={false}\n onDragStart={() => {\n setIsDragging(true);\n }}\n onDrag={(_, info) => {\n x.set(info.offset.x);\n y.set(info.offset.y);\n }}\n onDragEnd={() => {\n x.set(0);\n y.set(0);\n setIsDragging(false);\n }}\n {...props}\n >\n {children}\n </motion.div>\n </>\n );\n}\n\nexport { SpringElement };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/spring-element/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'spring-element';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/spring-element',
},
'stars-scrolling-wheel': {
name: 'stars-scrolling-wheel',
description: 'A scrolling wheel that displays stars count.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/star-icon'],
files: [
{
path: 'registry/components/stars-scrolling-wheel/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/stars-scrolling-wheel.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n AnimatePresence,\n motion,\n useMotionValue,\n useSpring,\n useTransform,\n useInView,\n type SpringOptions,\n type UseInViewOptions,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport { Star } from '@/components/animate-ui/icons/star';\n\nconst formatter = new Intl.NumberFormat('en-US');\n\nfunction generateRange(\n max: number,\n step: number,\n sideItemsCount: number,\n): number[] {\n const result: number[] = [];\n const end = max + sideItemsCount * step;\n for (let value = end; value >= 0; value -= step) {\n result.push(value);\n }\n return result;\n}\n\ntype StarsScrollingWheelProps = {\n stars: number;\n step?: number;\n itemHeight?: number;\n sideItemsCount?: number;\n transition?: SpringOptions;\n inView?: boolean;\n inViewOnce?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n delay?: number;\n} & React.ComponentProps<'div'>;\n\nfunction StarsScrollingWheel({\n ref,\n stars,\n step = 100,\n itemHeight = 48,\n sideItemsCount = 2,\n transition = { stiffness: 90, damping: 30 },\n inView = false,\n inViewOnce = true,\n inViewMargin = '0px',\n delay = 0,\n className,\n style,\n ...props\n}: StarsScrollingWheelProps) {\n const containerRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement);\n\n const inViewResult = useInView(containerRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const displayedItemsCount = 1 + sideItemsCount * 2;\n const range = React.useMemo(\n () => generateRange(stars, step, sideItemsCount),\n [stars, step, sideItemsCount],\n );\n\n const initialY = -(itemHeight * sideItemsCount);\n const finalY = itemHeight * (range.length - displayedItemsCount);\n\n const yMotion = useMotionValue(initialY);\n const ySpring = useSpring(yMotion, transition);\n\n React.useEffect(() => {\n if (!isInView) return;\n const timer = setTimeout(() => {\n yMotion.set(finalY);\n }, delay);\n return () => clearTimeout(timer);\n }, [isInView, finalY, yMotion, delay]);\n\n const currentIndex = useTransform(\n ySpring,\n (y) => y / itemHeight + sideItemsCount,\n );\n const currentValue = useTransform(currentIndex, (idx) => idx * step);\n const completedTransform = useTransform(\n currentValue,\n (val) => val >= stars * 0.99,\n );\n\n const [isCompleted, setCompleted] = React.useState<boolean>(\n completedTransform.get(),\n );\n React.useEffect(() => {\n const unsubscribe = completedTransform.on('change', (latest) => {\n if (latest) setCompleted(true);\n });\n return unsubscribe;\n }, [completedTransform]);\n\n return (\n <div\n ref={containerRef}\n className={cn(\n 'relative overflow-hidden w-[200px] bg-background',\n className,\n )}\n style={{ height: itemHeight * displayedItemsCount, ...style }}\n {...props}\n >\n <div\n className=\"absolute z-2 top-0 inset-x-0 bg-gradient-to-t from-transparent to-background\"\n style={{ height: itemHeight }}\n />\n <div\n className=\"absolute z-1 top-0 inset-x-0 bg-background/60\"\n style={{ height: itemHeight * sideItemsCount }}\n />\n\n <div\n className=\"absolute z-1 bottom-0 inset-x-0 bg-gradient-to-b from-transparent to-background\"\n style={{ height: itemHeight }}\n />\n <div\n className=\"absolute z-1 bottom-0 inset-x-0 bg-background/60\"\n style={{ height: itemHeight * sideItemsCount }}\n />\n\n <div className=\"absolute inset-x-0 top-1/2 -translate-y-1/2 flex items-center justify-center\">\n <div\n className=\"w-full bg-muted rounded-xl flex items-center justify-start px-6\"\n style={{ height: itemHeight }}\n >\n <div className=\"relative inline-flex size-[28px] shrink-0\">\n <Star\n animation=\"fill\"\n animate={isCompleted}\n className=\"text-yellow-500\"\n />\n <AnimatePresence>\n {isCompleted && (\n <>\n <motion.div\n className=\"absolute inset-0 rounded-full\"\n style={{\n background:\n 'radial-gradient(circle, rgba(255,215,0,0.4) 0%, rgba(255,215,0,0) 70%)',\n }}\n initial={{ scale: 1.2, opacity: 0 }}\n animate={{ scale: [1.2, 1.8, 1.2], opacity: [0, 0.3, 0] }}\n transition={{ duration: 1.2, ease: 'easeInOut' }}\n />\n <motion.div\n className=\"absolute inset-0 rounded-full\"\n style={{ boxShadow: '0 0 10px 2px rgba(255,215,0,0.6)' }}\n initial={{ scale: 1, opacity: 0 }}\n animate={{ scale: [1, 1.5], opacity: [0.8, 0] }}\n transition={{ duration: 0.8, ease: 'easeOut' }}\n />\n {[...Array(6)].map((_, i) => (\n <motion.div\n key={i}\n className=\"absolute w-1 h-1 rounded-full bg-yellow-500\"\n initial={{ x: '50%', y: '50%', scale: 0, opacity: 0 }}\n animate={{\n x: `calc(50% + ${Math.cos((i * Math.PI) / 3) * 30}px)`,\n y: `calc(50% + ${Math.sin((i * Math.PI) / 3) * 30}px)`,\n scale: [0, 1, 0],\n opacity: [0, 1, 0],\n }}\n transition={{\n duration: 0.8,\n delay: i * 0.05,\n ease: 'easeOut',\n }}\n />\n ))}\n </>\n )}\n </AnimatePresence>\n </div>\n </div>\n </div>\n\n <motion.div\n className=\"absolute left-17 bottom-0 text-start flex items-center justify-center flex-col\"\n style={{ y: ySpring }}\n >\n {range.map((value) => (\n <div\n key={value}\n className=\"text-2xl font-bold flex items-center justify-start w-full\"\n style={{ height: itemHeight }}\n >\n {formatter.format(value)}\n </div>\n ))}\n </motion.div>\n </div>\n );\n}\n\nexport { StarsScrollingWheel, type StarsScrollingWheelProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/components/stars-scrolling-wheel/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'stars-scrolling-wheel';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/stars-scrolling-wheel',
},
tabs: {
name: 'tabs',
description:
'A set of layered sections with the same height of content—known as tab panels—that are displayed one at a time.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/components/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/tabs.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Transition, type HTMLMotionProps } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype TabsContextType<T extends string> = {\n activeValue: T;\n handleValueChange: (value: T) => void;\n registerTrigger: (value: T, node: HTMLElement | null) => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst TabsContext = React.createContext<TabsContextType<any> | undefined>(\n undefined,\n);\n\nfunction useTabs<T extends string = string>(): TabsContextType<T> {\n const context = React.useContext(TabsContext);\n if (!context) {\n throw new Error('useTabs must be used within a TabsProvider');\n }\n return context;\n}\n\ntype BaseTabsProps = React.ComponentProps<'div'> & {\n children: React.ReactNode;\n};\n\ntype UnControlledTabsProps<T extends string = string> = BaseTabsProps & {\n defaultValue?: T;\n value?: never;\n onValueChange?: never;\n};\n\ntype ControlledTabsProps<T extends string = string> = BaseTabsProps & {\n value: T;\n onValueChange?: (value: T) => void;\n defaultValue?: never;\n};\n\ntype TabsProps<T extends string = string> =\n | UnControlledTabsProps<T>\n | ControlledTabsProps<T>;\n\nfunction Tabs<T extends string = string>({\n defaultValue,\n value,\n onValueChange,\n children,\n className,\n ...props\n}: TabsProps<T>) {\n const [activeValue, setActiveValue] = React.useState<T | undefined>(\n defaultValue ?? undefined,\n );\n const triggersRef = React.useRef(new Map<string, HTMLElement>());\n const initialSet = React.useRef(false);\n const isControlled = value !== undefined;\n\n React.useEffect(() => {\n if (\n !isControlled &&\n activeValue === undefined &&\n triggersRef.current.size > 0 &&\n !initialSet.current\n ) {\n const firstTab = Array.from(triggersRef.current.keys())[0];\n setActiveValue(firstTab as T);\n initialSet.current = true;\n }\n }, [activeValue, isControlled]);\n\n const registerTrigger = (value: string, node: HTMLElement | null) => {\n if (node) {\n triggersRef.current.set(value, node);\n if (!isControlled && activeValue === undefined && !initialSet.current) {\n setActiveValue(value as T);\n initialSet.current = true;\n }\n } else {\n triggersRef.current.delete(value);\n }\n };\n\n const handleValueChange = (val: T) => {\n if (!isControlled) setActiveValue(val);\n else onValueChange?.(val);\n };\n\n return (\n <TabsContext.Provider\n value={{\n activeValue: (value ?? activeValue)!,\n handleValueChange,\n registerTrigger,\n }}\n >\n <div\n data-slot=\"tabs\"\n className={cn('flex flex-col gap-2', className)}\n {...props}\n >\n {children}\n </div>\n </TabsContext.Provider>\n );\n}\n\ntype TabsListProps = React.ComponentProps<'div'> & {\n children: React.ReactNode;\n activeClassName?: string;\n transition?: Transition;\n};\n\nfunction TabsList({\n children,\n className,\n activeClassName,\n transition = {\n type: 'spring',\n stiffness: 200,\n damping: 25,\n },\n ...props\n}: TabsListProps) {\n const { activeValue } = useTabs();\n\n return (\n <MotionHighlight\n controlledItems\n className={cn('rounded-sm bg-background shadow-sm', activeClassName)}\n value={activeValue}\n transition={transition}\n >\n <div\n role=\"tablist\"\n data-slot=\"tabs-list\"\n className={cn(\n 'bg-muted text-muted-foreground inline-flex h-10 w-fit items-center justify-center rounded-lg p-[4px]',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </MotionHighlight>\n );\n}\n\ntype TabsTriggerProps = HTMLMotionProps<'button'> & {\n value: string;\n children: React.ReactNode;\n};\n\nfunction TabsTrigger({\n ref,\n value,\n children,\n className,\n ...props\n}: TabsTriggerProps) {\n const { activeValue, handleValueChange, registerTrigger } = useTabs();\n\n const localRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLButtonElement);\n\n React.useEffect(() => {\n registerTrigger(value, localRef.current);\n return () => registerTrigger(value, null);\n }, [value, registerTrigger]);\n\n return (\n <MotionHighlightItem value={value} className=\"size-full\">\n <motion.button\n ref={localRef}\n data-slot=\"tabs-trigger\"\n role=\"tab\"\n whileTap={{ scale: 0.95 }}\n onClick={() => handleValueChange(value)}\n data-state={activeValue === value ? 'active' : 'inactive'}\n className={cn(\n 'inline-flex cursor-pointer items-center size-full justify-center whitespace-nowrap rounded-sm px-2 py-1 text-sm font-medium ring-offset-background transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground z-[1]',\n className,\n )}\n {...props}\n >\n {children}\n </motion.button>\n </MotionHighlightItem>\n );\n}\n\ntype TabsContentsProps = React.ComponentProps<'div'> & {\n children: React.ReactNode;\n transition?: Transition;\n};\n\nfunction TabsContents({\n children,\n className,\n transition = {\n type: 'spring',\n stiffness: 300,\n damping: 30,\n bounce: 0,\n restDelta: 0.01,\n },\n ...props\n}: TabsContentsProps) {\n const { activeValue } = useTabs();\n const childrenArray = React.Children.toArray(children);\n const activeIndex = childrenArray.findIndex(\n (child): child is React.ReactElement<{ value: string }> =>\n React.isValidElement(child) &&\n typeof child.props === 'object' &&\n child.props !== null &&\n 'value' in child.props &&\n child.props.value === activeValue,\n );\n\n return (\n <div\n data-slot=\"tabs-contents\"\n className={cn('overflow-hidden', className)}\n {...props}\n >\n <motion.div\n className=\"flex -mx-2\"\n animate={{ x: activeIndex * -100 + '%' }}\n transition={transition}\n >\n {childrenArray.map((child, index) => (\n <div key={index} className=\"w-full shrink-0 px-2\">\n {child}\n </div>\n ))}\n </motion.div>\n </div>\n );\n}\n\ntype TabsContentProps = HTMLMotionProps<'div'> & {\n value: string;\n children: React.ReactNode;\n};\n\nfunction TabsContent({\n children,\n value,\n className,\n ...props\n}: TabsContentProps) {\n const { activeValue } = useTabs();\n const isActive = activeValue === value;\n return (\n <motion.div\n role=\"tabpanel\"\n data-slot=\"tabs-content\"\n className={cn('overflow-hidden', className)}\n initial={{ filter: 'blur(0px)' }}\n animate={{ filter: isActive ? 'blur(0px)' : 'blur(4px)' }}\n exit={{ filter: 'blur(0px)' }}\n transition={{ type: 'spring', stiffness: 200, damping: 25 }}\n {...props}\n >\n {children}\n </motion.div>\n );\n}\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContents,\n TabsContent,\n useTabs,\n type TabsContextType,\n type TabsProps,\n type TabsListProps,\n type TabsTriggerProps,\n type TabsContentsProps,\n type TabsContentProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'tabs';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/tabs',
},
tooltip: {
name: 'tooltip',
description:
'An animated tooltip that shows contextual info on hover or focus and smoothly glides to the next element without disappearing between transitions.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/components/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/components/tooltip.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n motion,\n AnimatePresence,\n LayoutGroup,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\n\ntype Align = 'start' | 'center' | 'end';\n\ntype TooltipData = {\n content: React.ReactNode;\n rect: DOMRect;\n side: Side;\n sideOffset: number;\n align: Align;\n alignOffset: number;\n id: string;\n arrow: boolean;\n};\n\ntype GlobalTooltipContextType = {\n showTooltip: (data: TooltipData) => void;\n hideTooltip: () => void;\n currentTooltip: TooltipData | null;\n transition: Transition;\n globalId: string;\n};\n\nconst GlobalTooltipContext = React.createContext<\n GlobalTooltipContextType | undefined\n>(undefined);\n\nconst useGlobalTooltip = () => {\n const context = React.useContext(GlobalTooltipContext);\n if (!context) {\n throw new Error('useGlobalTooltip must be used within a TooltipProvider');\n }\n return context;\n};\n\ntype TooltipPosition = {\n x: number;\n y: number;\n transform: string;\n initial: { x?: number; y?: number };\n};\n\nfunction getTooltipPosition({\n rect,\n side,\n sideOffset,\n align,\n alignOffset,\n}: {\n rect: DOMRect;\n side: Side;\n sideOffset: number;\n align: Align;\n alignOffset: number;\n}): TooltipPosition {\n switch (side) {\n case 'top':\n if (align === 'start') {\n return {\n x: rect.left + alignOffset,\n y: rect.top - sideOffset,\n transform: 'translate(0, -100%)',\n initial: { y: 15 },\n };\n } else if (align === 'end') {\n return {\n x: rect.right + alignOffset,\n y: rect.top - sideOffset,\n transform: 'translate(-100%, -100%)',\n initial: { y: 15 },\n };\n } else {\n // center\n return {\n x: rect.left + rect.width / 2,\n y: rect.top - sideOffset,\n transform: 'translate(-50%, -100%)',\n initial: { y: 15 },\n };\n }\n case 'bottom':\n if (align === 'start') {\n return {\n x: rect.left + alignOffset,\n y: rect.bottom + sideOffset,\n transform: 'translate(0, 0)',\n initial: { y: -15 },\n };\n } else if (align === 'end') {\n return {\n x: rect.right + alignOffset,\n y: rect.bottom + sideOffset,\n transform: 'translate(-100%, 0)',\n initial: { y: -15 },\n };\n } else {\n // center\n return {\n x: rect.left + rect.width / 2,\n y: rect.bottom + sideOffset,\n transform: 'translate(-50%, 0)',\n initial: { y: -15 },\n };\n }\n case 'left':\n if (align === 'start') {\n return {\n x: rect.left - sideOffset,\n y: rect.top + alignOffset,\n transform: 'translate(-100%, 0)',\n initial: { x: 15 },\n };\n } else if (align === 'end') {\n return {\n x: rect.left - sideOffset,\n y: rect.bottom + alignOffset,\n transform: 'translate(-100%, -100%)',\n initial: { x: 15 },\n };\n } else {\n // center\n return {\n x: rect.left - sideOffset,\n y: rect.top + rect.height / 2,\n transform: 'translate(-100%, -50%)',\n initial: { x: 15 },\n };\n }\n case 'right':\n if (align === 'start') {\n return {\n x: rect.right + sideOffset,\n y: rect.top + alignOffset,\n transform: 'translate(0, 0)',\n initial: { x: -15 },\n };\n } else if (align === 'end') {\n return {\n x: rect.right + sideOffset,\n y: rect.bottom + alignOffset,\n transform: 'translate(0, -100%)',\n initial: { x: -15 },\n };\n } else {\n // center\n return {\n x: rect.right + sideOffset,\n y: rect.top + rect.height / 2,\n transform: 'translate(0, -50%)',\n initial: { x: -15 },\n };\n }\n }\n}\n\ntype TooltipProviderProps = {\n children: React.ReactNode;\n openDelay?: number;\n closeDelay?: number;\n transition?: Transition;\n};\n\nfunction TooltipProvider({\n children,\n openDelay = 700,\n closeDelay = 300,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n}: TooltipProviderProps) {\n const globalId = React.useId();\n const [currentTooltip, setCurrentTooltip] =\n React.useState<TooltipData | null>(null);\n const timeoutRef = React.useRef<number>(null);\n const lastCloseTimeRef = React.useRef<number>(0);\n\n const showTooltip = React.useCallback(\n (data: TooltipData) => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n if (currentTooltip !== null) {\n setCurrentTooltip(data);\n return;\n }\n const now = Date.now();\n const delay = now - lastCloseTimeRef.current < closeDelay ? 0 : openDelay;\n timeoutRef.current = window.setTimeout(\n () => setCurrentTooltip(data),\n delay,\n );\n },\n [openDelay, closeDelay, currentTooltip],\n );\n\n const hideTooltip = React.useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = window.setTimeout(() => {\n setCurrentTooltip(null);\n lastCloseTimeRef.current = Date.now();\n }, closeDelay);\n }, [closeDelay]);\n\n const hideImmediate = React.useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n setCurrentTooltip(null);\n lastCloseTimeRef.current = Date.now();\n }, []);\n\n React.useEffect(() => {\n window.addEventListener('scroll', hideImmediate, true);\n return () => window.removeEventListener('scroll', hideImmediate, true);\n }, [hideImmediate]);\n\n return (\n <GlobalTooltipContext.Provider\n value={{\n showTooltip,\n hideTooltip,\n currentTooltip,\n transition,\n globalId,\n }}\n >\n <LayoutGroup>{children}</LayoutGroup>\n <TooltipOverlay />\n </GlobalTooltipContext.Provider>\n );\n}\n\ntype TooltipArrowProps = {\n side: Side;\n};\n\nfunction TooltipArrow({ side }: TooltipArrowProps) {\n return (\n <div\n className={cn(\n 'absolute bg-primary z-50 size-2.5 rotate-45 rounded-[2px]',\n (side === 'top' || side === 'bottom') && 'left-1/2 -translate-x-1/2',\n (side === 'left' || side === 'right') && 'top-1/2 -translate-y-1/2',\n side === 'top' && '-bottom-[3px]',\n side === 'bottom' && '-top-[3px]',\n side === 'left' && '-right-[3px]',\n side === 'right' && '-left-[3px]',\n )}\n />\n );\n}\n\ntype TooltipPortalProps = {\n children: React.ReactNode;\n};\n\nfunction TooltipPortal({ children }: TooltipPortalProps) {\n const [isMounted, setIsMounted] = React.useState(false);\n React.useEffect(() => setIsMounted(true), []);\n return isMounted ? createPortal(children, document.body) : null;\n}\n\nfunction TooltipOverlay() {\n const { currentTooltip, transition, globalId } = useGlobalTooltip();\n\n const position = React.useMemo(() => {\n if (!currentTooltip) return null;\n return getTooltipPosition({\n rect: currentTooltip.rect,\n side: currentTooltip.side,\n sideOffset: currentTooltip.sideOffset,\n align: currentTooltip.align,\n alignOffset: currentTooltip.alignOffset,\n });\n }, [currentTooltip]);\n\n return (\n <AnimatePresence>\n {currentTooltip && currentTooltip.content && position && (\n <TooltipPortal>\n <motion.div\n data-slot=\"tooltip-overlay-container\"\n className=\"fixed z-50\"\n style={{\n top: position.y,\n left: position.x,\n transform: position.transform,\n }}\n >\n <motion.div\n data-slot=\"tooltip-overlay\"\n layoutId={`tooltip-overlay-${globalId}`}\n initial={{ opacity: 0, scale: 0, ...position.initial }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0, ...position.initial }}\n transition={transition}\n className=\"relative rounded-md bg-primary fill-primary px-3 py-1.5 text-sm text-primary-foreground shadow-md w-fit text-balance\"\n >\n {currentTooltip.content}\n\n {currentTooltip.arrow && (\n <TooltipArrow side={currentTooltip.side} />\n )}\n </motion.div>\n </motion.div>\n </TooltipPortal>\n )}\n </AnimatePresence>\n );\n}\n\ntype TooltipContextType = {\n content: React.ReactNode;\n setContent: React.Dispatch<React.SetStateAction<React.ReactNode>>;\n arrow: boolean;\n setArrow: React.Dispatch<React.SetStateAction<boolean>>;\n side: Side;\n sideOffset: number;\n align: Align;\n alignOffset: number;\n id: string;\n};\n\nconst TooltipContext = React.createContext<TooltipContextType | undefined>(\n undefined,\n);\n\nconst useTooltip = () => {\n const context = React.useContext(TooltipContext);\n if (!context) {\n throw new Error('useTooltip must be used within a TooltipProvider');\n }\n return context;\n};\n\ntype TooltipProps = {\n children: React.ReactNode;\n side?: Side;\n sideOffset?: number;\n align?: Align;\n alignOffset?: number;\n};\n\nfunction Tooltip({\n children,\n side = 'top',\n sideOffset = 14,\n align = 'center',\n alignOffset = 0,\n}: TooltipProps) {\n const id = React.useId();\n const [content, setContent] = React.useState<React.ReactNode>(null);\n const [arrow, setArrow] = React.useState(true);\n\n return (\n <TooltipContext.Provider\n value={{\n content,\n setContent,\n arrow,\n setArrow,\n side,\n sideOffset,\n align,\n alignOffset,\n id,\n }}\n >\n {children}\n </TooltipContext.Provider>\n );\n}\n\ntype TooltipContentProps = {\n children: React.ReactNode;\n arrow?: boolean;\n};\n\nfunction TooltipContent({ children, arrow = true }: TooltipContentProps) {\n const { setContent, setArrow } = useTooltip();\n React.useEffect(() => {\n setContent(children);\n setArrow(arrow);\n }, [children, setContent, setArrow, arrow]);\n return null;\n}\n\ntype TooltipTriggerProps = {\n children: React.ReactElement;\n};\n\nfunction TooltipTrigger({ children }: TooltipTriggerProps) {\n const { content, side, sideOffset, align, alignOffset, id, arrow } =\n useTooltip();\n const { showTooltip, hideTooltip, currentTooltip } = useGlobalTooltip();\n const triggerRef = React.useRef<HTMLElement>(null);\n\n const handleOpen = React.useCallback(() => {\n if (!triggerRef.current) return;\n const rect = triggerRef.current.getBoundingClientRect();\n showTooltip({\n content,\n rect,\n side,\n sideOffset,\n align,\n alignOffset,\n id,\n arrow,\n });\n }, [showTooltip, content, side, sideOffset, align, alignOffset, id, arrow]);\n\n const handleMouseEnter = React.useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n (children.props as React.HTMLAttributes<HTMLElement>)?.onMouseEnter?.(e);\n handleOpen();\n },\n [handleOpen, children.props],\n );\n\n const handleMouseLeave = React.useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n (children.props as React.HTMLAttributes<HTMLElement>)?.onMouseLeave?.(e);\n hideTooltip();\n },\n [hideTooltip, children.props],\n );\n\n const handleFocus = React.useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n (children.props as React.HTMLAttributes<HTMLElement>)?.onFocus?.(e);\n handleOpen();\n },\n [handleOpen, children.props],\n );\n\n const handleBlur = React.useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n (children.props as React.HTMLAttributes<HTMLElement>)?.onBlur?.(e);\n hideTooltip();\n },\n [hideTooltip, children.props],\n );\n\n React.useEffect(() => {\n if (currentTooltip?.id !== id) return;\n if (!triggerRef.current) return;\n\n if (currentTooltip.content === content && currentTooltip.arrow === arrow)\n return;\n\n const rect = triggerRef.current.getBoundingClientRect();\n showTooltip({\n content,\n rect,\n side,\n sideOffset,\n align,\n alignOffset,\n id,\n arrow,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [content, arrow, currentTooltip?.id]);\n\n return React.cloneElement(children, {\n ref: triggerRef,\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onFocus: handleFocus,\n onBlur: handleBlur,\n 'data-state': currentTooltip?.id === id ? 'open' : 'closed',\n 'data-side': side,\n 'data-align': align,\n 'data-slot': 'tooltip-trigger',\n } as React.HTMLAttributes<HTMLElement>);\n}\n\nexport {\n TooltipProvider,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n useGlobalTooltip,\n useTooltip,\n type TooltipProviderProps,\n type TooltipProps,\n type TooltipContentProps,\n type TooltipTriggerProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/components/tooltip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'tooltip';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/tooltip',
},
'bubble-background-demo': {
name: 'bubble-background-demo',
description: 'Demo showing an animated bubble background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/bubble-background'],
files: [
{
path: 'registry/demo/backgrounds/bubble/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/bubble.tsx',
content:
'import { BubbleBackground } from \'@/components/animate-ui/backgrounds/bubble\';\n\nexport const BubbleBackgroundDemo = () => {\n return (\n <BubbleBackground\n interactive\n className="absolute inset-0 flex items-center justify-center rounded-xl"\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/bubble/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bubble-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bubble-background-demo',
},
'fireworks-background-demo': {
name: 'fireworks-background-demo',
description: 'Demo showing an animated fireworks background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/fireworks-background'],
files: [
{
path: 'registry/demo/backgrounds/fireworks/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/fireworks.tsx',
content:
"'use client';\n\nimport { FireworksBackground } from '@/components/animate-ui/backgrounds/fireworks';\nimport { useTheme } from 'next-themes';\nexport default function FireworksBackgroundDemo() {\n const { resolvedTheme: theme } = useTheme();\n\n return (\n <FireworksBackground\n className=\"absolute inset-0 flex items-center justify-center rounded-xl\"\n color={theme === 'dark' ? 'white' : 'black'}\n />\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/fireworks/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fireworks-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/fireworks-background-demo',
},
'fireworks-background-fix-size-speed-demo': {
name: 'fireworks-background-fix-size-speed-demo',
description:
'Demo showing an animated fireworks background with fixed size and speed.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/fireworks-background'],
files: [
{
path: 'registry/demo/backgrounds/fireworks-fix-size-speed/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/backgrounds/fireworks-fix-size-speed.tsx',
content:
"'use client';\n\nimport { FireworksBackground } from '@/components/animate-ui/backgrounds/fireworks';\n\nexport default function FireworksBackgroundFixSizeSpeedDemo() {\n return (\n <FireworksBackground\n className=\"absolute inset-0 flex items-center justify-center rounded-xl\"\n fireworkSize={7}\n fireworkSpeed={7}\n particleSize={7}\n particleSpeed={7}\n />\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/fireworks-fix-size-speed/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fireworks-background-fix-size-speed-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command:
'https://animate-ui.com/r/fireworks-background-fix-size-speed-demo',
},
'fireworks-background-population-demo': {
name: 'fireworks-background-population-demo',
description:
'Demo showing an animated fireworks background with a higher population.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/fireworks-background'],
files: [
{
path: 'registry/demo/backgrounds/fireworks-population/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/backgrounds/fireworks-population.tsx',
content:
"'use client';\n\nimport { FireworksBackground } from '@/components/animate-ui/backgrounds/fireworks';\n\nexport default function FireworksBackgroundPopulationDemo() {\n return (\n <FireworksBackground\n className=\"absolute inset-0 flex items-center justify-center rounded-xl\"\n population={8}\n />\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/fireworks-population/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fireworks-background-population-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/fireworks-background-population-demo',
},
'fireworks-background-size-speed-demo': {
name: 'fireworks-background-size-speed-demo',
description:
'Demo showing an animated fireworks background with high size and speed.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/fireworks-background'],
files: [
{
path: 'registry/demo/backgrounds/fireworks-size-speed/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/backgrounds/fireworks-size-speed.tsx',
content:
"'use client';\n\nimport { FireworksBackground } from '@/components/animate-ui/backgrounds/fireworks';\n\nexport default function FireworksBackgroundSizeSpeedDemo() {\n return (\n <FireworksBackground\n className=\"absolute inset-0 flex items-center justify-center rounded-xl\"\n fireworkSpeed={{ min: 8, max: 16 }}\n fireworkSize={{ min: 4, max: 10 }}\n particleSpeed={{ min: 4, max: 14 }}\n particleSize={{ min: 2, max: 10 }}\n />\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/fireworks-size-speed/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fireworks-background-size-speed-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/fireworks-background-size-speed-demo',
},
'gradient-background-demo': {
name: 'gradient-background-demo',
description: 'Demo showing an animated gradient background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/gradient-background'],
files: [
{
path: 'registry/demo/backgrounds/gradient/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/gradient.tsx',
content:
'import { GradientBackground } from \'@/components/animate-ui/backgrounds/gradient\';\n\nexport const GradientBackgroundDemo = () => {\n return (\n <GradientBackground className="absolute inset-0 flex items-center justify-center rounded-xl" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/gradient/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gradient-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gradient-background-demo',
},
'hexagon-background-demo': {
name: 'hexagon-background-demo',
description: 'Demo showing an animated hexagon background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/hexagon-background'],
files: [
{
path: 'registry/demo/backgrounds/hexagon/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/hexagon.tsx',
content:
'import { HexagonBackground } from \'@/components/animate-ui/backgrounds/hexagon\';\n\nexport const HexagonBackgroundDemo = () => {\n return (\n <HexagonBackground className="absolute inset-0 flex items-center justify-center rounded-xl" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/backgrounds/hexagon/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'hexagon-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/hexagon-background-demo',
},
'hole-background-demo': {
name: 'hole-background-demo',
description: 'Demo showing an animated hole background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/hole-background'],
files: [
{
path: 'registry/demo/backgrounds/hole/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/hole.tsx',
content:
'import { HoleBackground } from \'@/components/animate-ui/backgrounds/hole\';\n\nexport const HoleBackgroundDemo = () => {\n return (\n <HoleBackground className="absolute inset-0 flex items-center justify-center rounded-xl" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/backgrounds/hole/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'hole-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/hole-background-demo',
},
'stars-background-demo': {
name: 'stars-background-demo',
description: 'Demo showing an animated stars background.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/stars-background'],
files: [
{
path: 'registry/demo/backgrounds/stars/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/backgrounds/stars.tsx',
content:
'import { StarsBackground } from \'@/components/animate-ui/backgrounds/stars\';\n\nexport const StarsBackgroundDemo = () => {\n return (\n <StarsBackground className="absolute inset-0 flex items-center justify-center rounded-xl" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/backgrounds/stars/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'stars-background-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/stars-background-demo',
},
'base-accordion-demo': {
name: 'base-accordion-demo',
description: 'Demo showing a base accordion.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-accordion'],
files: [
{
path: 'registry/demo/base/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/accordion.tsx',
content:
'import {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionPanel,\n} from \'@/components/animate-ui/base/accordion\';\n\ninterface BaseAccordionDemoProps {\n multiple: boolean;\n}\n\nexport const BaseAccordionDemo = ({ multiple }: BaseAccordionDemoProps) => {\n return (\n <Accordion\n defaultValue={[\'item-1\']}\n openMultiple={multiple}\n className="max-w-[400px] w-full"\n >\n <AccordionItem value="item-1">\n <AccordionTrigger>What is Animate UI?</AccordionTrigger>\n <AccordionPanel>\n Animate UI is an open-source distribution of React components built\n with TypeScript, Tailwind CSS, and Motion.\n </AccordionPanel>\n </AccordionItem>\n\n <AccordionItem value="item-2">\n <AccordionTrigger>\n How is it different from other libraries?\n </AccordionTrigger>\n <AccordionPanel>\n Instead of installing via NPM, you copy and paste the components\n directly. This gives you full control to modify or customize them as\n needed.\n </AccordionPanel>\n </AccordionItem>\n\n <AccordionItem value="item-3">\n <AccordionTrigger>Is Animate UI free to use?</AccordionTrigger>\n <AccordionPanel>\n Absolutely! Animate UI is fully open-source. You can use, modify, and\n adapt it to fit your needs.\n </AccordionPanel>\n </AccordionItem>\n </Accordion>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/accordion/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-accordion-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = { Accordion: { multiple: { value: false } } };
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-accordion-demo',
},
'base-checkbox-demo': {
name: 'base-checkbox-demo',
description: 'Demo showing a base checkbox.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-checkbox', 'label'],
files: [
{
path: 'registry/demo/base/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/checkbox.tsx',
content:
'import { Label } from \'@/components/ui/label\';\nimport { Checkbox } from \'@/components/animate-ui/base/checkbox\';\n\nexport const BaseCheckboxDemo = () => {\n return (\n <div className="flex items-center space-x-2">\n <Checkbox defaultChecked id="terms" />\n <Label htmlFor="terms">Accept terms and conditions</Label>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-checkbox-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-checkbox-demo',
},
'base-popover-demo': {
name: 'base-popover-demo',
description: 'Demo showing a base popover.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/base-popover',
'button',
'input',
'label',
],
files: [
{
path: 'registry/demo/base/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/popover.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport { Label } from \'@/components/ui/label\';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n type Side,\n type Align,\n} from \'@/components/animate-ui/base/popover\';\n\ninterface BasePopoverDemoProps {\n side?: Side;\n sideOffset?: number;\n align?: Align;\n alignOffset?: number;\n openOnHover?: boolean;\n delay?: number;\n closeDelay?: number;\n}\n\nexport const BasePopoverDemo = ({\n side,\n sideOffset,\n align,\n alignOffset,\n openOnHover,\n delay,\n closeDelay,\n}: BasePopoverDemoProps) => {\n return (\n <Popover openOnHover={openOnHover} delay={delay} closeDelay={closeDelay}>\n <PopoverTrigger\n render={<Button variant="outline">Open popover</Button>}\n />\n <PopoverContent\n className="w-80"\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n >\n <div className="grid gap-4">\n <div className="space-y-2">\n <h4 className="font-medium leading-none">Dimensions</h4>\n <p className="text-sm text-muted-foreground">\n Set the dimensions for the layer.\n </p>\n </div>\n <div className="grid gap-2">\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="width">Width</Label>\n <Input\n id="width"\n defaultValue="100%"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxWidth">Max. width</Label>\n <Input\n id="maxWidth"\n defaultValue="300px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="height">Height</Label>\n <Input\n id="height"\n defaultValue="25px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxHeight">Max. height</Label>\n <Input\n id="maxHeight"\n defaultValue="none"\n className="col-span-2 h-8"\n />\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-popover-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
Popover: {
openOnHover: { value: false },
delay: { value: 300 },
closeDelay: { value: 0 },
},
PopoverContent: {
side: {
value: 'bottom',
options: {
top: 'top',
bottom: 'bottom',
left: 'left',
right: 'right',
'inline-start': 'inline-start',
'inline-end': 'inline-end',
},
},
align: {
value: 'center',
options: { start: 'start', center: 'center', end: 'end' },
},
sideOffset: { value: 4 },
alignOffset: { value: 0 },
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-popover-demo',
},
'base-preview-card-demo': {
name: 'base-preview-card-demo',
description: 'Demo showing a base preview card.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-preview-card'],
files: [
{
path: 'registry/demo/base/preview-card/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/preview-card.tsx',
content:
'import {\n PreviewCard,\n PreviewCardTrigger,\n PreviewCardContent,\n type PreviewCardProps,\n type PreviewCardContentProps,\n} from \'@/components/animate-ui/base/preview-card\';\n\ntype BasePreviewCardDemoProps = Pick<PreviewCardProps, \'delay\' | \'closeDelay\'> &\n Pick<\n PreviewCardContentProps,\n \'side\' | \'sideOffset\' | \'align\' | \'alignOffset\'\n >;\n\nexport const BasePreviewCardDemo = ({\n delay,\n closeDelay,\n side,\n sideOffset,\n align,\n alignOffset,\n}: BasePreviewCardDemoProps) => {\n return (\n <PreviewCard delay={delay} closeDelay={closeDelay} defaultOpen>\n <PreviewCardTrigger\n render={\n <a\n className="size-12 rounded-full overflow-hidden border"\n href="https://twitter.com/animate_ui"\n target="_blank"\n rel="noreferrer noopener"\n >\n <img\n src="https://pbs.twimg.com/profile_images/1904970066770214912/lYBctz26_400x400.jpg"\n alt="Animate UI"\n />\n </a>\n }\n />\n <PreviewCardContent\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n className="w-80"\n >\n <div className="flex flex-col gap-4">\n <img\n className="size-16 rounded-full overflow-hidden border"\n src="https://pbs.twimg.com/profile_images/1904970066770214912/lYBctz26_400x400.jpg"\n alt="Animate UI"\n />\n <div className="flex flex-col gap-4">\n <div>\n <div className="font-bold">Animate UI</div>\n <div className="text-sm text-muted-foreground">@animate_ui</div>\n </div>\n <div className="text-sm text-muted-foreground">\n A fully animated, open-source component distribution built with\n React, TypeScript, Tailwind CSS, and Motion.\n </div>\n <div className="flex gap-4">\n <div className="flex gap-1 text-sm items-center">\n <div className="font-bold">0</div>{\' \'}\n <div className="text-muted-foreground">Following</div>\n </div>\n <div className="flex gap-1 text-sm items-center">\n <div className="font-bold">2,900</div>{\' \'}\n <div className="text-muted-foreground">Followers</div>\n </div>\n </div>\n </div>\n </div>\n </PreviewCardContent>\n </PreviewCard>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/preview-card/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-preview-card-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
PreviewCard: {
delay: { value: 600, min: 0, max: 2000, step: 100 },
closeDelay: { value: 300, min: 0, max: 2000, step: 100 },
},
PreviewCardContent: {
side: {
value: 'bottom',
options: {
top: 'top',
bottom: 'bottom',
left: 'left',
right: 'right',
'inline-start': 'inline-start',
'inline-end': 'inline-end',
},
},
sideOffset: { value: 10 },
align: {
value: 'center',
options: { start: 'start', center: 'center', end: 'end' },
},
alignOffset: { value: 0 },
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-preview-card-demo',
},
'base-progress-demo': {
name: 'base-progress-demo',
description: 'Demo showing a base progress.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-progress'],
files: [
{
path: 'registry/demo/base/progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/progress.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport {\n Progress,\n ProgressLabel,\n ProgressTrack,\n ProgressValue,\n} from \'@/components/animate-ui/base/progress\';\n\nexport const BaseProgressDemo = () => {\n const [progress, setProgress] = React.useState(0);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setProgress((prev) => {\n if (prev >= 100) return 100;\n return prev + 25;\n });\n }, 2000);\n return () => clearInterval(timer);\n }, []);\n\n React.useEffect(() => {\n if (progress >= 100) setTimeout(() => setProgress(0), 4000);\n }, [progress]);\n\n return (\n <Progress value={progress} className="w-[300px] space-y-2">\n <div className="flex items-center justify-between gap-1">\n <ProgressLabel className="text-sm font-medium">\n Export data\n </ProgressLabel>\n <span className="text-sm">\n <ProgressValue /> %\n </span>\n </div>\n <ProgressTrack />\n </Progress>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/progress/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-progress-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-progress-demo',
},
'base-switch-demo': {
name: 'base-switch-demo',
description: 'Demo showing a base switch.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-switch', 'label'],
files: [
{
path: 'registry/demo/base/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/switch.tsx',
content:
"'use client';\n\nimport { useState } from 'react';\nimport { MoonIcon, SunIcon } from 'lucide-react';\n\nimport { Label } from '@/components/ui/label';\nimport { Switch } from '@/components/animate-ui/base/switch';\n\ninterface BaseSwitchDemoProps {\n leftIcon?: boolean;\n rightIcon?: boolean;\n thumbIcon?: boolean;\n}\n\nexport const BaseSwitchDemo = ({\n leftIcon,\n rightIcon,\n thumbIcon,\n}: BaseSwitchDemoProps) => {\n const [checked, setChecked] = useState(true);\n\n const ThumbIcon = checked ? <MoonIcon /> : <SunIcon />;\n\n return (\n <div className=\"flex items-center space-x-2\">\n <Label htmlFor=\"switch-theme\">Switch theme</Label>\n <Switch\n checked={checked}\n onCheckedChange={setChecked}\n id=\"switch-theme\"\n leftIcon={leftIcon ? <MoonIcon /> : null}\n rightIcon={rightIcon ? <SunIcon /> : null}\n thumbIcon={thumbIcon ? ThumbIcon : null}\n />\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-switch-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
Switch: {
leftIcon: { value: false },
rightIcon: { value: false },
thumbIcon: { value: false },
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-switch-demo',
},
'base-toggle-group-demo': {
name: 'base-toggle-group-demo',
description: 'Demo showing a base toggle group.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-toggle-group'],
files: [
{
path: 'registry/demo/base/toggle-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/toggle-group.tsx',
content:
'import { ToggleGroup, ToggleGroupItem } from \'@/components/animate-ui/base/toggle-group\';\nimport { Bold, Italic, Underline } from \'lucide-react\';\n\ninterface BaseToggleGroupDemoProps {\n multiple: boolean;\n size: \'default\' | \'sm\' | \'lg\';\n variant: \'default\' | \'outline\';\n}\n\nexport const BaseToggleGroupDemo = ({\n multiple,\n size,\n variant,\n}: BaseToggleGroupDemoProps) => {\n return (\n <ToggleGroup\n defaultValue={[\'bold\']}\n toggleMultiple={multiple}\n size={size}\n variant={variant}\n >\n <ToggleGroupItem value="bold" aria-label="Toggle bold">\n <Bold className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="italic" aria-label="Toggle italic">\n <Italic className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="underline" aria-label="Toggle underline">\n <Underline className="h-4 w-4" />\n </ToggleGroupItem>\n </ToggleGroup>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/toggle-group/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-toggle-group-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
ToggleGroup: {
multiple: { value: false },
size: {
value: 'default',
options: { default: 'default', sm: 'sm', lg: 'lg' },
},
variant: {
value: 'default',
options: { default: 'default', outline: 'outline' },
},
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-toggle-group-demo',
},
'base-tooltip-demo': {
name: 'base-tooltip-demo',
description: 'Demo showing a base tooltip.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/base-tooltip'],
files: [
{
path: 'registry/demo/base/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/base/tooltip.tsx',
content:
"import { Button } from '@/components/ui/button';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n type TooltipProviderProps,\n type TooltipContentProps,\n} from '@/components/animate-ui/base/tooltip';\n\ntype BaseTooltipDemoProps = Pick<TooltipProviderProps, 'delay' | 'closeDelay'> &\n Pick<\n TooltipContentProps,\n 'side' | 'sideOffset' | 'align' | 'alignOffset' | 'arrow'\n >;\n\nexport const BaseTooltipDemo = ({\n delay,\n closeDelay,\n side,\n sideOffset,\n align,\n alignOffset,\n arrow,\n}: BaseTooltipDemoProps) => {\n return (\n <TooltipProvider delay={delay} closeDelay={closeDelay}>\n <Tooltip defaultOpen>\n <TooltipTrigger render={<Button variant=\"outline\">Hover me</Button>} />\n <TooltipContent\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n arrow={arrow}\n >\n <p>Add to library</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/base/tooltip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'base-tooltip-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
TooltipProvider: {
delay: { value: 600, min: 0, max: 2000, step: 100 },
closeDelay: { value: 0, min: 0, max: 2000, step: 100 },
},
TooltipContent: {
side: {
value: 'top',
options: {
top: 'top',
bottom: 'bottom',
left: 'left',
right: 'right',
'inline-start': 'inline-start',
'inline-end': 'inline-end',
},
},
sideOffset: { value: 10 },
align: {
value: 'center',
options: { start: 'start', center: 'center', end: 'end' },
},
alignOffset: { value: 0 },
arrow: { value: true, disableVariants: ['shadcn-default'] },
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/base-tooltip-demo',
},
'copy-button-demo': {
name: 'copy-button-demo',
description:
'Demo showing an animated button with copy to clipboard effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/copy-button'],
files: [
{
path: 'registry/demo/buttons/copy/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/copy.tsx',
content:
'import { CopyButton } from \'@/components/animate-ui/buttons/copy\';\n\nexport const CopyButtonDemo = () => {\n return <CopyButton content="Content to copy" size="md" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/copy/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'copy-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/copy-button-demo',
},
'flip-button-demo': {
name: 'flip-button-demo',
description: 'Demo showing an animated button with flip effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/flip-button'],
files: [
{
path: 'registry/demo/buttons/flip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/flip.tsx',
content:
'import { FlipButton } from \'@/components/animate-ui/buttons/flip\';\n\nexport const FlipButtonDemo = () => {\n return <FlipButton frontText="Front Text" backText="Back Text" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/flip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'flip-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/flip-button-demo',
},
'flip-button-from-demo': {
name: 'flip-button-from-demo',
description: 'Demo showing an animated button with flip effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/flip-button'],
files: [
{
path: 'registry/demo/buttons/flip-from/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/flip-from.tsx',
content:
'import { FlipButton } from \'@/components/animate-ui/buttons/flip\';\n\nexport const FlipButtonFromDemo = () => {\n return <FlipButton frontText="Front Text" backText="Back Text" from="left" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/flip-from/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'flip-button-from-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/flip-button-from-demo',
},
'github-stars-button-demo': {
name: 'github-stars-button-demo',
description: 'Demo showing a GitHub stars button.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/github-stars-button'],
files: [
{
path: 'registry/demo/buttons/github-stars/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/github-stars.tsx',
content:
'import { GitHubStarsButton } from \'@/components/animate-ui/buttons/github-stars\';\n\nexport const GitHubStarsButtonDemo = () => {\n return <GitHubStarsButton username="animate-ui" repo="animate-ui" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/buttons/github-stars/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'github-stars-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/github-stars-button-demo',
},
'icon-button-demo': {
name: 'icon-button-demo',
description: 'Demo showing an icon button.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/icon-button'],
files: [
{
path: 'registry/demo/buttons/icon/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/icon.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Star } from 'lucide-react';\n\nimport { IconButton } from '@/components/animate-ui/buttons/icon';\n\nexport const IconButtonDemo = () => {\n const [active, setActive] = React.useState(false);\n\n return (\n <IconButton\n icon={Star}\n active={active}\n onClick={() => setActive(!active)}\n />\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/icon/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'icon-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/icon-button-demo',
},
'input-button-demo': {
name: 'input-button-demo',
description: 'Demo showing an animated button with input effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/input-button'],
files: [
{
path: 'registry/demo/buttons/input/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/input.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n InputButton,\n InputButtonAction,\n InputButtonProvider,\n InputButtonSubmit,\n InputButtonInput,\n} from '@/components/animate-ui/buttons/input';\n\nexport const InputButtonDemo = () => {\n return (\n <InputButtonProvider>\n <InputButton>\n <InputButtonAction>Join the newsletter</InputButtonAction>\n <InputButtonSubmit>Subscribe</InputButtonSubmit>\n </InputButton>\n <InputButtonInput type=\"email\" placeholder=\"your-email@example.com\" />\n </InputButtonProvider>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/input/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'input-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/input-button-demo',
},
'input-button-loading-demo': {
name: 'input-button-loading-demo',
description: 'Demo showing an animated button with input effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/input-button'],
files: [
{
path: 'registry/demo/buttons/input-loading/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/input-loading.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n InputButton,\n InputButtonAction,\n InputButtonProvider,\n InputButtonSubmit,\n InputButtonInput,\n} from '@/components/animate-ui/buttons/input';\nimport { Check, Loader2 } from 'lucide-react';\nimport { motion } from 'motion/react';\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport const InputButtonLoadingDemo = () => {\n const [showInput, setShowInput] = React.useState(false);\n const [pending, startTransition] = React.useTransition();\n const [success, setSuccess] = React.useState(false);\n const [value, setValue] = React.useState('');\n\n const handleSubmit = React.useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (!showInput) {\n setShowInput(true);\n return;\n }\n\n startTransition(async () => {\n await sleep(2000);\n setSuccess(true);\n await sleep(2000);\n setSuccess(false);\n setShowInput(false);\n setValue('');\n });\n },\n [showInput, setShowInput, setSuccess, setValue],\n );\n\n return (\n <form\n onSubmit={handleSubmit}\n className=\"w-full flex items-center justify-center\"\n >\n <InputButtonProvider showInput={showInput} setShowInput={setShowInput}>\n <InputButton>\n <InputButtonAction onClick={() => {}}>\n Join the newsletter\n </InputButtonAction>\n <InputButtonSubmit\n onClick={() => {}}\n type=\"submit\"\n disabled={pending}\n className={pending || success ? 'aspect-square px-0' : ''}\n >\n {success ? (\n <motion.span\n key=\"success\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.2 }}\n >\n <Check />\n </motion.span>\n ) : pending ? (\n <motion.span\n key=\"pending\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ duration: 0.2 }}\n >\n <Loader2 className=\"animate-spin\" />\n </motion.span>\n ) : (\n 'Subscribe'\n )}\n </InputButtonSubmit>\n </InputButton>\n <InputButtonInput\n type=\"email\"\n placeholder=\"your-email@example.com\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n disabled={pending}\n autoFocus\n />\n </InputButtonProvider>\n </form>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/buttons/input-loading/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'input-button-loading-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/input-button-loading-demo',
},
'liquid-button-demo': {
name: 'liquid-button-demo',
description: 'Demo showing an animated button with liquid effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/liquid-button'],
files: [
{
path: 'registry/demo/buttons/liquid/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/liquid.tsx',
content:
"import { LiquidButton } from '@/components/animate-ui/buttons/liquid';\n\nexport const LiquidButtonDemo = () => {\n return <LiquidButton>Liquid Button</LiquidButton>;\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/liquid/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'liquid-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/liquid-button-demo',
},
'ripple-button-demo': {
name: 'ripple-button-demo',
description: 'Demo showing an animated button with ripple effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/ripple-button'],
files: [
{
path: 'registry/demo/buttons/ripple/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/buttons/ripple.tsx',
content:
"import { RippleButton } from '@/components/animate-ui/buttons/ripple';\n\nexport const RippleButtonDemo = () => {\n return <RippleButton>Ripple Button</RippleButton>;\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/buttons/ripple/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'ripple-button-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/ripple-button-demo',
},
'avatar-group-demo': {
name: 'avatar-group-demo',
description: 'Demo showing an animated avatar group.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/avatar-group'],
files: [
{
path: 'registry/demo/components/avatar-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/avatar-group.tsx',
content:
"import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport {\n AvatarGroup,\n AvatarGroupTooltip,\n} from '@/components/animate-ui/components/avatar-group';\n\nconst AVATARS = [\n {\n src: 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n fallback: 'SK',\n tooltip: 'Skyleen',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1593304942210478080/TUYae5z7_400x400.jpg',\n fallback: 'CN',\n tooltip: 'Shadcn',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1677042510839857154/Kq4tpySA_400x400.jpg',\n fallback: 'AW',\n tooltip: 'Adam Wathan',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1783856060249595904/8TfcCN0r_400x400.jpg',\n fallback: 'GR',\n tooltip: 'Guillermo Rauch',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1534700564810018816/anAuSfkp_400x400.jpg',\n fallback: 'JH',\n tooltip: 'Jhey',\n },\n];\n\nexport const AvatarGroupDemo = () => {\n return (\n <AvatarGroup className=\"h-12 -space-x-3\">\n {AVATARS.map((avatar, index) => (\n <Avatar key={index} className=\"size-12 border-3 border-background\">\n <AvatarImage src={avatar.src} />\n <AvatarFallback>{avatar.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{avatar.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n ))}\n </AvatarGroup>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/avatar-group/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group-demo',
},
'avatar-group-bottom-demo': {
name: 'avatar-group-bottom-demo',
description:
'Demo showing an animated avatar group with the tooltip on the bottom.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/avatar-group'],
files: [
{
path: 'registry/demo/components/avatar-group-bottom/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/avatar-group-bottom.tsx',
content:
"import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport {\n AvatarGroup,\n AvatarGroupTooltip,\n} from '@/components/animate-ui/components/avatar-group';\n\nconst AVATARS = [\n {\n src: 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n fallback: 'SK',\n tooltip: 'Skyleen',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1593304942210478080/TUYae5z7_400x400.jpg',\n fallback: 'CN',\n tooltip: 'Shadcn',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1677042510839857154/Kq4tpySA_400x400.jpg',\n fallback: 'AW',\n tooltip: 'Adam Wathan',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1783856060249595904/8TfcCN0r_400x400.jpg',\n fallback: 'GR',\n tooltip: 'Guillermo Rauch',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1534700564810018816/anAuSfkp_400x400.jpg',\n fallback: 'JH',\n tooltip: 'Jhey',\n },\n];\n\nexport const AvatarGroupDemo = () => {\n return (\n <AvatarGroup\n invertOverlap\n className=\"h-12 -space-x-3\"\n tooltipProps={{ side: 'bottom', sideOffset: 24 }}\n translate=\"30%\"\n >\n {AVATARS.map((avatar, index) => (\n <Avatar key={index} className=\"size-12 border-3 border-background\">\n <AvatarImage src={avatar.src} />\n <AvatarFallback>{avatar.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{avatar.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n ))}\n </AvatarGroup>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/avatar-group-bottom/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group-bottom-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group-bottom-demo',
},
'avatar-group-mask-demo': {
name: 'avatar-group-mask-demo',
description: 'Demo showing an animated avatar group mask.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/avatar-group-mask'],
files: [
{
path: 'registry/demo/components/avatar-group-mask/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/avatar-group-mask.tsx',
content:
"import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport {\n AvatarGroup,\n AvatarGroupTooltip,\n} from '@/components/animate-ui/components/avatar-group-mask';\n\nconst AVATARS = [\n {\n src: 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n fallback: 'SK',\n tooltip: 'Skyleen',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1593304942210478080/TUYae5z7_400x400.jpg',\n fallback: 'CN',\n tooltip: 'Shadcn',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1677042510839857154/Kq4tpySA_400x400.jpg',\n fallback: 'AW',\n tooltip: 'Adam Wathan',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1783856060249595904/8TfcCN0r_400x400.jpg',\n fallback: 'GR',\n tooltip: 'Guillermo Rauch',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1534700564810018816/anAuSfkp_400x400.jpg',\n fallback: 'JH',\n tooltip: 'Jhey',\n },\n];\n\nexport const AvatarGroupMaskDemo = () => {\n return (\n <div className=\"bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 p-0.5 rounded-full\">\n <div className=\"bg-gradient-to-r from-indigo-100 via-purple-100 to-pink-100 dark:from-indigo-950 dark:via-purple-950 dark:to-pink-950 p-1.5 rounded-full\">\n <AvatarGroup>\n {AVATARS.map((avatar, index) => (\n <Avatar key={index}>\n <AvatarImage src={avatar.src} />\n <AvatarFallback>{avatar.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{avatar.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n ))}\n </AvatarGroup>\n </div>\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/avatar-group-mask/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group-mask-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group-mask-demo',
},
'avatar-group-mask-bottom-demo': {
name: 'avatar-group-mask-bottom-demo',
description:
'Demo showing an animated avatar group mask with bottom translation.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/avatar-group-mask'],
files: [
{
path: 'registry/demo/components/avatar-group-mask-bottom/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/components/avatar-group-mask-bottom.tsx',
content:
"import {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport {\n AvatarGroup,\n AvatarGroupTooltip,\n} from '@/components/animate-ui/components/avatar-group-mask';\n\nconst AVATARS = [\n {\n src: 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n fallback: 'SK',\n tooltip: 'Skyleen',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1593304942210478080/TUYae5z7_400x400.jpg',\n fallback: 'CN',\n tooltip: 'Shadcn',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1677042510839857154/Kq4tpySA_400x400.jpg',\n fallback: 'AW',\n tooltip: 'Adam Wathan',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1783856060249595904/8TfcCN0r_400x400.jpg',\n fallback: 'GR',\n tooltip: 'Guillermo Rauch',\n },\n {\n src: 'https://pbs.twimg.com/profile_images/1534700564810018816/anAuSfkp_400x400.jpg',\n fallback: 'JH',\n tooltip: 'Jhey',\n },\n];\n\nexport const AvatarGroupMaskBottomDemo = () => {\n return (\n <div className=\"bg-gradient-to-r from-indigo-500 from-10% via-sky-500 via-30% to-emerald-500 to-90% p-0.5 rounded-full\">\n <div className=\"bg-gradient-to-r from-indigo-100 dark:from-indigo-950 from-10% via-sky-100 dark:via-sky-950 via-30% to-emerald-100 dark:to-emerald-950 to-90% p-1.5 rounded-full\">\n <AvatarGroup\n invertOverlap\n align=\"start\"\n translate={50}\n tooltipProps={{ side: 'bottom', sideOffset: 12 }}\n >\n {AVATARS.map((avatar, index) => (\n <Avatar key={index}>\n <AvatarImage src={avatar.src} />\n <AvatarFallback>{avatar.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{avatar.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n ))}\n </AvatarGroup>\n </div>\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/avatar-group-mask-bottom/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'avatar-group-mask-bottom-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/avatar-group-mask-bottom-demo',
},
'code-editor-demo': {
name: 'code-editor-demo',
description: 'Demo showing an animated code editor.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/code-editor'],
files: [
{
path: 'registry/demo/components/code-editor/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/code-editor.tsx',
content:
"import ReactIcon from '@/components/icons/react-icon';\nimport { CodeEditor } from '@/components/animate-ui/components/code-editor';\n\nexport const CodeEditorDemo = () => {\n return (\n <CodeEditor\n cursor\n className=\"w-[640px] h-[480px]\"\n lang=\"tsx\"\n title=\"component.tsx\"\n icon={<ReactIcon />}\n duration={15}\n delay={0.5}\n copyButton\n >\n {`'use client';\n\nimport * as React from 'react';\n\ntype MyComponentProps = {\n myProps: string;\n} & React.HTMLAttributes<HTMLDivElement>;\n\nconst MyComponent = React.forwardRef<HTMLDivElement, MyComponentProps>(\n ({ myProps, ...props }, ref) => {\n return (\n <div ref={ref} {...props}>\n <p>My Component</p>\n </div>\n );\n },\n);\nMyComponent.displayName = 'MyComponent';\n\nexport { MyComponent, type MyComponentProps };`}\n </CodeEditor>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/code-editor/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'code-editor-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/code-editor-demo',
},
'code-tabs-demo': {
name: 'code-tabs-demo',
description: 'Demo showing a code tabs.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/code-tabs'],
files: [
{
path: 'registry/demo/components/code-tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/code-tabs.tsx',
content:
'import { CodeTabs } from \'@/components/animate-ui/components/code-tabs\';\n\nconst CODES = {\n Cursor: `// Copy and paste the code into .cursor/mcp.json\n{\n "mcpServers": {\n "shadcn": {\n "command": "npx",\n "args": ["-y", "shadcn@canary", "registry:mcp"],\n "env": {\n "REGISTRY_URL": "https://animate-ui.com/r/registry.json"\n }\n }\n }\n}`,\n Windsurf: `// Copy and paste the code into .codeium/windsurf/mcp_config.json\n{\n "mcpServers": {\n "shadcn": {\n "command": "npx",\n "args": ["-y", "shadcn@canary", "registry:mcp"],\n "env": {\n "REGISTRY_URL": "https://animate-ui.com/r/registry.json"\n }\n }\n }\n}`,\n};\n\nexport const CodeTabsDemo = () => {\n return <CodeTabs lang="json" codes={CODES} />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/code-tabs/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'code-tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/code-tabs-demo',
},
'counter-demo': {
name: 'counter-demo',
description: 'Demo showing an animated counter.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/counter'],
files: [
{
path: 'registry/demo/components/counter/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/counter.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { Counter } from '@/components/animate-ui/components/counter';\n\nexport const CounterDemo = () => {\n const [number, setNumber] = React.useState(100);\n\n return <Counter number={number} setNumber={setNumber} />;\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/counter/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counter-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counter-demo',
},
'cursor-demo': {
name: 'cursor-demo',
description: 'Demo showing a cursor component.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/cursor'],
files: [
{
path: 'registry/demo/components/cursor/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/cursor.tsx',
content:
'import {\n Cursor,\n CursorFollow,\n CursorProvider,\n} from \'@/components/animate-ui/components/cursor\';\n\nexport const CursorDemo = () => {\n return (\n <div className="max-w-[400px] h-[400px] w-full rounded-xl bg-muted flex items-center justify-center">\n <p className="font-medium italic text-muted-foreground">\n Move your mouse over the div\n </p>\n <CursorProvider>\n <Cursor>\n <svg\n className="size-6 text-blue-500"\n xmlns="http://www.w3.org/2000/svg"\n viewBox="0 0 40 40"\n >\n <path\n fill="currentColor"\n d="M1.8 4.4 7 36.2c.3 1.8 2.6 2.3 3.6.8l3.9-5.7c1.7-2.5 4.5-4.1 7.5-4.3l6.9-.5c1.8-.1 2.5-2.4 1.1-3.5L5 2.5c-1.4-1.1-3.5 0-3.3 1.9Z"\n />\n </svg>\n </Cursor>\n <CursorFollow>\n <div className="bg-blue-500 text-white px-2 py-1 rounded-lg text-sm shadow-lg">\n Designer\n </div>\n </CursorFollow>\n </CursorProvider>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/components/cursor/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cursor-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cursor-demo',
},
'cursor-follow-only-demo': {
name: 'cursor-follow-only-demo',
description: 'Demo showing a cursor follow component.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/cursor'],
files: [
{
path: 'registry/demo/components/cursor-follow-only/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/cursor-follow-only.tsx',
content:
'import { CursorFollow, CursorProvider } from \'@/components/animate-ui/components/cursor\';\n\nexport const CursorFollowOnlyDemo = () => {\n return (\n <div className="size-[400px] rounded-xl bg-muted flex items-center justify-center">\n <p className="font-medium">Move your mouse over the div</p>\n <CursorProvider>\n <CursorFollow>\n <div className="bg-blue-500 text-white px-2 py-1 rounded-lg text-sm shadow-lg">\n Designer\n </div>\n </CursorFollow>\n </CursorProvider>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/cursor-follow-only/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cursor-follow-only-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cursor-follow-only-demo',
},
'files-demo': {
name: 'files-demo',
description: 'Demo showing an files.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/files'],
files: [
{
path: 'registry/demo/components/files/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/files.tsx',
content:
'\'use client\';\n\nimport React from \'react\';\nimport { File, Folder, Files } from \'@/components/animate-ui/components/files\';\n\nexport const FilesDemo = () => {\n return (\n <Files className="max-w-[500px] w-full" defaultOpen={[\'app\']}>\n <Folder name="app" defaultOpen={[\'(home)\']}>\n <Folder name="(home)">\n <File name="page.tsx" />\n <File name="layout.tsx" />\n </Folder>\n <File name="layout.tsx" />\n <File name="page.tsx" />\n <File name="global.css" />\n </Folder>\n <Folder name="components">\n <File name="button.tsx" />\n <File name="tabs.tsx" />\n <File name="dialog.tsx" />\n <Folder name="empty" />\n </Folder>\n <File name="package.json" />\n </Files>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/components/files/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'files-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/files-demo',
},
'files-advanced-demo': {
name: 'files-advanced-demo',
description: 'Demo showing an advanced files component.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/files'],
files: [
{
path: 'registry/demo/components/files-advanced/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/files-advanced.tsx',
content:
'\'use client\';\n\nimport React from \'react\';\nimport { File, Folder, Files } from \'@/components/animate-ui/components/files\';\n\nexport const FilesAdvancedDemo = () => {\n return (\n <Files className="max-w-[500px] w-full" defaultOpen={[\'app\']}>\n <Folder\n name="app"\n className="text-amber-500 justify-between"\n sideComponent={<div className="bg-amber-500 rounded-full size-2" />}\n defaultOpen={[\'(home)\']}\n >\n <Folder\n name="(home)"\n className="text-green-500 justify-between"\n sideComponent={<div className="bg-green-500 rounded-full size-2" />}\n >\n <File\n name="page.tsx"\n className="text-green-500 justify-between"\n sideComponent={<span className="font-medium">U</span>}\n />\n <File\n name="layout.tsx"\n className="text-green-500 justify-between"\n sideComponent={<span className="font-medium">U</span>}\n />\n </Folder>\n <File name="layout.tsx" />\n <File\n name="page.tsx"\n className="text-amber-500 justify-between"\n sideComponent={<span className="font-medium">M</span>}\n />\n <File name="global.css" />\n </Folder>\n <Folder name="components">\n <File name="button.tsx" />\n <File name="tabs.tsx" />\n <File name="dialog.tsx" />\n <Folder name="empty" />\n </Folder>\n <File name="package.json" />\n </Files>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/files-advanced/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'files-advanced-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/files-advanced-demo',
},
'install-tabs-demo': {
name: 'install-tabs-demo',
description: 'Demo showing an install tabs.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/code-tabs'],
files: [
{
path: 'registry/demo/components/install-tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/install-tabs.tsx',
content:
'import { CodeTabs } from \'@/components/animate-ui/components/code-tabs\';\n\nconst COMMANDS = {\n npm: `npx shadcn@latest add "https://animate-ui.com/r/code-tabs"`,\n pnpm: `pnpm dlx shadcn@latest add "https://animate-ui.com/r/code-tabs"`,\n yarn: `npx shadcn@latest add "https://animate-ui.com/r/code-tabs"`,\n bun: `bun x --bun shadcn@latest add "https://animate-ui.com/r/code-tabs"`,\n};\n\nexport const InstallTabsDemo = () => {\n return (\n <CodeTabs defaultValue="pnpm" className="max-w-[650px]" codes={COMMANDS} />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/install-tabs/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'install-tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/install-tabs-demo',
},
'liquid-glass-demo': {
name: 'liquid-glass-demo',
description: 'Demo showing a liquid glass effect.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/liquid-glass'],
files: [
{
path: 'registry/demo/components/liquid-glass/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/liquid-glass.tsx',
content:
"import { LiquidGlass } from '@/components/animate-ui/components/liquid-glass';\nimport { GlassesIcon } from 'lucide-react';\nimport { motion } from 'motion/react';\n\nexport default function LiquidGlassDemo() {\n return (\n <div className=\"absolute inset-0\">\n <div className=\"relative h-full w-full overflow-hidden rounded-xl\">\n <div className=\"overflow-y-auto h-full\">\n <LiquidGlass\n className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 cursor-pointer\"\n radius={10}\n blur={1}\n childClassName=\"flex items-center gap-2 text-white font-medium px-3\"\n as={motion.button}\n whileHover={{\n scale: 1.05,\n }}\n whileTap={{\n scale: 0.95,\n }}\n >\n <GlassesIcon className=\"size-5\" />\n <span>Liquid Glass</span>\n </LiquidGlass>\n <div\n className=\"size-full dark:bg-neutral-900 bg-neutral-100\"\n style={{\n backgroundImage:\n 'url(https://upload.wikimedia.org/wikipedia/commons/9/93/Rainbow_on_Rara_Lake.jpg)',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }}\n />\n <div\n className=\"size-full dark:bg-neutral-950 bg-white\"\n style={{\n backgroundImage:\n 'url(https://www.terdav.com/Content/img/mag/vignettes/grande/1515.jpg)',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }}\n />\n <div\n className=\"size-full dark:bg-neutral-900 bg-neutral-100\"\n style={{\n backgroundImage:\n 'url(https://www.amplitudes.com/blog/wp-content/uploads/2019/07/iStock-1014791492-1.jpg)',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }}\n />\n <div\n className=\"size-full dark:bg-neutral-950 bg-white\"\n style={{\n backgroundImage:\n 'url(https://m.media-amazon.com/images/I/714N8vbkr6L._AC_UF1000,1000_QL80_.jpg)',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n }}\n />\n </div>\n </div>\n </div>\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/liquid-glass/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'liquid-glass-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/liquid-glass-demo',
},
'motion-grid-demo': {
name: 'motion-grid-demo',
description: 'Demo Motion Grid.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-grid'],
files: [
{
path: 'registry/demo/components/motion-grid/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/motion-grid.tsx',
content:
"import { useEffect, useState } from 'react';\nimport { motion } from 'motion/react';\n\nimport { Button } from '@/components/ui/button';\nimport { type Frames, MotionGrid } from '@/components/animate-ui/components/motion-grid';\nimport { RotatingText } from '@/components/animate-ui/text/rotating';\n\nconst importingFrames = [\n [[2, 2]],\n [\n [1, 2],\n [2, 1],\n [2, 3],\n [3, 2],\n ],\n [\n [2, 2],\n [0, 2],\n [1, 1],\n [1, 3],\n [2, 0],\n [2, 4],\n [3, 1],\n [3, 3],\n [4, 2],\n ],\n [\n [0, 1],\n [0, 3],\n [1, 0],\n [1, 2],\n [1, 4],\n [2, 1],\n [2, 3],\n [3, 0],\n [3, 2],\n [3, 4],\n [4, 1],\n [4, 3],\n ],\n [\n [0, 0],\n [0, 2],\n [0, 4],\n [1, 1],\n [1, 3],\n [2, 0],\n [2, 2],\n [2, 4],\n [3, 1],\n [3, 3],\n [4, 0],\n [4, 2],\n [4, 4],\n ],\n [\n [0, 1],\n [0, 3],\n [1, 0],\n [1, 2],\n [1, 4],\n [2, 1],\n [2, 3],\n [3, 0],\n [3, 2],\n [3, 4],\n [4, 1],\n [4, 3],\n ],\n [\n [0, 0],\n [0, 2],\n [0, 4],\n [1, 1],\n [1, 3],\n [2, 0],\n [2, 4],\n [3, 1],\n [3, 3],\n [4, 0],\n [4, 2],\n [4, 4],\n ],\n [\n [0, 1],\n [1, 0],\n [3, 0],\n [4, 1],\n [0, 3],\n [1, 4],\n [3, 4],\n [4, 3],\n ],\n [\n [0, 0],\n [0, 4],\n [4, 0],\n [4, 4],\n ],\n [],\n] as Frames;\n\nconst arrowDownFrames = [\n [[2, 0]],\n [\n [1, 0],\n [2, 0],\n [3, 0],\n [2, 1],\n ],\n [\n [2, 0],\n [1, 1],\n [2, 1],\n [3, 1],\n [2, 2],\n ],\n [\n [2, 0],\n [2, 1],\n [1, 2],\n [2, 2],\n [3, 2],\n [2, 3],\n ],\n [\n [2, 1],\n [2, 2],\n [1, 3],\n [2, 3],\n [3, 3],\n [2, 4],\n ],\n [\n [2, 2],\n [2, 3],\n [1, 4],\n [2, 4],\n [3, 4],\n ],\n [\n [2, 3],\n [2, 4],\n ],\n [[2, 4]],\n [],\n] as Frames;\n\nconst arrowUpFrames = [\n [[2, 4]],\n [\n [1, 4],\n [2, 4],\n [3, 4],\n [2, 3],\n ],\n [\n [2, 4],\n [1, 3],\n [2, 3],\n [3, 3],\n [2, 2],\n ],\n [\n [2, 4],\n [2, 3],\n [1, 2],\n [2, 2],\n [3, 2],\n [2, 1],\n ],\n [\n [2, 3],\n [2, 2],\n [1, 1],\n [2, 1],\n [3, 1],\n [2, 0],\n ],\n [\n [2, 2],\n [2, 1],\n [1, 0],\n [2, 0],\n [3, 0],\n ],\n [\n [2, 1],\n [2, 0],\n ],\n [[2, 0]],\n [],\n] as Frames;\n\nconst syncingFrames = [...arrowDownFrames, ...arrowUpFrames] as Frames;\n\nconst searchingFrames = [\n [\n [1, 0],\n [0, 1],\n [1, 1],\n [2, 1],\n [1, 2],\n ],\n [\n [2, 0],\n [1, 1],\n [2, 1],\n [3, 1],\n [2, 2],\n ],\n [\n [3, 0],\n [2, 1],\n [3, 1],\n [4, 1],\n [3, 2],\n ],\n [\n [3, 1],\n [2, 2],\n [3, 2],\n [4, 2],\n [3, 3],\n ],\n [\n [3, 2],\n [2, 3],\n [3, 3],\n [4, 3],\n [3, 4],\n ],\n [\n [1, 2],\n [0, 3],\n [1, 3],\n [2, 3],\n [1, 4],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [1, 0],\n [1, 2],\n [2, 0],\n [2, 1],\n [2, 2],\n ],\n [],\n] as Frames;\n\nconst busyFrames = [\n [\n [0, 1],\n [0, 2],\n [0, 3],\n [1, 2],\n [4, 1],\n [4, 2],\n [4, 3],\n ],\n [\n [0, 1],\n [0, 2],\n [0, 3],\n [2, 3],\n [4, 2],\n [4, 3],\n [4, 4],\n ],\n [\n [0, 1],\n [0, 2],\n [0, 3],\n [3, 4],\n [4, 2],\n [4, 3],\n [4, 4],\n ],\n [\n [0, 1],\n [0, 2],\n [0, 3],\n [2, 3],\n [4, 2],\n [4, 3],\n [4, 4],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [1, 2],\n [4, 2],\n [4, 3],\n [4, 4],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [2, 1],\n [4, 1],\n [4, 2],\n [4, 3],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [3, 0],\n [4, 0],\n [4, 1],\n [4, 2],\n ],\n [\n [0, 1],\n [0, 2],\n [0, 3],\n [2, 1],\n [4, 0],\n [4, 1],\n [4, 2],\n ],\n] as Frames;\n\nconst savingFrames = [\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [0, 3],\n [0, 4],\n [1, 0],\n [1, 1],\n [1, 2],\n [1, 3],\n [2, 0],\n [2, 1],\n [2, 2],\n [2, 3],\n [2, 4],\n [3, 0],\n [3, 1],\n [3, 2],\n [3, 3],\n [4, 0],\n [4, 1],\n [4, 2],\n [4, 3],\n [4, 4],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [0, 3],\n [1, 0],\n [1, 1],\n [1, 2],\n [2, 0],\n [2, 1],\n [2, 2],\n [2, 3],\n [3, 0],\n [3, 1],\n [3, 2],\n [4, 0],\n [4, 1],\n [4, 2],\n [4, 3],\n ],\n [\n [0, 0],\n [0, 1],\n [0, 2],\n [1, 0],\n [1, 1],\n [2, 0],\n [2, 1],\n [2, 2],\n [3, 0],\n [3, 1],\n [4, 0],\n [4, 1],\n [4, 2],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n [\n [0, 0],\n [0, 1],\n [1, 0],\n [2, 0],\n [2, 1],\n [3, 0],\n [4, 0],\n [4, 1],\n [4, 3],\n [3, 3],\n [2, 3],\n [1, 3],\n [0, 3],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n [\n [0, 0],\n [2, 0],\n [4, 0],\n [4, 2],\n [3, 2],\n [2, 2],\n [1, 2],\n [0, 2],\n [4, 3],\n [3, 3],\n [2, 3],\n [1, 3],\n [0, 3],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n [\n [0, 0],\n [1, 0],\n [2, 0],\n [3, 0],\n [4, 0],\n [4, 1],\n [3, 1],\n [2, 1],\n [1, 1],\n [0, 1],\n [4, 2],\n [3, 2],\n [2, 2],\n [1, 2],\n [0, 2],\n [4, 3],\n [3, 3],\n [2, 3],\n [1, 3],\n [0, 3],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n [\n [0, 0],\n [1, 0],\n [2, 0],\n [3, 0],\n [4, 0],\n [4, 1],\n [3, 1],\n [2, 1],\n [1, 1],\n [0, 1],\n [4, 2],\n [3, 2],\n [2, 2],\n [1, 2],\n [0, 2],\n [4, 3],\n [3, 3],\n [2, 3],\n [1, 3],\n [0, 3],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n [\n [0, 0],\n [1, 0],\n [2, 0],\n [3, 0],\n [4, 0],\n [4, 1],\n [3, 1],\n [2, 1],\n [1, 1],\n [0, 1],\n [4, 2],\n [3, 2],\n [2, 2],\n [1, 2],\n [0, 2],\n [4, 3],\n [3, 3],\n [2, 3],\n [1, 3],\n [0, 3],\n [4, 4],\n [3, 4],\n [2, 4],\n [1, 4],\n [0, 4],\n ],\n] as Frames;\n\nconst initializingFrames = [\n [],\n [\n [1, 0],\n [3, 0],\n ],\n [\n [1, 0],\n [3, 0],\n [0, 1],\n [1, 1],\n [2, 1],\n [3, 1],\n [4, 1],\n ],\n [\n [1, 0],\n [3, 0],\n [0, 1],\n [1, 1],\n [2, 1],\n [3, 1],\n [4, 1],\n [0, 2],\n [1, 2],\n [2, 2],\n [3, 2],\n [4, 2],\n ],\n [\n [1, 0],\n [3, 0],\n [0, 1],\n [1, 1],\n [2, 1],\n [3, 1],\n [4, 1],\n [0, 2],\n [1, 2],\n [2, 2],\n [3, 2],\n [4, 2],\n [1, 3],\n [2, 3],\n [3, 3],\n ],\n [\n [1, 0],\n [3, 0],\n [0, 1],\n [1, 1],\n [2, 1],\n [3, 1],\n [4, 1],\n [0, 2],\n [1, 2],\n [2, 2],\n [3, 2],\n [4, 2],\n [1, 3],\n [2, 3],\n [3, 3],\n [2, 4],\n ],\n [\n [1, 2],\n [2, 1],\n [2, 2],\n [2, 3],\n [3, 2],\n ],\n [[2, 2]],\n [],\n] as Frames;\n\nconst states = {\n importing: {\n frames: importingFrames,\n label: 'Importing',\n },\n syncing: {\n frames: syncingFrames,\n label: 'Syncing',\n },\n searching: {\n frames: searchingFrames,\n label: 'Searching',\n },\n busy: {\n frames: busyFrames,\n label: 'Busy',\n },\n saving: {\n frames: savingFrames,\n label: 'Saving',\n },\n initializing: {\n frames: initializingFrames,\n label: 'Initializing',\n },\n};\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport const MotionGridDemo = () => {\n const [state, setState] = useState<keyof typeof states>('importing');\n\n const runStates = async () => {\n while (true) {\n for (const state of Object.keys(states) as (keyof typeof states)[]) {\n setState(state);\n await sleep(3000);\n }\n }\n };\n\n useEffect(() => {\n runStates();\n }, []);\n\n return (\n <Button size=\"lg\" className=\"px-3 h-11 gap-x-3 relative\" asChild>\n <motion.button\n layout\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n <motion.div layout=\"preserve-aspect\">\n <MotionGrid\n gridSize={[5, 5]}\n frames={states[state].frames}\n cellClassName=\"size-[3px]\"\n cellActiveClassName=\"bg-white/70 dark:bg-black/70\"\n cellInactiveClassName=\"bg-white/20 dark:bg-black/20\"\n />\n </motion.div>\n\n <RotatingText\n text={states[state].label}\n containerClassName=\"absolute left-[46px] top-1/2 -translate-y-1/2\"\n layout=\"preserve-aspect\"\n />\n\n <span className=\"invisible opacity-0\" aria-hidden>\n {states[state].label}\n </span>\n </motion.button>\n </Button>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/motion-grid/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-grid-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-grid-demo',
},
'pin-list-demo': {
name: 'pin-list-demo',
description: 'Demo Pin List.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/pin-list'],
files: [
{
path: 'registry/demo/components/pin-list/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/pin-list.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { PinList } from '@/components/animate-ui/components/pin-list';\n\nimport { GitCommit, AlertTriangle, Box, KeyRound, Regex } from 'lucide-react';\n\nconst ITEMS = [\n {\n id: 1,\n name: 'Commit Zone',\n info: 'Code updates · Closes 9:00 PM',\n icon: GitCommit,\n pinned: true,\n },\n {\n id: 2,\n name: '404 Room',\n info: 'Fixing errors · Open 24 hours',\n icon: AlertTriangle,\n pinned: true,\n },\n {\n id: 3,\n name: 'NPM Stop',\n info: 'Install stuff · Closes 8:00 PM',\n icon: Box,\n pinned: false,\n },\n {\n id: 4,\n name: 'Token Lock',\n info: 'Login stuff · Open 24 hours',\n icon: KeyRound,\n pinned: false,\n },\n {\n id: 5,\n name: 'Regex Zone',\n info: 'Find words · Closes 9:00 PM',\n icon: Regex,\n pinned: false,\n },\n];\n\nexport const PinListDemo = () => <PinList items={ITEMS} />;",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/pin-list/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pin-list-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pin-list-demo',
},
'scroll-progress-demo': {
name: 'scroll-progress-demo',
description: 'Demo showing a scroll progress.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/scroll-progress'],
files: [
{
path: 'registry/demo/components/scroll-progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/scroll-progress.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { ArrowDown } from \'lucide-react\';\nimport { motion } from \'motion/react\';\n\nimport { ScrollProgress } from \'@/components/animate-ui/components/scroll-progress\';\n\nexport const ScrollProgressDemo = () => {\n return (\n <div className="absolute inset-0">\n <div className="relative h-full w-full overflow-hidden rounded-xl">\n <ScrollProgress progressProps={{ className: \'absolute\' }}>\n <div className="size-full flex items-center justify-center dark:bg-neutral-950 bg-white">\n <p className="flex items-center gap-2 font-medium">\n Scroll down to see the progress bar{\' \'}\n <motion.span\n animate={{ y: [3, -3, 3] }}\n transition={{\n duration: 1.25,\n repeat: Infinity,\n ease: \'easeInOut\',\n type: \'keyframes\',\n }}\n >\n <ArrowDown className="size-5" />\n </motion.span>\n </p>\n </div>\n <div className="size-full dark:bg-neutral-900 bg-neutral-100" />\n <div className="size-full dark:bg-neutral-950 bg-white" />\n <div className="size-full dark:bg-neutral-900 bg-neutral-100" />\n <div className="size-full dark:bg-neutral-950 bg-white" />\n </ScrollProgress>\n </div>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/scroll-progress/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'scroll-progress-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/scroll-progress-demo',
},
'spring-element-demo': {
name: 'spring-element-demo',
description: 'Demo showing a Spring Element attached to an avatar.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/spring-element'],
files: [
{
path: 'registry/demo/components/spring-element/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/spring-element.tsx',
content:
'import { SpringElement } from \'@/components/animate-ui/components/spring-element\';\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \'@/components/ui/avatar\';\n\nexport default function SpringElementDemo() {\n return (\n <SpringElement>\n <Avatar className="size-20">\n <AvatarImage\n draggable={false}\n src="https://pbs.twimg.com/profile_images/1897311929028255744/otxpL-ke_400x400.jpg"\n />\n <AvatarFallback>AK</AvatarFallback>\n </Avatar>\n </SpringElement>\n );\n}',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/spring-element/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'spring-element-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/spring-element-demo',
},
'stars-scrolling-wheel-demo': {
name: 'stars-scrolling-wheel-demo',
description: 'Demo showing a Stars Scrolling Wheel.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/stars-scrolling-wheel'],
files: [
{
path: 'registry/demo/components/stars-scrolling-wheel/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/components/stars-scrolling-wheel.tsx',
content:
'import { StarsScrollingWheel } from \'@/components/animate-ui/components/stars-scrolling-wheel\';\n\nexport const StarsScrollingWheelDemo = () => {\n return (\n <div className="size-full flex items-center justify-center">\n <StarsScrollingWheel stars={1000} delay={1000} />\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/stars-scrolling-wheel/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'stars-scrolling-wheel-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/stars-scrolling-wheel-demo',
},
'tabs-demo': {
name: 'tabs-demo',
description: 'Demo showing an animated tabs.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/tabs',
'label',
'input',
'button',
],
files: [
{
path: 'registry/demo/components/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/tabs.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsContents,\n} from \'@/components/animate-ui/components/tabs\';\nimport { Label } from \'@/components/ui/label\';\n\nexport const TabsDemo = () => {\n return (\n <Tabs defaultValue="account" className="w-[400px] bg-muted rounded-lg">\n <TabsList className="grid w-full grid-cols-2">\n <TabsTrigger value="account">Account</TabsTrigger>\n <TabsTrigger value="password">Password</TabsTrigger>\n </TabsList>\n\n <TabsContents className="mx-1 mb-1 -mt-2 rounded-sm h-full bg-background">\n <TabsContent value="account" className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Make changes to your account here. Click save when you&apos;re done.\n </p>\n\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="name">Name</Label>\n <Input id="name" defaultValue="Pedro Duarte" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="username">Username</Label>\n <Input id="username" defaultValue="@peduarte" />\n </div>\n </div>\n\n <Button>Save changes</Button>\n </TabsContent>\n <TabsContent value="password" className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Change your password here. After saving, you&apos;ll be logged out.\n </p>\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="current">Current password</Label>\n <Input id="current" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="new">New password</Label>\n <Input id="new" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="confirm">Confirm password</Label>\n <Input id="confirm" type="password" />\n </div>\n </div>\n\n <Button>Save password</Button>\n </TabsContent>\n </TabsContents>\n </Tabs>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/components/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/tabs-demo',
},
'tooltip-demo': {
name: 'tooltip-demo',
description: 'Demo showing an animated tooltip.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/tooltip'],
files: [
{
path: 'registry/demo/components/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/components/tooltip.tsx',
content:
"import { Button } from '@/components/ui/button';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n type TooltipProviderProps,\n type TooltipProps,\n type TooltipContentProps,\n} from '@/components/animate-ui/components/tooltip';\nimport React from 'react';\n\ntype TooltipDemoProps = Pick<TooltipProviderProps, 'openDelay' | 'closeDelay'> &\n Pick<TooltipProps, 'side' | 'sideOffset' | 'align' | 'alignOffset'> &\n Pick<TooltipContentProps, 'arrow'>;\n\nexport const TooltipDemo = ({\n openDelay,\n closeDelay,\n side,\n sideOffset,\n align,\n alignOffset,\n arrow,\n}: TooltipDemoProps) => {\n return (\n <TooltipProvider openDelay={openDelay} closeDelay={closeDelay}>\n <div className=\"flex flex-col gap-5 justify-center items-center\">\n <div className=\"flex flex-row gap-5 border rounded-lg p-5\">\n <Tooltip\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n >\n <TooltipTrigger>\n <Button variant=\"outline\">Docs</Button>\n </TooltipTrigger>\n <TooltipContent arrow={arrow}>\n <p>Documentation</p>\n </TooltipContent>\n </Tooltip>\n <Tooltip\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n >\n <TooltipTrigger>\n <Button variant=\"outline\">API</Button>\n </TooltipTrigger>\n <TooltipContent arrow={arrow}>\n <p>API Reference</p>\n </TooltipContent>\n </Tooltip>\n <Tooltip\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n >\n <TooltipTrigger>\n <Button variant=\"outline\">Guide</Button>\n </TooltipTrigger>\n <TooltipContent arrow={arrow}>\n <p>User Guide</p>\n </TooltipContent>\n </Tooltip>\n </div>\n <div className=\"flex flex-row gap-5\">\n <Tooltip\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n >\n <TooltipTrigger>\n <Button variant=\"outline\">Repo</Button>\n </TooltipTrigger>\n <TooltipContent arrow={arrow}>\n <p>GitHub</p>\n </TooltipContent>\n </Tooltip>\n </div>\n </div>\n </TooltipProvider>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/components/tooltip/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'tooltip-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
TooltipProvider: {
openDelay: { value: 700, min: 0, max: 2000, step: 100 },
closeDelay: { value: 300, min: 0, max: 2000, step: 100 },
},
Tooltip: {
side: {
value: 'top',
options: {
top: 'top',
bottom: 'bottom',
left: 'left',
right: 'right',
},
},
sideOffset: { value: 14 },
align: {
value: 'center',
options: { start: 'start', center: 'center', end: 'end' },
},
alignOffset: { value: 0 },
},
TooltipContent: { arrow: { value: true } },
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/tooltip-demo',
},
'magnetic-demo': {
name: 'magnetic-demo',
description: 'Demo showing the magnetic effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/magnetic'],
files: [
{
path: 'registry/demo/effects/magnetic/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/effects/magnetic.tsx',
content:
'import { Magnetic } from \'@/components/animate-ui/effects/magnetic\';\n\ninterface MagneticDemoProps {\n onlyOnHover: boolean;\n strength: number;\n range: number;\n}\n\nexport const MagneticDemo = (props: MagneticDemoProps) => {\n return (\n <div className="size-full flex items-center justify-center">\n <Magnetic {...props}>\n <div className="size-32 rounded-2xl bg-emerald-500" />\n </Magnetic>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/effects/magnetic/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'magnetic-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
Magnetic: {
onlyOnHover: { value: false },
strength: { value: 0.5, min: 0, max: 1, step: 0.05 },
range: { value: 120 },
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/magnetic-demo',
},
'motion-effect-fade-blur-demo': {
name: 'motion-effect-fade-blur-demo',
description: 'Demo showing the motion effect fade blur.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-effect'],
files: [
{
path: 'registry/demo/effects/motion-effect-fade-blur/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/effects/motion-effect-fade-blur.tsx',
content:
'import { MotionEffect } from \'@/components/animate-ui/effects/motion-effect\';\n\nexport const MotionEffectFadeBlurDemo = () => {\n return (\n <MotionEffect\n fade\n blur="10px"\n transition={{\n duration: 0.5,\n ease: \'easeInOut\',\n }}\n inView\n >\n <p className="text-4xl font-bold">Motion Effect Fade Blur</p>\n </MotionEffect>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-effect-fade-blur/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-effect-fade-blur-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-effect-fade-blur-demo',
},
'motion-effect-image-grid-demo': {
name: 'motion-effect-image-grid-demo',
description: 'Demo showing the motion effect image grid.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/motion-effect',
'use-mobile',
],
files: [
{
path: 'registry/demo/effects/motion-effect-image-grid/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/effects/motion-effect-image-grid.tsx',
content:
"'use client';\n\nimport { useIsMobile } from '@/hooks/use-mobile';\nimport { MotionEffect } from '@/components/animate-ui/effects/motion-effect';\n\nexport const MotionEffectImageGridDemo = () => {\n const isMobile = useIsMobile();\n\n return (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {Array.from({ length: isMobile ? 2 : 4 }).map((_, index) => (\n <MotionEffect\n key={index}\n slide={{\n direction: 'down',\n }}\n fade\n zoom\n inView\n delay={0.5 + index * 0.1}\n >\n <img\n src={`https://picsum.photos/seed/${index + 100}/600/400`}\n alt=\"Slide In Demo\"\n className=\"w-[300px] h-[200px] object-cover object-center bg-muted rounded-xl flex items-center justify-center\"\n />\n </MotionEffect>\n ))}\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-effect-image-grid/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-effect-image-grid-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-effect-image-grid-demo',
},
'motion-effect-slide-demo': {
name: 'motion-effect-slide-demo',
description: 'Demo showing the motion effect slide.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-effect'],
files: [
{
path: 'registry/demo/effects/motion-effect-slide/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/effects/motion-effect-slide.tsx',
content:
'import { MotionEffect } from \'@/components/animate-ui/effects/motion-effect\';\n\nexport const MotionEffectSlideDemo = () => {\n return (\n <MotionEffect slide inView>\n <p className="text-4xl font-bold">Motion Effect Slide</p>\n </MotionEffect>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-effect-slide/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-effect-slide-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-effect-slide-demo',
},
'motion-highlight-cards-hover-demo': {
name: 'motion-highlight-cards-hover-demo',
description: 'Demo showing the motion highlight cards hover effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/demo/effects/motion-highlight-cards-hover/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/effects/motion-highlight-cards-hover.tsx',
content:
"import { Blocks, BringToFront, GitPullRequest } from 'lucide-react';\n\nimport ShadcnIcon from '@/components/icons/shadcn-icon';\nimport { MotionHighlight } from '@/components/animate-ui/effects/motion-highlight';\n\nconst CARDS = [\n {\n value: '1',\n icon: BringToFront,\n title: 'Animated Components',\n description: 'Beautiful Motion-animated components for dynamic websites.',\n },\n {\n value: '2',\n icon: GitPullRequest,\n title: 'Open Source',\n description:\n 'A project built for the dev community with the dev community.',\n },\n {\n value: '3',\n icon: ShadcnIcon,\n title: 'Complementary to Shadcn UI',\n description:\n 'The components are designed to be used with Shadcn UI components.',\n },\n {\n value: '4',\n icon: Blocks,\n title: 'Component Distribution',\n description:\n 'Install the components in your project and modify them as you wish.',\n },\n];\n\nexport const MotionHighlightCardsHoverDemo = () => {\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <MotionHighlight hover className=\"rounded-xl\">\n {CARDS.map((card) => (\n <div key={card.value} data-value={card.value}>\n <div className=\"p-4 flex flex-col border rounded-xl\">\n <div className=\"flex items-center justify-around size-10 rounded-lg bg-blue-500/10 mb-2\">\n <card.icon className=\"size-5 text-blue-500\" />\n </div>\n <p className=\"text-base font-medium mb-1\">{card.title}</p>\n <p className=\"text-sm text-muted-foreground\">\n {card.description}\n </p>\n </div>\n </div>\n ))}\n </MotionHighlight>\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-highlight-cards-hover/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-highlight-cards-hover-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-highlight-cards-hover-demo',
},
'motion-highlight-tabs-demo': {
name: 'motion-highlight-tabs-demo',
description: 'Demo showing the motion highlight tabs effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/demo/effects/motion-highlight-tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/effects/motion-highlight-tabs.tsx',
content:
"import { MotionHighlight } from '@/components/animate-ui/effects/motion-highlight';\n\nconst TABS = [\n {\n value: 'tab-1',\n title: 'Tab 1',\n description: 'Tab 1 description',\n },\n {\n value: 'tab-2',\n title: 'Tab 2',\n description: 'Tab 2 description',\n },\n {\n value: 'tab-3',\n title: 'Tab 3',\n description: 'Tab 3 description',\n },\n];\n\nexport const MotionHighlightTabsDemo = () => {\n return (\n <div className=\"flex border rounded-full p-1\">\n <MotionHighlight defaultValue={TABS[0]?.value} className=\"rounded-full\">\n {TABS.map((tab) => (\n <div\n key={tab.value}\n data-value={tab.value}\n className=\"px-3 h-8 flex items-center cursor-pointer justify-center rounded-full text-sm data-[active=true]:text-current data-[active=true]:font-medium text-muted-foreground transition-all duration-300\"\n >\n {tab.title}\n </div>\n ))}\n </MotionHighlight>\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-highlight-tabs/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-highlight-tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-highlight-tabs-demo',
},
'motion-highlight-tabs-hover-demo': {
name: 'motion-highlight-tabs-hover-demo',
description: 'Demo showing the motion highlight tabs hover effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/demo/effects/motion-highlight-tabs-hover/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/effects/motion-highlight-tabs-hover.tsx',
content:
"import { MotionHighlight } from '@/components/animate-ui/effects/motion-highlight';\n\nconst TABS = [\n {\n value: 'tab-1',\n title: 'Tab 1',\n description: 'Tab 1 description',\n },\n {\n value: 'tab-2',\n title: 'Tab 2',\n description: 'Tab 2 description',\n },\n {\n value: 'tab-3',\n title: 'Tab 3',\n description: 'Tab 3 description',\n },\n];\n\nexport const MotionHighlightTabsHoverDemo = () => {\n return (\n <div className=\"flex border rounded-full p-1\">\n <MotionHighlight hover className=\"rounded-full\">\n {TABS.map((tab) => (\n <div\n key={tab.value}\n data-value={tab.value}\n className=\"px-3 h-8 flex items-center cursor-pointer justify-center rounded-full text-sm data-[active=true]:text-current data-[active=true]:font-medium text-muted-foreground transition-all duration-300\"\n >\n {tab.title}\n </div>\n ))}\n </MotionHighlight>\n </div>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-highlight-tabs-hover/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-highlight-tabs-hover-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-highlight-tabs-hover-demo',
},
'motion-highlight-tabs-hover-parent-demo': {
name: 'motion-highlight-tabs-hover-parent-demo',
description: 'Demo showing the motion highlight tabs hover effect.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/demo/effects/motion-highlight-tabs-hover-parent/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/effects/motion-highlight-tabs-hover-parent.tsx',
content:
"import { MotionHighlight } from '@/components/animate-ui/effects/motion-highlight';\n\nconst TABS = [\n {\n value: 'tab-1',\n title: 'Tab 1',\n description: 'Tab 1 description',\n },\n {\n value: 'tab-2',\n title: 'Tab 2',\n description: 'Tab 2 description',\n },\n {\n value: 'tab-3',\n title: 'Tab 3',\n description: 'Tab 3 description',\n },\n];\n\nexport const MotionHighlightTabsHoverParentDemo = () => {\n return (\n <MotionHighlight\n hover\n mode=\"parent\"\n containerClassName=\"flex border rounded-full p-1\"\n className=\"rounded-full\"\n boundsOffset={{ top: -1, left: -1 }} // we have to add an offset of the same size as the border when we set a border\n >\n {TABS.map((tab) => (\n <div\n key={tab.value}\n data-value={tab.value}\n className=\"px-3 h-8 flex items-center cursor-pointer justify-center rounded-full text-sm data-[active=true]:text-current data-[active=true]:font-medium text-muted-foreground transition-all duration-300\"\n >\n {tab.title}\n </div>\n ))}\n </MotionHighlight>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/effects/motion-highlight-tabs-hover-parent/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-highlight-tabs-hover-parent-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-highlight-tabs-hover-parent-demo',
},
'headless-accordion-demo': {
name: 'headless-accordion-demo',
description: 'Demo showing an animated headless accordion.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-accordion'],
files: [
{
path: 'registry/demo/headless/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/accordion.tsx',
content:
'import {\n Accordion,\n AccordionItem,\n AccordionButton,\n AccordionPanel,\n} from \'@/components/animate-ui/headless/accordion\';\n\nexport const HeadlessAccordionDemo = () => {\n return (\n <Accordion className="max-w-[400px] w-full">\n <AccordionItem defaultOpen>\n <AccordionButton>What is Animate UI?</AccordionButton>\n <AccordionPanel>\n Animate UI is an open-source distribution of React components built\n with TypeScript, Tailwind CSS, and Motion.\n </AccordionPanel>\n </AccordionItem>\n <AccordionItem>\n <AccordionButton>\n How is it different from other libraries?\n </AccordionButton>\n <AccordionPanel>\n Instead of installing via NPM, you copy and paste the components\n directly. This gives you full control to modify or customize them as\n needed.\n </AccordionPanel>\n </AccordionItem>\n <AccordionItem>\n <AccordionButton>Is Animate UI free to use?</AccordionButton>\n <AccordionPanel>\n Absolutely! Animate UI is fully open-source. You can use, modify, and\n adapt it to fit your needs.\n </AccordionPanel>\n </AccordionItem>\n </Accordion>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/headless/accordion/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-accordion-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-accordion-demo',
},
'headless-checkbox-demo': {
name: 'headless-checkbox-demo',
description: 'Demo showing an animated headless checkbox.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-checkbox'],
files: [
{
path: 'registry/demo/headless/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/checkbox.tsx',
content:
'import { Checkbox } from \'@/components/animate-ui/headless/checkbox\';\nimport { Field, Label } from \'@headlessui/react\';\n\nexport const HeadlessCheckboxDemo = () => {\n return (\n <Field className="flex items-center space-x-2">\n <Checkbox id="terms" />\n <Label htmlFor="terms" className="text-sm font-medium">\n Accept terms and conditions\n </Label>\n </Field>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/headless/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-checkbox-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-checkbox-demo',
},
'headless-dialog-demo': {
name: 'headless-dialog-demo',
description: 'Demo showing an animated headless dialog.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-dialog'],
files: [
{
path: 'registry/demo/headless/dialog/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/dialog.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { Button } from \'@/components/ui/button\';\nimport {\n Dialog,\n DialogBackdrop,\n DialogPanel,\n DialogTitle,\n DialogDescription,\n DialogHeader,\n DialogFooter,\n} from \'@/components/animate-ui/headless/dialog\';\n\nexport const RadixDialogDemo = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <div>\n <Button variant="outline" onClick={() => setIsOpen(true)}>\n Open Dialog\n </Button>\n\n <Dialog open={isOpen} onClose={() => setIsOpen(false)}>\n <DialogBackdrop />\n\n <DialogPanel className="sm:max-w-[425px]">\n <DialogHeader>\n <DialogTitle>Terms of Service</DialogTitle>\n <DialogDescription>\n Please read the following terms of service carefully.\n </DialogDescription>\n </DialogHeader>\n\n <div className="grid gap-4 py-4">\n <p>\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,\n quos. Lorem ipsum dolor sit amet consectetur adipisicing elit.\n Quisquam, quos.\n </p>\n </div>\n\n <DialogFooter>\n <Button variant="outline" onClick={() => setIsOpen(false)}>\n Decline\n </Button>\n <Button type="submit" onClick={() => setIsOpen(false)}>\n Accept\n </Button>\n </DialogFooter>\n </DialogPanel>\n </Dialog>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/headless/dialog/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-dialog-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-dialog-demo',
},
'headless-dialog-from-demo': {
name: 'headless-dialog-from-demo',
description: 'Demo showing an animated headless dialog with a from prop.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-dialog'],
files: [
{
path: 'registry/demo/headless/dialog-from/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/dialog-from.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { Button } from \'@/components/ui/button\';\nimport {\n Dialog,\n DialogBackdrop,\n DialogPanel,\n DialogTitle,\n DialogDescription,\n DialogHeader,\n DialogFooter,\n} from \'@/components/animate-ui/headless/dialog\';\n\nexport const RadixDialogDemo = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <div>\n <Button variant="outline" onClick={() => setIsOpen(true)}>\n Open Dialog\n </Button>\n\n <Dialog open={isOpen} onClose={() => setIsOpen(false)}>\n <DialogBackdrop />\n\n <DialogPanel from="left" className="sm:max-w-[425px]">\n <DialogHeader>\n <DialogTitle>Terms of Service</DialogTitle>\n <DialogDescription>\n Please read the following terms of service carefully.\n </DialogDescription>\n </DialogHeader>\n\n <div className="grid gap-4 py-4">\n <p>\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,\n quos. Lorem ipsum dolor sit amet consectetur adipisicing elit.\n Quisquam, quos.\n </p>\n </div>\n\n <DialogFooter>\n <Button variant="outline" onClick={() => setIsOpen(false)}>\n Decline\n </Button>\n <Button type="submit" onClick={() => setIsOpen(false)}>\n Accept\n </Button>\n </DialogFooter>\n </DialogPanel>\n </Dialog>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/headless/dialog-from/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-dialog-from-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-dialog-from-demo',
},
'headless-disclosure-demo': {
name: 'headless-disclosure-demo',
description: 'Demo showing an animated headless disclosure.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-disclosure'],
files: [
{
path: 'registry/demo/headless/disclosure/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/disclosure.tsx',
content:
'\'use client\';\n\nimport { Button } from \'@/components/ui/button\';\nimport {\n Disclosure,\n DisclosureButton,\n DisclosurePanel,\n} from \'@/components/animate-ui/headless/disclosure\';\nimport { ChevronsUpDown } from \'lucide-react\';\n\nexport const RadixCollapsibleDemo = () => {\n return (\n <Disclosure className="w-[350px]" as="div">\n <div className="space-y-2 mb-2">\n <div className="flex items-center justify-between space-x-4">\n <h4 className="text-sm font-semibold">\n @peduarte starred 3 repositories\n </h4>\n <DisclosureButton\n as={Button}\n variant="outline"\n size="sm"\n className="w-9 p-0"\n >\n <ChevronsUpDown className="h-4 w-4" />\n <span className="sr-only">Toggle</span>\n </DisclosureButton>\n </div>\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @headlessui/react\n </div>\n </div>\n <DisclosurePanel className="space-y-2">\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @headlessui/vue\n </div>\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @stitches/react\n </div>\n </DisclosurePanel>\n </Disclosure>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/headless/disclosure/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-disclosure-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-disclosure-demo',
},
'headless-popover-demo': {
name: 'headless-popover-demo',
description: 'Demo showing an animated headless popover.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'button',
'input',
'label',
'https://animate-ui.com/r/headless-popover',
],
files: [
{
path: 'registry/demo/headless/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/popover.tsx',
content:
'\'use client\';\n\nimport { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport { Label } from \'@/components/ui/label\';\nimport {\n Popover,\n PopoverButton,\n PopoverPanel,\n} from \'@/components/animate-ui/headless/popover\';\n\nexport function RadixPopoverDemo() {\n return (\n <Popover>\n <PopoverButton as={Button} variant="outline">\n Open popover\n </PopoverButton>\n <PopoverPanel className="w-80">\n <div className="grid gap-4">\n <div className="space-y-2">\n <h4 className="font-medium leading-none">Dimensions</h4>\n <p className="text-sm text-muted-foreground">\n Set the dimensions for the layer.\n </p>\n </div>\n <div className="grid gap-2">\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="width">Width</Label>\n <Input\n id="width"\n defaultValue="100%"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxWidth">Max. width</Label>\n <Input\n id="maxWidth"\n defaultValue="300px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="height">Height</Label>\n <Input\n id="height"\n defaultValue="25px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxHeight">Max. height</Label>\n <Input\n id="maxHeight"\n defaultValue="none"\n className="col-span-2 h-8"\n />\n </div>\n </div>\n </div>\n </PopoverPanel>\n </Popover>\n );\n}',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/headless/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-popover-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-popover-demo',
},
'headless-switch-demo': {
name: 'headless-switch-demo',
description: 'Demo showing an animated headless switch.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-switch'],
files: [
{
path: 'registry/demo/headless/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/switch.tsx',
content:
'import { Switch } from \'@/components/animate-ui/headless/switch\';\nimport { Field, Label } from \'@headlessui/react\';\n\nexport const HeadlessSwitchDemo = () => {\n return (\n <Field className="flex items-center space-x-2">\n <Label htmlFor="airplane-mode" className="text-sm font-medium">\n Airplane mode\n </Label>\n <Switch defaultChecked id="airplane-mode" />\n </Field>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/headless/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-switch-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-switch-demo',
},
'headless-tabs-demo': {
name: 'headless-tabs-demo',
description: 'Demo showing an animated headless tabs.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-tabs'],
files: [
{
path: 'registry/demo/headless/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/headless/tabs.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport { Label } from \'@/components/ui/label\';\nimport {\n Tab,\n TabGroup,\n TabList,\n TabPanel,\n TabPanels,\n} from \'@/components/animate-ui/headless/tabs\';\n\nexport const HeadlessTabsDemo = () => {\n return (\n <TabGroup defaultValue="account" className="w-[400px] bg-muted rounded-lg">\n <TabList className="grid w-full grid-cols-2">\n <Tab index={0}>Account</Tab>\n <Tab index={1}>Password</Tab>\n </TabList>\n\n <TabPanels className="mx-1 mb-1 -mt-2 rounded-sm h-full bg-background">\n <TabPanel className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Make changes to your account here. Click save when you&apos;re done.\n </p>\n\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="name">Name</Label>\n <Input id="name" defaultValue="Pedro Duarte" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="username">Username</Label>\n <Input id="username" defaultValue="@peduarte" />\n </div>\n </div>\n\n <Button>Save changes</Button>\n </TabPanel>\n <TabPanel className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Change your password here. After saving, you&apos;ll be logged out.\n </p>\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="current">Current password</Label>\n <Input id="current" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="new">New password</Label>\n <Input id="new" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="confirm">Confirm password</Label>\n <Input id="confirm" type="password" />\n </div>\n </div>\n\n <Button>Save password</Button>\n </TabPanel>\n </TabPanels>\n </TabGroup>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/headless/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-tabs-demo',
},
'radix-accordion-demo': {
name: 'radix-accordion-demo',
description: 'Demo showing an animated radix accordion.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-accordion'],
files: [
{
path: 'registry/demo/radix/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/accordion.tsx',
content:
'import {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \'@/components/animate-ui/radix/accordion\';\n\nexport const RadixAccordionDemo = () => {\n return (\n <Accordion\n type="single"\n defaultValue="item-1"\n collapsible\n className="max-w-[400px] w-full"\n >\n <AccordionItem value="item-1">\n <AccordionTrigger>What is Animate UI?</AccordionTrigger>\n <AccordionContent>\n Animate UI is an open-source distribution of React components built\n with TypeScript, Tailwind CSS, and Motion.\n </AccordionContent>\n </AccordionItem>\n\n <AccordionItem value="item-2">\n <AccordionTrigger>\n How is it different from other libraries?\n </AccordionTrigger>\n <AccordionContent>\n Instead of installing via NPM, you copy and paste the components\n directly. This gives you full control to modify or customize them as\n needed.\n </AccordionContent>\n </AccordionItem>\n\n <AccordionItem value="item-3">\n <AccordionTrigger>Is Animate UI free to use?</AccordionTrigger>\n <AccordionContent>\n Absolutely! Animate UI is fully open-source. You can use, modify, and\n adapt it to fit your needs.\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/accordion/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-accordion-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-accordion-demo',
},
'radix-checkbox-demo': {
name: 'radix-checkbox-demo',
description: 'Demo showing an animated radix checkbox.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-checkbox', 'label'],
files: [
{
path: 'registry/demo/radix/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/checkbox.tsx',
content:
'import { Label } from \'@/components/ui/label\';\nimport { Checkbox } from \'@/components/animate-ui/radix/checkbox\';\n\nexport const RadixCheckboxDemo = () => {\n return (\n <div className="flex items-center space-x-2">\n <Checkbox defaultChecked id="terms" />\n <Label htmlFor="terms">Accept terms and conditions</Label>\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-checkbox-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-checkbox-demo',
},
'radix-collapsible-demo': {
name: 'radix-collapsible-demo',
description: 'Demo showing an animated radix collapsible.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-collapsible',
'button',
],
files: [
{
path: 'registry/demo/radix/collapsible/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/collapsible.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \'@/components/animate-ui/radix/collapsible\';\nimport { ChevronsUpDown } from \'lucide-react\';\n\nexport const RadixCollapsibleDemo = () => {\n return (\n <Collapsible className="w-[350px]">\n <div className="space-y-2 mb-2">\n <div className="flex items-center justify-between space-x-4">\n <h4 className="text-sm font-semibold">\n @peduarte starred 3 repositories\n </h4>\n <CollapsibleTrigger asChild>\n <Button variant="outline" size="sm" className="w-9 p-0">\n <ChevronsUpDown className="h-4 w-4" />\n <span className="sr-only">Toggle</span>\n </Button>\n </CollapsibleTrigger>\n </div>\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @radix-ui/primitives\n </div>\n </div>\n <CollapsibleContent className="space-y-2">\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @radix-ui/colors\n </div>\n <div className="rounded-md border px-4 py-3 font-mono text-sm">\n @stitches/react\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/collapsible/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-collapsible-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-collapsible-demo',
},
'radix-dialog-demo': {
name: 'radix-dialog-demo',
description: 'Demo showing an animated radix dialog.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-dialog', 'button'],
files: [
{
path: 'registry/demo/radix/dialog/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/dialog.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \'@/components/animate-ui/radix/dialog\';\n\nexport const RadixDialogDemo = () => {\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant="outline">Open Dialog</Button>\n </DialogTrigger>\n\n <DialogContent className="sm:max-w-[425px]">\n <DialogHeader>\n <DialogTitle>Terms of Service</DialogTitle>\n <DialogDescription>\n Please read the following terms of service carefully.\n </DialogDescription>\n </DialogHeader>\n\n <div className="grid gap-4 py-4">\n <p>\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,\n quos. Lorem ipsum dolor sit amet consectetur adipisicing elit.\n Quisquam, quos.\n </p>\n </div>\n\n <DialogFooter>\n <Button variant="outline">Decline</Button>\n <Button type="submit">Accept</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/dialog/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dialog-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dialog-demo',
},
'radix-dialog-from-demo': {
name: 'radix-dialog-from-demo',
description: 'Demo showing an animated radix dialog.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-dialog', 'button'],
files: [
{
path: 'registry/demo/radix/dialog-from/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/dialog-from.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from \'@/components/animate-ui/radix/dialog\';\n\nexport const RadixDialogFromDemo = () => {\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant="outline">Open Dialog</Button>\n </DialogTrigger>\n <DialogContent className="sm:max-w-[425px]" from="left">\n <DialogHeader>\n <DialogTitle>Terms of Service</DialogTitle>\n <DialogDescription>\n Please read the following terms of service carefully.\n </DialogDescription>\n </DialogHeader>\n <div className="grid gap-4 py-4">\n <p>\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam,\n quos. Lorem ipsum dolor sit amet consectetur adipisicing elit.\n Quisquam, quos.\n </p>\n </div>\n <DialogFooter>\n <Button variant="outline">Decline</Button>\n <Button type="submit">Accept</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/dialog-from/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dialog-from-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dialog-from-demo',
},
'radix-dropdown-menu-demo': {
name: 'radix-dropdown-menu-demo',
description: 'Demo showing an animated radix dropdown menu.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-dropdown-menu',
'button',
],
files: [
{
path: 'registry/demo/radix/dropdown-menu/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/dropdown-menu.tsx',
content:
"'use client';\n\nimport {\n CreditCard,\n Keyboard,\n LogOut,\n Mail,\n MessageSquare,\n Plus,\n PlusCircle,\n Settings,\n User,\n UserPlus,\n Users,\n} from 'lucide-react';\nimport { motion } from 'motion/react';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuPortal,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '@/components/animate-ui/radix/dropdown-menu';\n\nexport const RadixDropdownMenuDemo = () => {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" asChild>\n <motion.button\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n Open\n </motion.button>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\">\n <DropdownMenuLabel>My Account</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <User />\n <span>Profile</span>\n <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n <span>Billing</span>\n <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Settings />\n <span>Settings</span>\n <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Keyboard />\n <span>Keyboard shortcuts</span>\n <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Users />\n <span>Team</span>\n </DropdownMenuItem>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>\n <UserPlus />\n <span>Invite users</span>\n </DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent>\n <DropdownMenuItem>\n <Mail />\n <span>Email</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <MessageSquare />\n <span>Message</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <PlusCircle />\n <span>More...</span>\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n <DropdownMenuItem disabled>\n <Plus />\n <span>New Team</span>\n <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n <span>Log out</span>\n <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/dropdown-menu/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dropdown-menu-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dropdown-menu-demo',
},
'radix-dropdown-menu-checkboxes-demo': {
name: 'radix-dropdown-menu-checkboxes-demo',
description:
'Demo showing an animated radix dropdown menu with checkboxes.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-dropdown-menu',
'button',
],
files: [
{
path: 'registry/demo/radix/dropdown-menu-checkboxes/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/dropdown-menu-checkboxes.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion } from 'motion/react';\n\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n DropdownMenuCheckboxItemProps,\n} from '@/components/animate-ui/radix/dropdown-menu';\n\ntype Checked = DropdownMenuCheckboxItemProps['checked'];\n\nexport const RadixDropdownMenuCheckboxesDemo = () => {\n const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true);\n const [showActivityBar, setShowActivityBar] = React.useState<Checked>(false);\n const [showPanel, setShowPanel] = React.useState<Checked>(false);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" asChild>\n <motion.button\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n Open\n </motion.button>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\">\n <DropdownMenuLabel>Appearance</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n checked={showStatusBar}\n onCheckedChange={setShowStatusBar}\n >\n Status Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={showActivityBar}\n onCheckedChange={setShowActivityBar}\n disabled\n >\n Activity Bar\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={showPanel}\n onCheckedChange={setShowPanel}\n >\n Panel\n </DropdownMenuCheckboxItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/dropdown-menu-checkboxes/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dropdown-menu-checkboxes-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dropdown-menu-checkboxes-demo',
},
'radix-dropdown-menu-radio-group-demo': {
name: 'radix-dropdown-menu-radio-group-demo',
description:
'Demo showing an animated radix dropdown menu with radio groups.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-dropdown-menu',
'button',
],
files: [
{
path: 'registry/demo/radix/dropdown-menu-radio-group/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/radix/dropdown-menu-radio-group.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion } from 'motion/react';\n\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@/components/animate-ui/radix/dropdown-menu';\n\nexport const RadixDropdownMenuRadioGroupDemo = () => {\n const [position, setPosition] = React.useState('bottom');\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" asChild>\n <motion.button\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n Open\n </motion.button>\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent className=\"w-56\">\n <DropdownMenuLabel>Panel Position</DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>\n <DropdownMenuRadioItem value=\"top\">Top</DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"bottom\">Bottom</DropdownMenuRadioItem>\n <DropdownMenuRadioItem value=\"right\">Right</DropdownMenuRadioItem>\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/dropdown-menu-radio-group/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dropdown-menu-radio-group-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dropdown-menu-radio-group-demo',
},
'radix-hover-card-demo': {
name: 'radix-hover-card-demo',
description: 'Demo showing an animated radix hover card.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-hover-card',
'button',
],
files: [
{
path: 'registry/demo/radix/hover-card/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/hover-card.tsx',
content:
'import {\n HoverCard,\n HoverCardTrigger,\n HoverCardContent,\n} from \'@/components/animate-ui/radix/hover-card\';\n\nexport const RadixHoverCardDemo = () => {\n return (\n <HoverCard>\n <HoverCardTrigger asChild>\n <a\n className="size-12 rounded-full overflow-hidden border"\n href="https://twitter.com/animate_ui"\n target="_blank"\n rel="noreferrer noopener"\n >\n <img\n src="https://pbs.twimg.com/profile_images/1904970066770214912/lYBctz26_400x400.jpg"\n alt="Animate UI"\n />\n </a>\n </HoverCardTrigger>\n <HoverCardContent className="w-80">\n <div className="flex flex-col gap-4">\n <img\n className="size-16 rounded-full overflow-hidden border"\n src="https://pbs.twimg.com/profile_images/1904970066770214912/lYBctz26_400x400.jpg"\n alt="Animate UI"\n />\n <div className="flex flex-col gap-4">\n <div>\n <div className="font-bold">Animate UI</div>\n <div className="text-sm text-muted-foreground">@animate_ui</div>\n </div>\n <div className="text-sm text-muted-foreground">\n A fully animated, open-source component distribution built with\n React, TypeScript, Tailwind CSS, and Motion.\n </div>\n <div className="flex gap-4">\n <div className="flex gap-1 text-sm items-center">\n <div className="font-bold">0</div>{\' \'}\n <div className="text-muted-foreground">Following</div>\n </div>\n <div className="flex gap-1 text-sm items-center">\n <div className="font-bold">2,900</div>{\' \'}\n <div className="text-muted-foreground">Followers</div>\n </div>\n </div>\n </div>\n </div>\n </HoverCardContent>\n </HoverCard>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/hover-card/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-hover-card-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-hover-card-demo',
},
'radix-popover-demo': {
name: 'radix-popover-demo',
description: 'Demo showing an animated radix popover.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-popover',
'label',
'button',
'input',
],
files: [
{
path: 'registry/demo/radix/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/popover.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport { Label } from \'@/components/ui/label\';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \'@/components/animate-ui/radix/popover\';\n\nexport function RadixPopoverDemo() {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button variant="outline">Open popover</Button>\n </PopoverTrigger>\n <PopoverContent className="w-80">\n <div className="grid gap-4">\n <div className="space-y-2">\n <h4 className="font-medium leading-none">Dimensions</h4>\n <p className="text-sm text-muted-foreground">\n Set the dimensions for the layer.\n </p>\n </div>\n <div className="grid gap-2">\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="width">Width</Label>\n <Input\n id="width"\n defaultValue="100%"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxWidth">Max. width</Label>\n <Input\n id="maxWidth"\n defaultValue="300px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="height">Height</Label>\n <Input\n id="height"\n defaultValue="25px"\n className="col-span-2 h-8"\n />\n </div>\n <div className="grid grid-cols-3 items-center gap-4">\n <Label htmlFor="maxHeight">Max. height</Label>\n <Input\n id="maxHeight"\n defaultValue="none"\n className="col-span-2 h-8"\n />\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-popover-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-popover-demo',
},
'radix-popover-datepicker-demo': {
name: 'radix-popover-datepicker-demo',
description: 'Radix Popover DatePicker',
type: 'registry:ui',
dependencies: ['date-fns', 'lucide-react'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-popover',
'button',
'calendar',
],
files: [
{
path: 'registry/demo/radix/popover-datepicker/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/popover-datepicker.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { format } from 'date-fns';\nimport { CalendarIcon } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Calendar } from '@/components/ui/calendar';\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from '@/components/animate-ui/radix/popover';\n\nexport function RadixPopoverDatePickerDemo() {\n const [date, setDate] = React.useState<Date>();\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant={'outline'}\n className={cn(\n 'w-[240px] justify-start text-left font-normal',\n !date && 'text-muted-foreground',\n )}\n >\n <CalendarIcon />\n {date ? format(date, 'PPP') : <span>Pick a date</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={setDate}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n );\n}",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/popover-datepicker/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-popover-datepicker-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-popover-datepicker-demo',
},
'radix-progress-demo': {
name: 'radix-progress-demo',
description: 'Demo showing an animated radix progress.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-progress'],
files: [
{
path: 'registry/demo/radix/progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/progress.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Progress } from '@/components/animate-ui/radix/progress';\n\nexport const RadixProgressDemo = () => {\n const [progress, setProgress] = React.useState(0);\n\n React.useEffect(() => {\n const timer = setInterval(() => {\n setProgress((prev) => {\n if (prev >= 100) return 100;\n return prev + 25;\n });\n }, 2000);\n return () => clearInterval(timer);\n }, []);\n\n React.useEffect(() => {\n if (progress >= 100) setTimeout(() => setProgress(0), 4000);\n }, [progress]);\n\n return <Progress value={progress} className=\"w-[300px]\" />;\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/progress/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-progress-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-progress-demo',
},
'radix-radio-group-demo': {
name: 'radix-radio-group-demo',
description: 'Demo showing an animated radix radio group.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-radio-group',
'label',
],
files: [
{
path: 'registry/demo/radix/radio-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/radio-group.tsx',
content:
'import { Label } from \'@/components/ui/label\';\nimport { RadioGroup, RadioGroupItem } from \'@/components/animate-ui/radix/radio-group\';\n\nexport function RadioGroupDemo() {\n return (\n <RadioGroup defaultValue="default">\n <div className="flex items-center space-x-2">\n <RadioGroupItem value="default" id="r1" />\n <Label htmlFor="r1">Default</Label>\n </div>\n <div className="flex items-center space-x-2">\n <RadioGroupItem value="comfortable" id="r2" />\n <Label htmlFor="r2">Comfortable</Label>\n </div>\n <div className="flex items-center space-x-2">\n <RadioGroupItem value="compact" id="r3" />\n <Label htmlFor="r3">Compact</Label>\n </div>\n </RadioGroup>\n );\n}',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/radio-group/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-radio-group-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-radio-group-demo',
},
'radix-sheet-demo': {
name: 'radix-sheet-demo',
description: 'Demo showing a sheet with radix dialog.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-sheet',
'button',
'label',
'input',
],
files: [
{
path: 'registry/demo/radix/sheet/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/sheet.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport { Label } from \'@/components/ui/label\';\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \'@/components/animate-ui/radix/sheet\';\n\ninterface RadixSheetDemoProps {\n side: \'right\' | \'left\' | \'top\' | \'bottom\';\n}\nexport const RadixSheetDemo = ({ side }: RadixSheetDemoProps) => {\n return (\n <Sheet>\n <SheetTrigger asChild>\n <Button variant="outline">Open</Button>\n </SheetTrigger>\n <SheetContent side={side}>\n <SheetHeader>\n <SheetTitle>Edit profile</SheetTitle>\n <SheetDescription>\n Make changes to your profile here. Click save when you&apos;re done.\n </SheetDescription>\n </SheetHeader>\n <div className="grid gap-4 py-4">\n <div className="grid grid-cols-4 items-center gap-4">\n <Label htmlFor="name" className="text-right">\n Name\n </Label>\n <Input id="name" value="Pedro Duarte" className="col-span-3" />\n </div>\n <div className="grid grid-cols-4 items-center gap-4">\n <Label htmlFor="username" className="text-right">\n Username\n </Label>\n <Input id="username" value="@peduarte" className="col-span-3" />\n </div>\n </div>\n <SheetFooter>\n <SheetClose asChild>\n <Button type="submit">Save changes</Button>\n </SheetClose>\n </SheetFooter>\n </SheetContent>\n </Sheet>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/sheet/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-sheet-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {
Sheet: {
side: {
value: 'right',
options: {
right: 'right',
left: 'left',
top: 'top',
bottom: 'bottom',
},
},
},
};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-sheet-demo',
},
'radix-sidebar-demo': {
name: 'radix-sidebar-demo',
description: 'Demo showing a sidebar with radix components.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-sidebar',
'https://animate-ui.com/r/radix-collapsible',
'https://animate-ui.com/r/radix-dropdown-menu',
'use-mobile',
'avatar',
'breadcrumb',
'separator',
],
files: [
{
path: 'registry/demo/radix/sidebar/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/sidebar.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/components/ui/breadcrumb';\nimport { Separator } from '@/components/ui/separator';\nimport {\n SidebarProvider,\n SidebarInset,\n SidebarTrigger,\n Sidebar,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarRail,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n SidebarMenuSub,\n SidebarMenuSubItem,\n SidebarMenuSubButton,\n SidebarMenuAction,\n} from '@/components/animate-ui/radix/sidebar';\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/components/animate-ui/radix/collapsible';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuTrigger,\n} from '@/components/animate-ui/radix/dropdown-menu';\nimport {\n AudioWaveform,\n BadgeCheck,\n Bell,\n BookOpen,\n Bot,\n ChevronRight,\n ChevronsUpDown,\n Command,\n CreditCard,\n Folder,\n Forward,\n Frame,\n GalleryVerticalEnd,\n LogOut,\n Map,\n MoreHorizontal,\n PieChart,\n Plus,\n Settings2,\n Sparkles,\n SquareTerminal,\n Trash2,\n} from 'lucide-react';\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport { useIsMobile } from '@/hooks/use-mobile';\n\nconst DATA = {\n user: {\n name: 'Skyleen',\n email: 'skyleen@example.com',\n avatar:\n 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n },\n teams: [\n {\n name: 'Acme Inc',\n logo: GalleryVerticalEnd,\n plan: 'Enterprise',\n },\n {\n name: 'Acme Corp.',\n logo: AudioWaveform,\n plan: 'Startup',\n },\n {\n name: 'Evil Corp.',\n logo: Command,\n plan: 'Free',\n },\n ],\n navMain: [\n {\n title: 'Playground',\n url: '#',\n icon: SquareTerminal,\n isActive: true,\n items: [\n {\n title: 'History',\n url: '#',\n },\n {\n title: 'Starred',\n url: '#',\n },\n {\n title: 'Settings',\n url: '#',\n },\n ],\n },\n {\n title: 'Models',\n url: '#',\n icon: Bot,\n items: [\n {\n title: 'Genesis',\n url: '#',\n },\n {\n title: 'Explorer',\n url: '#',\n },\n {\n title: 'Quantum',\n url: '#',\n },\n ],\n },\n {\n title: 'Documentation',\n url: '#',\n icon: BookOpen,\n items: [\n {\n title: 'Introduction',\n url: '#',\n },\n {\n title: 'Get Started',\n url: '#',\n },\n {\n title: 'Tutorials',\n url: '#',\n },\n {\n title: 'Changelog',\n url: '#',\n },\n ],\n },\n {\n title: 'Settings',\n url: '#',\n icon: Settings2,\n items: [\n {\n title: 'General',\n url: '#',\n },\n {\n title: 'Team',\n url: '#',\n },\n {\n title: 'Billing',\n url: '#',\n },\n {\n title: 'Limits',\n url: '#',\n },\n ],\n },\n ],\n projects: [\n {\n name: 'Design Engineering',\n url: '#',\n icon: Frame,\n },\n {\n name: 'Sales & Marketing',\n url: '#',\n icon: PieChart,\n },\n {\n name: 'Travel',\n url: '#',\n icon: Map,\n },\n ],\n};\n\nexport const RadixSidebarDemo = () => {\n const isMobile = useIsMobile();\n const [activeTeam, setActiveTeam] = React.useState(DATA.teams[0]);\n\n if (!activeTeam) return null;\n\n return (\n <SidebarProvider>\n <Sidebar collapsible=\"icon\">\n <SidebarHeader>\n {/* Team Switcher */}\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <div className=\"flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground\">\n <activeTeam.logo className=\"size-4\" />\n </div>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-semibold\">\n {activeTeam.name}\n </span>\n <span className=\"truncate text-xs\">\n {activeTeam.plan}\n </span>\n </div>\n <ChevronsUpDown className=\"ml-auto\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n align=\"start\"\n side={isMobile ? 'bottom' : 'right'}\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"text-xs text-muted-foreground\">\n Teams\n </DropdownMenuLabel>\n {DATA.teams.map((team, index) => (\n <DropdownMenuItem\n key={team.name}\n onClick={() => setActiveTeam(team)}\n className=\"gap-2 p-2\"\n >\n <div className=\"flex size-6 items-center justify-center rounded-sm border\">\n <team.logo className=\"size-4 shrink-0\" />\n </div>\n {team.name}\n <DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>\n </DropdownMenuItem>\n ))}\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"gap-2 p-2\">\n <div className=\"flex size-6 items-center justify-center rounded-md border bg-background\">\n <Plus className=\"size-4\" />\n </div>\n <div className=\"font-medium text-muted-foreground\">\n Add team\n </div>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n {/* Team Switcher */}\n </SidebarHeader>\n\n <SidebarContent>\n {/* Nav Main */}\n <SidebarGroup>\n <SidebarGroupLabel>Platform</SidebarGroupLabel>\n <SidebarMenu>\n {DATA.navMain.map((item) => (\n <Collapsible\n key={item.title}\n asChild\n defaultOpen={item.isActive}\n className=\"group/collapsible\"\n >\n <SidebarMenuItem>\n <CollapsibleTrigger asChild>\n <SidebarMenuButton tooltip={item.title}>\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n <ChevronRight className=\"ml-auto transition-transform duration-300 group-data-[state=open]/collapsible:rotate-90\" />\n </SidebarMenuButton>\n </CollapsibleTrigger>\n <CollapsibleContent>\n <SidebarMenuSub>\n {item.items?.map((subItem) => (\n <SidebarMenuSubItem key={subItem.title}>\n <SidebarMenuSubButton asChild>\n <a href={subItem.url}>\n <span>{subItem.title}</span>\n </a>\n </SidebarMenuSubButton>\n </SidebarMenuSubItem>\n ))}\n </SidebarMenuSub>\n </CollapsibleContent>\n </SidebarMenuItem>\n </Collapsible>\n ))}\n </SidebarMenu>\n </SidebarGroup>\n {/* Nav Main */}\n\n {/* Nav Project */}\n <SidebarGroup className=\"group-data-[collapsible=icon]:hidden\">\n <SidebarGroupLabel>Projects</SidebarGroupLabel>\n <SidebarMenu>\n {DATA.projects.map((item) => (\n <SidebarMenuItem key={item.name}>\n <SidebarMenuButton asChild>\n <a href={item.url}>\n <item.icon />\n <span>{item.name}</span>\n </a>\n </SidebarMenuButton>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuAction showOnHover>\n <MoreHorizontal />\n <span className=\"sr-only\">More</span>\n </SidebarMenuAction>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-48 rounded-lg\"\n side={isMobile ? 'bottom' : 'right'}\n align={isMobile ? 'end' : 'start'}\n >\n <DropdownMenuItem>\n <Folder className=\"text-muted-foreground\" />\n <span>View Project</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Forward className=\"text-muted-foreground\" />\n <span>Share Project</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <Trash2 className=\"text-muted-foreground\" />\n <span>Delete Project</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n ))}\n <SidebarMenuItem>\n <SidebarMenuButton className=\"text-sidebar-foreground/70\">\n <MoreHorizontal className=\"text-sidebar-foreground/70\" />\n <span>More</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroup>\n {/* Nav Project */}\n </SidebarContent>\n <SidebarFooter>\n {/* Nav User */}\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground\"\n >\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage\n src={DATA.user.avatar}\n alt={DATA.user.name}\n />\n <AvatarFallback className=\"rounded-lg\">CN</AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-semibold\">\n {DATA.user.name}\n </span>\n <span className=\"truncate text-xs\">\n {DATA.user.email}\n </span>\n </div>\n <ChevronsUpDown className=\"ml-auto size-4\" />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg\"\n side={isMobile ? 'bottom' : 'right'}\n align=\"end\"\n sideOffset={4}\n >\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"flex items-center gap-2 px-1 py-1.5 text-left text-sm\">\n <Avatar className=\"h-8 w-8 rounded-lg\">\n <AvatarImage\n src={DATA.user.avatar}\n alt={DATA.user.name}\n />\n <AvatarFallback className=\"rounded-lg\">\n CN\n </AvatarFallback>\n </Avatar>\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-semibold\">\n {DATA.user.name}\n </span>\n <span className=\"truncate text-xs\">\n {DATA.user.email}\n </span>\n </div>\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <Sparkles />\n Upgrade to Pro\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem>\n <BadgeCheck />\n Account\n </DropdownMenuItem>\n <DropdownMenuItem>\n <CreditCard />\n Billing\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Bell />\n Notifications\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut />\n Log out\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n {/* Nav User */}\n </SidebarFooter>\n <SidebarRail />\n </Sidebar>\n\n <SidebarInset>\n <header className=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12\">\n <div className=\"flex items-center gap-2 px-4\">\n <SidebarTrigger className=\"-ml-1\" />\n <Separator orientation=\"vertical\" className=\"mr-2 h-4\" />\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem className=\"hidden md:block\">\n <BreadcrumbLink href=\"#\">\n Building Your Application\n </BreadcrumbLink>\n </BreadcrumbItem>\n <BreadcrumbSeparator className=\"hidden md:block\" />\n <BreadcrumbItem>\n <BreadcrumbPage>Data Fetching</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n <div className=\"flex flex-1 flex-col gap-4 p-4 pt-0\">\n <div className=\"grid auto-rows-min gap-4 md:grid-cols-3\">\n <div className=\"aspect-video rounded-xl bg-muted/50\" />\n <div className=\"aspect-video rounded-xl bg-muted/50\" />\n <div className=\"aspect-video rounded-xl bg-muted/50\" />\n </div>\n <div className=\"min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min\" />\n </div>\n </SidebarInset>\n </SidebarProvider>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/sidebar/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-sidebar-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-sidebar-demo',
},
'radix-switch-demo': {
name: 'radix-switch-demo',
description: 'Demo showing an animated radix switch.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-switch', 'label'],
files: [
{
path: 'registry/demo/radix/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/switch.tsx',
content:
'import { Label } from \'@/components/ui/label\';\nimport { Switch } from \'@/components/animate-ui/radix/switch\';\n\nexport const RadixSwitchDemo = () => {\n return (\n <div className="flex items-center space-x-2">\n <Label htmlFor="airplane-mode">Airplane mode</Label>\n <Switch defaultChecked id="airplane-mode" />\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-switch-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-switch-demo',
},
'radix-tabs-demo': {
name: 'radix-tabs-demo',
description: 'Demo showing an animated Radix UI tabs.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-tabs',
'label',
'input',
'button',
],
files: [
{
path: 'registry/demo/radix/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/tabs.tsx',
content:
'import { Button } from \'@/components/ui/button\';\nimport { Input } from \'@/components/ui/input\';\nimport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsContents,\n} from \'@/components/animate-ui/radix/tabs\';\nimport { Label } from \'@/components/ui/label\';\n\nexport const RadixTabsDemo = () => {\n return (\n <Tabs defaultValue="account" className="w-[400px] bg-muted rounded-lg">\n <TabsList className="grid w-full grid-cols-2">\n <TabsTrigger value="account">Account</TabsTrigger>\n <TabsTrigger value="password">Password</TabsTrigger>\n </TabsList>\n\n <TabsContents className="mx-1 mb-1 -mt-2 rounded-sm h-full bg-background">\n <TabsContent value="account" className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Make changes to your account here. Click save when you&apos;re done.\n </p>\n\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="name">Name</Label>\n <Input id="name" defaultValue="Pedro Duarte" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="username">Username</Label>\n <Input id="username" defaultValue="@peduarte" />\n </div>\n </div>\n\n <Button>Save changes</Button>\n </TabsContent>\n <TabsContent value="password" className="space-y-6 p-6">\n <p className="text-sm text-muted-foreground">\n Change your password here. After saving, you&apos;ll be logged out.\n </p>\n <div className="space-y-3">\n <div className="space-y-1">\n <Label htmlFor="current">Current password</Label>\n <Input id="current" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="new">New password</Label>\n <Input id="new" type="password" />\n </div>\n <div className="space-y-1">\n <Label htmlFor="confirm">Confirm password</Label>\n <Input id="confirm" type="password" />\n </div>\n </div>\n\n <Button>Save password</Button>\n </TabsContent>\n </TabsContents>\n </Tabs>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-tabs-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-tabs-demo',
},
'radix-toggle-group-demo': {
name: 'radix-toggle-group-demo',
description: 'Demo showing an animated Radix UI toggle group.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-toggle-group'],
files: [
{
path: 'registry/demo/radix/toggle-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/toggle-group.tsx',
content:
'import { ToggleGroup, ToggleGroupItem } from \'@/components/animate-ui/radix/toggle-group\';\nimport { Bold, Italic, Underline } from \'lucide-react\';\n\nexport const RadixToggleGroupDemo = () => {\n return (\n <ToggleGroup type="single" defaultValue="bold">\n <ToggleGroupItem value="bold" aria-label="Toggle bold">\n <Bold className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="italic" aria-label="Toggle italic">\n <Italic className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="underline" aria-label="Toggle underline">\n <Underline className="h-4 w-4" />\n </ToggleGroupItem>\n </ToggleGroup>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/toggle-group/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-toggle-group-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-toggle-group-demo',
},
'radix-toggle-group-multiple-demo': {
name: 'radix-toggle-group-multiple-demo',
description:
'Demo showing an animated Radix UI toggle group with multiple values.',
type: 'registry:ui',
dependencies: ['lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-toggle-group'],
files: [
{
path: 'registry/demo/radix/toggle-group-multiple/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/toggle-group-multiple.tsx',
content:
'import { ToggleGroup, ToggleGroupItem } from \'@/components/animate-ui/radix/toggle-group\';\nimport { Bold, Italic, Underline } from \'lucide-react\';\n\nexport const RadixToggleGroupMultipleDemo = () => {\n return (\n <ToggleGroup type="multiple" defaultValue={[\'bold\']}>\n <ToggleGroupItem value="bold" aria-label="Toggle bold">\n <Bold className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="italic" aria-label="Toggle italic">\n <Italic className="h-4 w-4" />\n </ToggleGroupItem>\n <ToggleGroupItem value="underline" aria-label="Toggle underline">\n <Underline className="h-4 w-4" />\n </ToggleGroupItem>\n </ToggleGroup>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/radix/toggle-group-multiple/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-toggle-group-multiple-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-toggle-group-multiple-demo',
},
'radix-tooltip-demo': {
name: 'radix-tooltip-demo',
description: 'Demo showing an animated radix tooltip.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-tooltip'],
files: [
{
path: 'registry/demo/radix/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/radix/tooltip.tsx',
content:
"import { Button } from '@/components/ui/button';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/animate-ui/radix/tooltip';\n\nexport const RadixTooltipDemo = () => {\n return (\n <TooltipProvider>\n <Tooltip defaultOpen>\n <TooltipTrigger asChild>\n <Button variant=\"outline\">Hover</Button>\n </TooltipTrigger>\n <TooltipContent>\n <p>Add to library</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/radix/tooltip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-tooltip-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-tooltip-demo',
},
'counting-from-number-demo': {
name: 'counting-from-number-demo',
description:
'Demo showing a counting number starting from a specific number.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/counting-number'],
files: [
{
path: 'registry/demo/text/counting-from-number/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/counting-from-number.tsx',
content:
'import { CountingNumber } from \'@/components/animate-ui/text/counting-number\';\n\nexport const CountingFromNumberDemo = () => {\n return (\n <CountingNumber\n number={0}\n fromNumber={new Date().getFullYear()}\n className="text-4xl"\n inView\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/counting-from-number/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counting-from-number-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counting-from-number-demo',
},
'counting-number-demo': {
name: 'counting-number-demo',
description: 'Demo showing a counting number.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/counting-number'],
files: [
{
path: 'registry/demo/text/counting-number/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/counting-number.tsx',
content:
'import { CountingNumber } from \'@/components/animate-ui/text/counting-number\';\n\nexport const CountingNumberDemo = () => {\n return (\n <CountingNumber number={new Date().getFullYear()} className="text-4xl" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/counting-number/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counting-number-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counting-number-demo',
},
'counting-number-decimal-demo': {
name: 'counting-number-decimal-demo',
description: 'Demo showing a counting number with a decimal separator.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/counting-number'],
files: [
{
path: 'registry/demo/text/counting-number-decimal/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/counting-number-decimal.tsx',
content:
'import { CountingNumber } from \'@/components/animate-ui/text/counting-number\';\n\nexport const CountingNumberDecimalDemo = () => {\n return (\n <CountingNumber\n number={12345.67}\n decimalPlaces={2}\n decimalSeparator=","\n className="text-4xl"\n inView\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/counting-number-decimal/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counting-number-decimal-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counting-number-decimal-demo',
},
'gradient-text-demo': {
name: 'gradient-text-demo',
description: 'Demo showing an animated gradient text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/gradient-text'],
files: [
{
path: 'registry/demo/text/gradient/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/gradient.tsx',
content:
'import { GradientText } from \'@/components/animate-ui/text/gradient\';\n\nexport const GradientTextDemo = () => {\n return <GradientText className="text-4xl font-bold" text="Gradient Text" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/gradient/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gradient-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gradient-text-demo',
},
'highlight-text-demo': {
name: 'highlight-text-demo',
description: 'Demo showing an animated highlight text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/highlight-text'],
files: [
{
path: 'registry/demo/text/highlight/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/highlight.tsx',
content:
'import { HighlightText } from \'@/components/animate-ui/text/highlight\';\n\nexport const HighlightTextDemo = () => {\n return (\n <HighlightText className="text-4xl font-semibold" text="Highlight Text" />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/highlight/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'highlight-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/highlight-text-demo',
},
'rolling-text-demo': {
name: 'rolling-text-demo',
description: 'Demo showing an animated rolling text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/rolling-text'],
files: [
{
path: 'registry/demo/text/rolling/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/rolling.tsx',
content:
'import { RollingText } from \'@/components/animate-ui/text/rolling\';\n\nexport const RollingTextDemo = () => {\n return <RollingText className="text-4xl" text="Rolling Text" />;\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/rolling/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rolling-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rolling-text-demo',
},
'rotating-text-demo': {
name: 'rotating-text-demo',
description: 'Demo showing an animated rotating text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/rotating-text'],
files: [
{
path: 'registry/demo/text/rotating/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/rotating.tsx',
content:
"import { RotatingText } from '@/components/animate-ui/text/rotating';\n\nexport const RotatingTextDemo = () => {\n return (\n <RotatingText\n className=\"text-4xl font-semibold\"\n text={['Rotating', 'Text', 'Demo']}\n />\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/rotating/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rotating-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rotating-text-demo',
},
'shimmering-text-demo': {
name: 'shimmering-text-demo',
description: 'Demo showing an animated shimmering text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/shimmering-text'],
files: [
{
path: 'registry/demo/text/shimmering/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/shimmering.tsx',
content:
'import { ShimmeringText } from \'@/components/animate-ui/text/shimmering\';\n\nexport const ShimmeringTextDemo = () => (\n <ShimmeringText\n className="text-4xl font-semibold"\n text="Shimmering Text"\n wave\n />\n);',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/shimmering/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'shimmering-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/shimmering-text-demo',
},
'sliding-number-demo': {
name: 'sliding-number-demo',
description: 'Demo showing an animated sliding number.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/sliding-number'],
files: [
{
path: 'registry/demo/text/sliding-number/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/sliding-number.tsx',
content:
'import { SlidingNumber } from \'@/components/animate-ui/text/sliding-number\';\n\nexport const SlidingNumberDemo = () => {\n return (\n <SlidingNumber\n number={new Date().getFullYear()}\n padStart\n className="text-4xl"\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/sliding-number/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'sliding-number-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/sliding-number-demo',
},
'sliding-number-decimal-demo': {
name: 'sliding-number-decimal-demo',
description:
'Demo showing an animated sliding number with a decimal separator.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/sliding-number'],
files: [
{
path: 'registry/demo/text/sliding-number-decimal/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/sliding-number-decimal.tsx',
content:
'import { SlidingNumber } from \'@/components/animate-ui/text/sliding-number\';\n\nexport const SlidingNumberDecimalDemo = () => {\n return (\n <SlidingNumber\n number={12345.67}\n decimalSeparator=","\n padStart\n className="text-4xl"\n inView\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/sliding-number-decimal/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'sliding-number-decimal-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/sliding-number-decimal-demo',
},
'splitting-text-demo': {
name: 'splitting-text-demo',
description: 'Demo showing an animated splitting text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/splitting-text'],
files: [
{
path: 'registry/demo/text/splitting/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/splitting.tsx',
content:
'import { SplittingText } from \'@/components/animate-ui/text/splitting\';\n\nexport const SplittingTextDemo = () => {\n return (\n <div className="flex flex-col gap-2 justify-center text-center">\n <SplittingText\n className="text-2xl"\n text="Introducing Splitting Text component"\n />\n <SplittingText\n className="text-base text-muted-foreground"\n text="Made with Motion. Highly customizable and easy to use."\n delay={2200}\n type="words"\n />\n </div>\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/splitting/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'splitting-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/splitting-text-demo',
},
'splitting-lines-demo': {
name: 'splitting-lines-demo',
description: 'Demo showing an animated splitting lines.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/splitting-text'],
files: [
{
path: 'registry/demo/text/splitting-lines/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/splitting-lines.tsx',
content:
"import { SplittingText } from '@/components/animate-ui/text/splitting';\n\nexport const SplittingLinesDemo = () => {\n return (\n <SplittingText\n className=\"text-lg\"\n type=\"lines\"\n inView\n motionVariants={{\n initial: { y: 50, opacity: 0, x: 0 },\n animate: { y: 0, opacity: 1, x: 0 },\n }}\n text={[\n 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.',\n 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.',\n 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos.',\n ]}\n />\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/splitting-lines/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'splitting-lines-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/splitting-lines-demo',
},
'splitting-with-custom-variants-demo': {
name: 'splitting-with-custom-variants-demo',
description:
'Demo showing an animated splitting text with custom variants.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/splitting-text'],
files: [
{
path: 'registry/demo/text/splitting-with-custom-variants/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/text/splitting-with-custom-variants.tsx',
content:
'import { SplittingText } from \'@/components/animate-ui/text/splitting\';\n\nexport const SplittingWithCustomVariantsDemo = () => {\n return (\n <SplittingText\n className="text-lg"\n type="chars"\n inView\n text="Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos."\n motionVariants={{\n initial: { y: 50, scale: 0.5, opacity: 0, x: 50, rotate: 90 },\n animate: { y: 0, scale: 1, opacity: 1, x: 0, rotate: 0 },\n transition: { duration: 0.5, ease: \'easeOut\' },\n }}\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/splitting-with-custom-variants/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'splitting-with-custom-variants-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/splitting-with-custom-variants-demo',
},
'splitting-words-demo': {
name: 'splitting-words-demo',
description: 'Demo showing an animated splitting words.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/splitting-text'],
files: [
{
path: 'registry/demo/text/splitting-words/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/splitting-words.tsx',
content:
'import { SplittingText } from \'@/components/animate-ui/text/splitting\';\n\nexport const SplittingWordsDemo = () => {\n return (\n <SplittingText\n className="text-lg"\n type="words"\n inView\n text="Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quos."\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/text/splitting-words/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'splitting-words-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/splitting-words-demo',
},
'typing-text-demo': {
name: 'typing-text-demo',
description: 'Demo showing an animated typing text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/typing-text'],
files: [
{
path: 'registry/demo/text/typing/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/typing.tsx',
content:
'import { TypingText } from \'@/components/animate-ui/text/typing\';\n\nexport const TypingTextDemo = () => {\n return (\n <TypingText\n className="text-4xl"\n text="Typing Text"\n cursor\n cursorClassName="h-9"\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/typing/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'typing-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/typing-text-demo',
},
'writing-text-demo': {
name: 'writing-text-demo',
description: 'Demo showing an animated writing text.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/writing-text'],
files: [
{
path: 'registry/demo/text/writing/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/text/writing.tsx',
content:
'import { WritingText } from \'@/components/animate-ui/text/writing\';\n\nexport const WritingTextDemo = () => {\n return (\n <WritingText\n className="text-4xl"\n text="Writing Text With Effect"\n spacing={9}\n />\n );\n};',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/demo/text/writing/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'writing-text-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/writing-text-demo',
},
'management-bar-demo': {
name: 'management-bar-demo',
description: 'Demo management Bar.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/management-bar'],
files: [
{
path: 'registry/demo/ui-elements/management-bar/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/ui-elements/management-bar.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { ManagementBar } from '@/components/animate-ui/ui-elements/management-bar';\n\nexport const ManagementBarDemo = () => <ManagementBar />;",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/ui-elements/management-bar/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'management-bar-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/management-bar-demo',
},
'notification-list-demo': {
name: 'notification-list-demo',
description: 'Demo Notification List',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/notification-list'],
files: [
{
path: 'registry/demo/ui-elements/notification-list/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/ui-elements/notification-list.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { NotificationList } from '@/components/animate-ui/ui-elements/notification-list';\n\nexport const NotificationListDemo = () => <NotificationList />;",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/ui-elements/notification-list/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'notification-list-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/notification-list-demo',
},
'playful-todolist-demo': {
name: 'playful-todolist-demo',
description: 'Demo Playful Todolist.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/playful-todolist'],
files: [
{
path: 'registry/demo/ui-elements/playful-todolist/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/demo/ui-elements/playful-todolist.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { PlayfulTodolist } from '@/components/animate-ui/ui-elements/playful-todolist';\n\nexport const PlayfulTodolistDemo = () => <PlayfulTodolist />;",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/ui-elements/playful-todolist/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'playful-todolist-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/playful-todolist-demo',
},
'user-presence-avatar-demo': {
name: 'user-presence-avatar-demo',
description: 'Demo User Presence Avatar Demo.',
type: 'registry:ui',
dependencies: undefined,
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/user-presence-avatar'],
files: [
{
path: 'registry/demo/ui-elements/user-presence-avatar/index.tsx',
type: 'registry:ui',
target:
'components/animate-ui/demo/ui-elements/user-presence-avatar.tsx',
content:
"'use client';\n\nimport * as React from 'react';\n\nimport { UserPresenceAvatar } from '@/components/animate-ui/ui-elements/user-presence-avatar';\n\nexport const UserPresenceAvatarDemo = () => <UserPresenceAvatar />;",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/demo/ui-elements/user-presence-avatar/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'user-presence-avatar-demo';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/user-presence-avatar-demo',
},
magnetic: {
name: 'magnetic',
description:
'A magnetic effect that clings to the cursor, creating a magnetic attraction effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/effects/magnetic/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/effects/magnetic.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n HTMLMotionProps,\n motion,\n useMotionValue,\n useSpring,\n type SpringOptions,\n} from 'motion/react';\n\ntype MagneticProps = {\n children: React.ReactElement;\n strength?: number;\n range?: number;\n springOptions?: SpringOptions;\n onlyOnHover?: boolean;\n disableOnTouch?: boolean;\n} & HTMLMotionProps<'div'>;\n\nfunction Magnetic({\n ref,\n children,\n strength = 0.5,\n range = 120,\n springOptions = { stiffness: 100, damping: 10, mass: 0.5 },\n onlyOnHover = false,\n disableOnTouch = true,\n style,\n onMouseEnter,\n onMouseLeave,\n onMouseMove,\n ...props\n}: MagneticProps) {\n const localRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const isTouchDevice = React.useMemo(() => {\n if (typeof window === 'undefined') return false;\n return window.matchMedia('(pointer:coarse)').matches;\n }, []);\n\n const [active, setActive] = React.useState(!onlyOnHover);\n\n const rawX = useMotionValue(0);\n const rawY = useMotionValue(0);\n const x = useSpring(rawX, springOptions);\n const y = useSpring(rawY, springOptions);\n\n const compute = React.useCallback(\n (e: MouseEvent | React.MouseEvent) => {\n if (!localRef.current) return;\n const { left, top, width, height } =\n localRef.current.getBoundingClientRect();\n const cx = left + width / 2;\n const cy = top + height / 2;\n const dx = e.clientX - cx;\n const dy = e.clientY - cy;\n const dist = Math.hypot(dx, dy);\n\n if ((active || !onlyOnHover) && dist <= range) {\n const factor = (1 - dist / range) * strength;\n rawX.set(dx * factor);\n rawY.set(dy * factor);\n } else {\n rawX.set(0);\n rawY.set(0);\n }\n },\n [active, onlyOnHover, range, strength, rawX, rawY],\n );\n\n React.useEffect(() => {\n if (disableOnTouch && isTouchDevice) return;\n const handle = (e: MouseEvent) => compute(e);\n window.addEventListener('mousemove', handle);\n return () => window.removeEventListener('mousemove', handle);\n }, [compute, disableOnTouch, isTouchDevice]);\n\n return (\n <motion.div\n ref={localRef}\n style={{ display: 'inline-block', ...style, x, y }}\n onMouseEnter={(e) => {\n if (onlyOnHover) setActive(true);\n onMouseEnter?.(e);\n }}\n onMouseLeave={(e) => {\n if (onlyOnHover) setActive(false);\n rawX.set(0);\n rawY.set(0);\n onMouseLeave?.(e);\n }}\n onMouseMove={(e) => {\n if (onlyOnHover) compute(e);\n onMouseMove?.(e);\n }}\n {...props}\n >\n {children}\n </motion.div>\n );\n}\n\nexport { Magnetic, type MagneticProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/effects/magnetic/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'magnetic';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/magnetic',
},
'motion-effect': {
name: 'motion-effect',
description:
'Motion effect component that displays the motion effect (fade in, slide in, etc.).',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/effects/motion-effect/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/effects/motion-effect.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n AnimatePresence,\n motion,\n useInView,\n type HTMLMotionProps,\n type UseInViewOptions,\n type Transition,\n type Variant,\n} from 'motion/react';\n\ntype MotionEffectProps = HTMLMotionProps<'div'> & {\n children: React.ReactNode;\n className?: string;\n transition?: Transition;\n delay?: number;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n blur?: string | boolean;\n slide?:\n | {\n direction?: 'up' | 'down' | 'left' | 'right';\n offset?: number;\n }\n | boolean;\n fade?: { initialOpacity?: number; opacity?: number } | boolean;\n zoom?:\n | {\n initialScale?: number;\n scale?: number;\n }\n | boolean;\n};\n\nfunction MotionEffect({\n ref,\n children,\n className,\n transition = { type: 'spring', stiffness: 200, damping: 20 },\n delay = 0,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n blur = false,\n slide = false,\n fade = false,\n zoom = false,\n ...props\n}: MotionEffectProps) {\n const localRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const hiddenVariant: Variant = {};\n const visibleVariant: Variant = {};\n\n if (slide) {\n const offset = typeof slide === 'boolean' ? 100 : (slide.offset ?? 100);\n const direction =\n typeof slide === 'boolean' ? 'left' : (slide.direction ?? 'left');\n const axis = direction === 'up' || direction === 'down' ? 'y' : 'x';\n hiddenVariant[axis] =\n direction === 'left' || direction === 'up' ? -offset : offset;\n visibleVariant[axis] = 0;\n }\n\n if (fade) {\n hiddenVariant.opacity =\n typeof fade === 'boolean' ? 0 : (fade.initialOpacity ?? 0);\n visibleVariant.opacity =\n typeof fade === 'boolean' ? 1 : (fade.opacity ?? 1);\n }\n\n if (zoom) {\n hiddenVariant.scale =\n typeof zoom === 'boolean' ? 0.5 : (zoom.initialScale ?? 0.5);\n visibleVariant.scale = typeof zoom === 'boolean' ? 1 : (zoom.scale ?? 1);\n }\n\n if (blur) {\n hiddenVariant.filter =\n typeof blur === 'boolean' ? 'blur(10px)' : `blur(${blur})`;\n visibleVariant.filter = 'blur(0px)';\n }\n\n return (\n <AnimatePresence>\n <motion.div\n ref={localRef}\n data-slot=\"motion-effect\"\n initial=\"hidden\"\n animate={isInView ? 'visible' : 'hidden'}\n exit=\"hidden\"\n variants={{\n hidden: hiddenVariant,\n visible: visibleVariant,\n }}\n transition={{\n ...transition,\n delay: (transition?.delay ?? 0) + delay,\n }}\n className={className}\n {...props}\n >\n {children}\n </motion.div>\n </AnimatePresence>\n );\n}\n\nexport { MotionEffect, type MotionEffectProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/effects/motion-effect/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-effect';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-effect',
},
'motion-highlight': {
name: 'motion-highlight',
description:
'Motion highlight component that displays the motion highlight effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/effects/motion-highlight/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/effects/motion-highlight.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { AnimatePresence, Transition, motion } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype MotionHighlightMode = 'children' | 'parent';\n\ntype Bounds = {\n top: number;\n left: number;\n width: number;\n height: number;\n};\n\ntype MotionHighlightContextType<T extends string> = {\n mode: MotionHighlightMode;\n activeValue: T | null;\n setActiveValue: (value: T | null) => void;\n setBounds: (bounds: DOMRect) => void;\n clearBounds: () => void;\n id: string;\n hover: boolean;\n className?: string;\n activeClassName?: string;\n setActiveClassName: (className: string) => void;\n transition?: Transition;\n disabled?: boolean;\n enabled?: boolean;\n exitDelay?: number;\n forceUpdateBounds?: boolean;\n};\n\nconst MotionHighlightContext = React.createContext<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n MotionHighlightContextType<any> | undefined\n>(undefined);\n\nfunction useMotionHighlight<T extends string>(): MotionHighlightContextType<T> {\n const context = React.useContext(MotionHighlightContext);\n if (!context) {\n throw new Error(\n 'useMotionHighlight must be used within a MotionHighlightProvider',\n );\n }\n return context as unknown as MotionHighlightContextType<T>;\n}\n\ntype BaseMotionHighlightProps<T extends string> = {\n mode?: MotionHighlightMode;\n value?: T | null;\n defaultValue?: T | null;\n onValueChange?: (value: T | null) => void;\n className?: string;\n transition?: Transition;\n hover?: boolean;\n disabled?: boolean;\n enabled?: boolean;\n exitDelay?: number;\n};\n\ntype ParentModeMotionHighlightProps = {\n boundsOffset?: Partial<Bounds>;\n containerClassName?: string;\n forceUpdateBounds?: boolean;\n};\n\ntype ControlledParentModeMotionHighlightProps<T extends string> =\n BaseMotionHighlightProps<T> &\n ParentModeMotionHighlightProps & {\n mode: 'parent';\n controlledItems: true;\n children: React.ReactNode;\n };\n\ntype ControlledChildrenModeMotionHighlightProps<T extends string> =\n BaseMotionHighlightProps<T> & {\n mode?: 'children' | undefined;\n controlledItems: true;\n children: React.ReactNode;\n };\n\ntype UncontrolledParentModeMotionHighlightProps<T extends string> =\n BaseMotionHighlightProps<T> &\n ParentModeMotionHighlightProps & {\n mode: 'parent';\n controlledItems?: false;\n itemsClassName?: string;\n children: React.ReactElement | React.ReactElement[];\n };\n\ntype UncontrolledChildrenModeMotionHighlightProps<T extends string> =\n BaseMotionHighlightProps<T> & {\n mode?: 'children';\n controlledItems?: false;\n itemsClassName?: string;\n children: React.ReactElement | React.ReactElement[];\n };\n\ntype MotionHighlightProps<T extends string> = React.ComponentProps<'div'> &\n (\n | ControlledParentModeMotionHighlightProps<T>\n | ControlledChildrenModeMotionHighlightProps<T>\n | UncontrolledParentModeMotionHighlightProps<T>\n | UncontrolledChildrenModeMotionHighlightProps<T>\n );\n\nfunction MotionHighlight<T extends string>({\n ref,\n ...props\n}: MotionHighlightProps<T>) {\n const {\n children,\n value,\n defaultValue,\n onValueChange,\n className,\n transition = { type: 'spring', stiffness: 350, damping: 35 },\n hover = false,\n enabled = true,\n controlledItems,\n disabled = false,\n exitDelay = 0.2,\n mode = 'children',\n } = props;\n\n const localRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const [activeValue, setActiveValue] = React.useState<T | null>(\n value ?? defaultValue ?? null,\n );\n const [boundsState, setBoundsState] = React.useState<Bounds | null>(null);\n const [activeClassNameState, setActiveClassNameState] =\n React.useState<string>('');\n\n const safeSetActiveValue = React.useCallback(\n (id: T | null) => {\n setActiveValue((prev) => (prev === id ? prev : id));\n if (id !== activeValue) onValueChange?.(id as T);\n },\n [activeValue, onValueChange],\n );\n\n const safeSetBounds = React.useCallback(\n (bounds: DOMRect) => {\n if (!localRef.current) return;\n\n const boundsOffset = (props as ParentModeMotionHighlightProps)\n ?.boundsOffset ?? {\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n };\n\n const containerRect = localRef.current.getBoundingClientRect();\n const newBounds: Bounds = {\n top: bounds.top - containerRect.top + (boundsOffset.top ?? 0),\n left: bounds.left - containerRect.left + (boundsOffset.left ?? 0),\n width: bounds.width + (boundsOffset.width ?? 0),\n height: bounds.height + (boundsOffset.height ?? 0),\n };\n\n setBoundsState((prev) => {\n if (\n prev &&\n prev.top === newBounds.top &&\n prev.left === newBounds.left &&\n prev.width === newBounds.width &&\n prev.height === newBounds.height\n ) {\n return prev;\n }\n return newBounds;\n });\n },\n [props],\n );\n\n const clearBounds = React.useCallback(() => {\n setBoundsState((prev) => (prev === null ? prev : null));\n }, []);\n\n React.useEffect(() => {\n if (value !== undefined) setActiveValue(value);\n else if (defaultValue !== undefined) setActiveValue(defaultValue);\n }, [value, defaultValue]);\n\n const id = React.useId();\n\n React.useEffect(() => {\n if (mode !== 'parent') return;\n const container = localRef.current;\n if (!container) return;\n\n const onScroll = () => {\n if (!activeValue) return;\n const activeEl = container.querySelector<HTMLElement>(\n `[data-value=\"${activeValue}\"][data-highlight=\"true\"]`,\n );\n if (activeEl) safeSetBounds(activeEl.getBoundingClientRect());\n };\n\n container.addEventListener('scroll', onScroll, { passive: true });\n return () => container.removeEventListener('scroll', onScroll);\n }, [mode, activeValue, safeSetBounds]);\n\n const render = React.useCallback(\n (children: React.ReactNode) => {\n if (mode === 'parent') {\n return (\n <div\n ref={localRef}\n data-slot=\"motion-highlight-container\"\n className={cn(\n 'relative',\n (props as ParentModeMotionHighlightProps)?.containerClassName,\n )}\n >\n <AnimatePresence initial={false}>\n {boundsState && (\n <motion.div\n data-slot=\"motion-highlight\"\n animate={{\n top: boundsState.top,\n left: boundsState.left,\n width: boundsState.width,\n height: boundsState.height,\n opacity: 1,\n }}\n initial={{\n top: boundsState.top,\n left: boundsState.left,\n width: boundsState.width,\n height: boundsState.height,\n opacity: 0,\n }}\n exit={{\n opacity: 0,\n transition: {\n ...transition,\n delay: (transition?.delay ?? 0) + (exitDelay ?? 0),\n },\n }}\n transition={transition}\n className={cn(\n 'absolute bg-muted z-0',\n className,\n activeClassNameState,\n )}\n />\n )}\n </AnimatePresence>\n {children}\n </div>\n );\n }\n\n return children;\n },\n [\n mode,\n props,\n boundsState,\n transition,\n exitDelay,\n className,\n activeClassNameState,\n ],\n );\n\n return (\n <MotionHighlightContext.Provider\n value={{\n mode,\n activeValue,\n setActiveValue: safeSetActiveValue,\n id,\n hover,\n className,\n transition,\n disabled,\n enabled,\n exitDelay,\n setBounds: safeSetBounds,\n clearBounds,\n activeClassName: activeClassNameState,\n setActiveClassName: setActiveClassNameState,\n forceUpdateBounds: (props as ParentModeMotionHighlightProps)\n ?.forceUpdateBounds,\n }}\n >\n {enabled\n ? controlledItems\n ? render(children)\n : render(\n React.Children.map(children, (child, index) => (\n <MotionHighlightItem\n key={index}\n className={props?.itemsClassName}\n >\n {child}\n </MotionHighlightItem>\n )),\n )\n : children}\n </MotionHighlightContext.Provider>\n );\n}\n\nfunction getNonOverridingDataAttributes(\n element: React.ReactElement,\n dataAttributes: Record<string, unknown>,\n): Record<string, unknown> {\n return Object.keys(dataAttributes).reduce<Record<string, unknown>>(\n (acc, key) => {\n if ((element.props as Record<string, unknown>)[key] === undefined) {\n acc[key] = dataAttributes[key];\n }\n return acc;\n },\n {},\n );\n}\n\ntype ExtendedChildProps = React.ComponentProps<'div'> & {\n id?: string;\n ref?: React.Ref<HTMLElement>;\n 'data-active'?: string;\n 'data-value'?: string;\n 'data-disabled'?: boolean;\n 'data-highlight'?: boolean;\n 'data-slot'?: string;\n};\n\ntype MotionHighlightItemProps = React.ComponentProps<'div'> & {\n children: React.ReactElement;\n id?: string;\n value?: string;\n className?: string;\n transition?: Transition;\n activeClassName?: string;\n disabled?: boolean;\n exitDelay?: number;\n asChild?: boolean;\n forceUpdateBounds?: boolean;\n};\n\nfunction MotionHighlightItem({\n ref,\n children,\n id,\n value,\n className,\n transition,\n disabled = false,\n activeClassName,\n exitDelay,\n asChild = false,\n forceUpdateBounds,\n ...props\n}: MotionHighlightItemProps) {\n const itemId = React.useId();\n const {\n activeValue,\n setActiveValue,\n mode,\n setBounds,\n clearBounds,\n hover,\n enabled,\n className: contextClassName,\n transition: contextTransition,\n id: contextId,\n disabled: contextDisabled,\n exitDelay: contextExitDelay,\n forceUpdateBounds: contextForceUpdateBounds,\n setActiveClassName,\n } = useMotionHighlight();\n\n const element = children as React.ReactElement<ExtendedChildProps>;\n const childValue =\n id ?? value ?? element.props?.['data-value'] ?? element.props?.id ?? itemId;\n const isActive = activeValue === childValue;\n const isDisabled = disabled === undefined ? contextDisabled : disabled;\n const itemTransition = transition ?? contextTransition;\n\n const localRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n if (mode !== 'parent') return;\n let rafId: number;\n let previousBounds: Bounds | null = null;\n const shouldUpdateBounds =\n forceUpdateBounds === true ||\n (contextForceUpdateBounds && forceUpdateBounds !== false);\n\n const updateBounds = () => {\n if (!localRef.current) return;\n\n const bounds = localRef.current.getBoundingClientRect();\n\n if (shouldUpdateBounds) {\n if (\n previousBounds &&\n previousBounds.top === bounds.top &&\n previousBounds.left === bounds.left &&\n previousBounds.width === bounds.width &&\n previousBounds.height === bounds.height\n ) {\n rafId = requestAnimationFrame(updateBounds);\n return;\n }\n previousBounds = bounds;\n rafId = requestAnimationFrame(updateBounds);\n }\n\n setBounds(bounds);\n };\n\n if (isActive) {\n updateBounds();\n setActiveClassName(activeClassName ?? '');\n } else if (!activeValue) clearBounds();\n\n if (shouldUpdateBounds) return () => cancelAnimationFrame(rafId);\n }, [\n mode,\n isActive,\n activeValue,\n setBounds,\n clearBounds,\n activeClassName,\n setActiveClassName,\n forceUpdateBounds,\n contextForceUpdateBounds,\n ]);\n\n if (!React.isValidElement(children)) return children;\n\n const dataAttributes = {\n 'data-active': isActive ? 'true' : 'false',\n 'aria-selected': isActive,\n 'data-disabled': isDisabled,\n 'data-value': childValue,\n 'data-highlight': true,\n };\n\n const commonHandlers = hover\n ? {\n onMouseEnter: (e: React.MouseEvent<HTMLDivElement>) => {\n setActiveValue(childValue);\n element.props.onMouseEnter?.(e);\n },\n onMouseLeave: (e: React.MouseEvent<HTMLDivElement>) => {\n setActiveValue(null);\n element.props.onMouseLeave?.(e);\n },\n }\n : {\n onClick: (e: React.MouseEvent<HTMLDivElement>) => {\n setActiveValue(childValue);\n element.props.onClick?.(e);\n },\n };\n\n if (asChild) {\n if (mode === 'children') {\n return React.cloneElement(\n element,\n {\n key: childValue,\n ref: localRef,\n className: cn('relative', element.props.className),\n ...getNonOverridingDataAttributes(element, {\n ...dataAttributes,\n 'data-slot': 'motion-highlight-item-container',\n }),\n ...commonHandlers,\n ...props,\n },\n <>\n <AnimatePresence initial={false}>\n {isActive && !isDisabled && (\n <motion.div\n layoutId={`transition-background-${contextId}`}\n data-slot=\"motion-highlight\"\n className={cn(\n 'absolute inset-0 bg-muted z-0',\n contextClassName,\n activeClassName,\n )}\n transition={itemTransition}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{\n opacity: 0,\n transition: {\n ...itemTransition,\n delay:\n (itemTransition?.delay ?? 0) +\n (exitDelay ?? contextExitDelay ?? 0),\n },\n }}\n {...dataAttributes}\n />\n )}\n </AnimatePresence>\n\n <div\n data-slot=\"motion-highlight-item\"\n className={cn('relative z-[1]', className)}\n {...dataAttributes}\n >\n {children}\n </div>\n </>,\n );\n }\n\n return React.cloneElement(element, {\n ref: localRef,\n ...getNonOverridingDataAttributes(element, {\n ...dataAttributes,\n 'data-slot': 'motion-highlight-item',\n }),\n ...commonHandlers,\n });\n }\n\n return enabled ? (\n <div\n key={childValue}\n ref={localRef}\n data-slot=\"motion-highlight-item-container\"\n className={cn(mode === 'children' && 'relative', className)}\n {...dataAttributes}\n {...props}\n {...commonHandlers}\n >\n {mode === 'children' && (\n <AnimatePresence initial={false}>\n {isActive && !isDisabled && (\n <motion.div\n layoutId={`transition-background-${contextId}`}\n data-slot=\"motion-highlight\"\n className={cn(\n 'absolute inset-0 bg-muted z-0',\n contextClassName,\n activeClassName,\n )}\n transition={itemTransition}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{\n opacity: 0,\n transition: {\n ...itemTransition,\n delay:\n (itemTransition?.delay ?? 0) +\n (exitDelay ?? contextExitDelay ?? 0),\n },\n }}\n {...dataAttributes}\n />\n )}\n </AnimatePresence>\n )}\n\n {React.cloneElement(element, {\n className: cn('relative z-[1]', element.props.className),\n ...getNonOverridingDataAttributes(element, {\n ...dataAttributes,\n 'data-slot': 'motion-highlight-item',\n }),\n })}\n </div>\n ) : (\n children\n );\n}\n\nexport {\n MotionHighlight,\n MotionHighlightItem,\n useMotionHighlight,\n type MotionHighlightProps,\n type MotionHighlightItemProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/effects/motion-highlight/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'motion-highlight';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/motion-highlight',
},
'headless-accordion': {
name: 'headless-accordion',
description:
'A vertically stacked set of interactive headings that each reveal an associated section of content built with Headless UI.',
type: 'registry:ui',
dependencies: ['lucide-react', 'motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/headless-disclosure'],
files: [
{
path: 'registry/headless/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/accordion.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Transition } from 'motion/react';\nimport { ChevronDown } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\nimport {\n Disclosure,\n DisclosureButton,\n DisclosurePanel,\n type DisclosureProps,\n type DisclosureButtonProps,\n type DisclosurePanelProps,\n} from '@/components/animate-ui/headless/disclosure';\n\ntype AccordionProps<TTag extends React.ElementType = 'div'> =\n React.ComponentProps<TTag> & {\n children: React.ReactNode;\n as?: TTag;\n };\n\nfunction Accordion<TTag extends React.ElementType = 'div'>({\n as: Component = 'div',\n ...props\n}: AccordionProps<TTag>) {\n return <Component data-slot=\"accordion\" {...props} />;\n}\n\ntype AccordionItemProps<TTag extends React.ElementType = 'div'> =\n DisclosureProps<TTag> & {\n className?: string;\n as?: TTag;\n };\n\nfunction AccordionItem<TTag extends React.ElementType = 'div'>(\n props: AccordionItemProps<TTag>,\n) {\n const { className, as = 'div', ...rest } = props;\n\n return (\n <Disclosure\n data-slot=\"accordion-item\"\n {...rest}\n as={as as React.ElementType}\n className={cn('border-b', className)}\n />\n );\n}\n\ntype AccordionButtonProps<TTag extends React.ElementType = 'button'> =\n DisclosureButtonProps<TTag> & {\n transition?: Transition;\n chevron?: boolean;\n className?: string;\n as?: TTag;\n };\n\nfunction AccordionButton<TTag extends React.ElementType = 'button'>(\n props: AccordionButtonProps<TTag>,\n) {\n const {\n children,\n className,\n transition = { type: 'spring', stiffness: 150, damping: 17 },\n chevron = true,\n ...rest\n } = props;\n\n return (\n <DisclosureButton\n data-slot=\"accordion-button\"\n {...rest}\n className={cn(\n 'flex w-full text-start flex-1 items-center justify-between py-4 font-medium hover:underline',\n className,\n )}\n >\n {(bag) => (\n <>\n {typeof children === 'function' ? children(bag) : children}\n\n {chevron && (\n <motion.div\n data-slot=\"accordion-button-chevron\"\n animate={{ rotate: bag.open ? 180 : 0 }}\n transition={transition}\n >\n <ChevronDown className=\"size-5 shrink-0\" />\n </motion.div>\n )}\n </>\n )}\n </DisclosureButton>\n );\n}\n\ntype AccordionPanelProps<TTag extends React.ElementType = 'div'> =\n DisclosurePanelProps<TTag> & {\n as?: TTag;\n };\n\nfunction AccordionPanel<TTag extends React.ElementType = 'div'>(\n props: AccordionPanelProps<TTag>,\n) {\n const { children, className, as = 'div', ...rest } = props;\n\n return (\n <DisclosurePanel\n data-slot=\"accordion-panel\"\n {...rest}\n as={as as React.ElementType}\n >\n {(bag) => (\n <div className={cn('pb-4 pt-0 text-sm', className)}>\n {typeof children === 'function' ? children(bag) : children}\n </div>\n )}\n </DisclosurePanel>\n );\n}\n\nexport {\n Accordion,\n AccordionItem,\n AccordionButton,\n AccordionPanel,\n type AccordionProps,\n type AccordionItemProps,\n type AccordionButtonProps,\n type AccordionPanelProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/accordion/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-accordion';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-accordion',
},
'headless-checkbox': {
name: 'headless-checkbox',
description:
"Checkboxes provide the same functionality as native HTML checkboxes, without any of the styling, giving you a clean slate to design them however you'd like.",
type: 'registry:ui',
dependencies: ['@headlessui/react', 'motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/headless/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/checkbox.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n Checkbox as CheckboxPrimitive,\n type CheckboxProps as CheckboxPrimitiveProps,\n} from '@headlessui/react';\nimport { motion, type HTMLMotionProps } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype CheckboxProps<TTag extends React.ElementType = typeof motion.button> =\n CheckboxPrimitiveProps<TTag> &\n Omit<\n HTMLMotionProps<'button'>,\n 'checked' | 'onChange' | 'defaultChecked' | 'children'\n > & {\n as?: TTag;\n };\n\nfunction Checkbox<TTag extends React.ElementType = typeof motion.button>(\n props: CheckboxProps<TTag>,\n) {\n const { className, as = motion.button, ...rest } = props;\n\n return (\n <CheckboxPrimitive\n data-slot=\"checkbox\"\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n {...rest}\n className={cn(\n 'peer size-5 flex items-center justify-center shrink-0 rounded-sm bg-input transition-colors duration-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[checked]:bg-primary data-[checked]:text-primary-foreground',\n className,\n )}\n as={as as React.ElementType}\n >\n {({ checked }) => (\n <motion.svg\n data-slot=\"checkbox-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth=\"3.5\"\n stroke=\"currentColor\"\n className=\"size-3.5\"\n initial=\"unchecked\"\n animate={checked ? 'checked' : 'unchecked'}\n >\n <motion.path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4.5 12.75l6 6 9-13.5\"\n variants={{\n checked: {\n pathLength: 1,\n opacity: 1,\n transition: {\n duration: 0.2,\n delay: 0.2,\n },\n },\n unchecked: {\n pathLength: 0,\n opacity: 0,\n transition: {\n duration: 0.2,\n },\n },\n }}\n />\n </motion.svg>\n )}\n </CheckboxPrimitive>\n );\n}\n\nexport { Checkbox, type CheckboxProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-checkbox';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-checkbox',
},
'headless-dialog': {
name: 'headless-dialog',
description:
'A fully-managed, renderless dialog component jam-packed with accessibility and keyboard features, perfect for building completely custom dialogs and alerts.',
type: 'registry:ui',
dependencies: ['@headlessui/react', 'motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/headless/dialog/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/dialog.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n Dialog as DialogPrimitive,\n DialogBackdrop as DialogBackdropPrimitive,\n DialogPanel as DialogPanelPrimitive,\n DialogTitle as DialogTitlePrimitive,\n Description as DialogDescriptionPrimitive,\n type DialogProps as DialogPrimitiveProps,\n type DialogBackdropProps as DialogBackdropPrimitiveProps,\n type DialogPanelProps as DialogPanelPrimitiveProps,\n type DialogTitleProps as DialogTitlePrimitiveProps,\n CloseButton,\n} from '@headlessui/react';\nimport {\n motion,\n AnimatePresence,\n type Transition,\n type HTMLMotionProps,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport { X } from 'lucide-react';\n\ntype DialogProps<TTag extends React.ElementType = 'div'> = Omit<\n DialogPrimitiveProps<TTag>,\n 'static'\n> & {\n className?: string;\n as?: TTag;\n};\n\nfunction Dialog<TTag extends React.ElementType = 'div'>({\n className,\n ...props\n}: DialogProps<TTag>) {\n return (\n <AnimatePresence>\n {props?.open && (\n <DialogPrimitive\n data-slot=\"dialog\"\n className={cn('relative z-50', className)}\n {...props}\n static\n />\n )}\n </AnimatePresence>\n );\n}\n\ntype DialogBackdropProps<TTag extends React.ElementType = typeof motion.div> =\n DialogBackdropPrimitiveProps<TTag> & {\n className?: string;\n as?: TTag;\n };\n\nfunction DialogBackdrop<TTag extends React.ElementType = typeof motion.div>(\n props: DialogBackdropProps<TTag>,\n) {\n const { className, as = motion.div, ...rest } = props;\n\n return (\n <DialogBackdropPrimitive\n key=\"dialog-backdrop\"\n data-slot=\"dialog-backdrop\"\n className={cn('fixed inset-0 z-50 bg-black/80', className)}\n as={as as React.ElementType}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n {...rest}\n />\n );\n}\n\ntype FlipDirection = 'top' | 'bottom' | 'left' | 'right';\n\ntype DialogPanelProps<TTag extends React.ElementType = typeof motion.div> =\n Omit<DialogPanelPrimitiveProps<typeof motion.div>, 'transition'> &\n Omit<HTMLMotionProps<'div'>, 'children'> & {\n from?: FlipDirection;\n transition?: Transition;\n as?: TTag;\n };\n\nfunction DialogPanel<TTag extends React.ElementType = typeof motion.div>(\n props: DialogPanelProps<TTag>,\n) {\n const {\n children,\n className,\n as = motion.div,\n from = 'top',\n transition = { type: 'spring', stiffness: 150, damping: 25 },\n ...rest\n } = props;\n\n const initialRotation =\n from === 'top' || from === 'left' ? '20deg' : '-20deg';\n const isVertical = from === 'top' || from === 'bottom';\n const rotateAxis = isVertical ? 'rotateX' : 'rotateY';\n\n return (\n <DialogPanelPrimitive\n key=\"dialog-panel\"\n data-slot=\"dialog-panel\"\n className={cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg rounded-xl',\n className,\n )}\n as={as as React.ElementType}\n initial={{\n opacity: 0,\n filter: 'blur(4px)',\n transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n transition,\n }}\n animate={{\n opacity: 1,\n filter: 'blur(0px)',\n transform: `perspective(500px) ${rotateAxis}(0deg) scale(1)`,\n transition,\n }}\n exit={{\n opacity: 0,\n filter: 'blur(4px)',\n transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n transition,\n }}\n {...rest}\n >\n {(bag) => (\n <>\n {typeof children === 'function' ? children(bag) : children}\n\n <CloseButton\n data-slot=\"dialog-panel-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\"\n >\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </CloseButton>\n </>\n )}\n </DialogPanelPrimitive>\n );\n}\n\ntype DialogHeaderProps<TTag extends React.ElementType = 'div'> =\n React.ComponentProps<TTag> & {\n as?: TTag;\n };\n\nfunction DialogHeader<TTag extends React.ElementType = 'div'>({\n className,\n as: Component = 'div',\n ...props\n}: DialogHeaderProps<TTag>) {\n return (\n <Component\n data-slot=\"dialog-header\"\n className={cn(\n 'flex flex-col space-y-1.5 text-center sm:text-left',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogFooterProps<TTag extends React.ElementType = 'div'> =\n React.ComponentProps<TTag> & {\n as?: TTag;\n };\n\nfunction DialogFooter({\n className,\n as: Component = 'div',\n ...props\n}: DialogFooterProps) {\n return (\n <Component\n data-slot=\"dialog-footer\"\n className={cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end gap-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogTitleProps<TTag extends React.ElementType = 'h2'> =\n DialogTitlePrimitiveProps<TTag> & {\n className?: string;\n as?: TTag;\n };\n\nfunction DialogTitle<TTag extends React.ElementType = 'h2'>({\n className,\n ...props\n}: DialogTitleProps<TTag>) {\n return (\n <DialogTitlePrimitive\n data-slot=\"dialog-title\"\n className={cn(\n 'text-lg font-semibold leading-none tracking-tight',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogDescriptionProps<TTag extends React.ElementType = 'div'> =\n React.ComponentProps<typeof DialogDescriptionPrimitive<TTag>> & {\n className?: string;\n as?: TTag;\n };\n\nfunction DialogDescription<TTag extends React.ElementType = 'div'>({\n className,\n ...props\n}: DialogDescriptionProps<TTag>) {\n return (\n <DialogDescriptionPrimitive\n data-slot=\"dialog-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogBackdrop,\n DialogPanel,\n DialogTitle,\n DialogDescription,\n DialogHeader,\n DialogFooter,\n type DialogProps,\n type DialogBackdropProps,\n type DialogPanelProps,\n type DialogTitleProps,\n type DialogDescriptionProps,\n type DialogHeaderProps,\n type DialogFooterProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/dialog/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-dialog';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-dialog',
},
'headless-disclosure': {
name: 'headless-disclosure',
description:
'A simple, accessible foundation for building custom UIs that show and hide content, like togglable accordion panels.',
type: 'registry:ui',
dependencies: ['@headlessui/react', 'motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/headless/disclosure/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/disclosure.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n Disclosure as DisclosurePrimitive,\n DisclosureButton as DisclosureButtonPrimitive,\n DisclosurePanel as DisclosurePanelPrimitive,\n type DisclosureProps as DisclosurePrimitiveProps,\n type DisclosureButtonProps as DisclosureButtonPrimitiveProps,\n type DisclosurePanelProps as DisclosurePanelPrimitiveProps,\n} from '@headlessui/react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype DisclosureContextType = {\n isOpen: boolean;\n};\n\nconst DisclosureContext = React.createContext<\n DisclosureContextType | undefined\n>(undefined);\n\nconst useDisclosure = (): DisclosureContextType => {\n const context = React.useContext(DisclosureContext);\n if (!context) {\n throw new Error('useDisclosure must be used within a Disclosure');\n }\n return context;\n};\n\ntype DisclosureProps<TTag extends React.ElementType = 'div'> =\n DisclosurePrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction Disclosure<TTag extends React.ElementType = 'div'>({\n children,\n ...props\n}: DisclosureProps<TTag>) {\n return (\n <DisclosurePrimitive data-slot=\"disclosure\" {...props}>\n {(bag) => (\n <DisclosureContext.Provider value={{ isOpen: bag.open }}>\n {typeof children === 'function' ? children(bag) : children}\n </DisclosureContext.Provider>\n )}\n </DisclosurePrimitive>\n );\n}\n\ntype DisclosureButtonProps<TTag extends React.ElementType = 'button'> =\n DisclosureButtonPrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction DisclosureButton<TTag extends React.ElementType = 'button'>(\n props: DisclosureButtonProps<TTag>,\n) {\n return <DisclosureButtonPrimitive data-slot=\"disclosure-button\" {...props} />;\n}\n\ntype DisclosurePanelProps<TTag extends React.ElementType = typeof motion.div> =\n Pick<DisclosurePanelPrimitiveProps<TTag>, 'static' | 'unmount' | 'children'> &\n Omit<HTMLMotionProps<'div'>, 'children'> & {\n transition?: Transition;\n as?: TTag;\n };\n\nfunction DisclosurePanel<TTag extends React.ElementType = typeof motion.div>(\n props: DisclosurePanelProps<TTag>,\n) {\n const {\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n as = motion.div,\n unmount,\n ...rest\n } = props;\n const { isOpen } = useDisclosure();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <DisclosurePanelPrimitive\n static\n as={as as React.ElementType}\n unmount={unmount}\n >\n {(bag) => (\n <motion.div\n key=\"disclosure-panel\"\n data-slot=\"disclosure-panel\"\n initial={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n animate={{ height: 'auto', opacity: 1, '--mask-stop': '100%' }}\n exit={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n transition={transition}\n style={{\n maskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n WebkitMaskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n }}\n className={cn('overflow-hidden', className)}\n {...rest}\n >\n {typeof children === 'function' ? children(bag) : children}\n </motion.div>\n )}\n </DisclosurePanelPrimitive>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Disclosure,\n DisclosureButton,\n DisclosurePanel,\n useDisclosure,\n type DisclosureProps,\n type DisclosureButtonProps,\n type DisclosurePanelProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/disclosure/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-disclosure';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-disclosure',
},
'headless-popover': {
name: 'headless-popover',
description:
'Popovers are perfect for floating panels with arbitrary content like navigation menus, mobile menus and flyout menus.',
type: 'registry:ui',
dependencies: ['@headlessui/react', 'motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/headless/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/popover.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n Popover as PopoverPrimitive,\n PopoverButton as PopoverButtonPrimitive,\n PopoverPanel as PopoverPanelPrimitive,\n PopoverBackdrop as PopoverBackdropPrimitive,\n PopoverGroup as PopoverGroupPrimitive,\n type PopoverProps as PopoverPrimitiveProps,\n type PopoverButtonProps as PopoverButtonPrimitiveProps,\n type PopoverPanelProps as PopoverPanelPrimitiveProps,\n type PopoverBackdropProps as PopoverBackdropPrimitiveProps,\n type PopoverGroupProps as PopoverGroupPrimitiveProps,\n} from '@headlessui/react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype PopoverContextType = {\n isOpen: boolean;\n};\n\nconst PopoverContext = React.createContext<PopoverContextType | undefined>(\n undefined,\n);\n\nconst usePopover = (): PopoverContextType => {\n const context = React.useContext(PopoverContext);\n if (!context) {\n throw new Error('usePopover must be used within a Popover');\n }\n return context;\n};\n\ntype PopoverProps<TTag extends React.ElementType = 'div'> =\n PopoverPrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction Popover<TTag extends React.ElementType = 'div'>({\n children,\n ...props\n}: PopoverProps<TTag>) {\n return (\n <PopoverPrimitive data-slot=\"popover\" {...props}>\n {(bag) => (\n <PopoverContext.Provider value={{ isOpen: bag.open }}>\n {typeof children === 'function' ? children(bag) : children}\n </PopoverContext.Provider>\n )}\n </PopoverPrimitive>\n );\n}\n\ntype PopoverButtonProps<TTag extends React.ElementType = 'button'> =\n PopoverButtonPrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction PopoverButton<TTag extends React.ElementType = 'button'>(\n props: PopoverButtonProps<TTag>,\n) {\n return <PopoverButtonPrimitive data-slot=\"popover-button\" {...props} />;\n}\n\ntype PopoverBackdropProps<TTag extends React.ElementType = 'div'> =\n PopoverBackdropPrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction PopoverBackdrop<TTag extends React.ElementType = 'div'>(\n props: PopoverBackdropProps<TTag>,\n) {\n return <PopoverBackdropPrimitive data-slot=\"popover-backdrop\" {...props} />;\n}\n\ntype PopoverGroupProps<TTag extends React.ElementType = 'div'> =\n PopoverGroupPrimitiveProps<TTag> & {\n as?: TTag;\n };\n\nfunction PopoverGroup<TTag extends React.ElementType = 'div'>(\n props: PopoverGroupProps<TTag>,\n) {\n return <PopoverGroupPrimitive data-slot=\"popover-group\" {...props} />;\n}\n\ntype PopoverPanelProps<TTag extends React.ElementType = 'div'> = Omit<\n PopoverPanelPrimitiveProps<TTag>,\n 'transition'\n> &\n Omit<HTMLMotionProps<'div'>, 'children'> & {\n transition?: Transition;\n as?: TTag;\n };\n\nfunction PopoverPanel(props: PopoverPanelProps) {\n const {\n children,\n className,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n anchor = { to: 'bottom', gap: 4 },\n as = motion.div,\n ...rest\n } = props;\n const { isOpen } = usePopover();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <PopoverPanelPrimitive\n key=\"popover-panel\"\n data-slot=\"popover-panel\"\n static\n as={as}\n initial={{ opacity: 0, scale: 0.5, transition }}\n animate={{ opacity: 1, scale: 1, transition }}\n exit={{ opacity: 0, scale: 0.5, transition }}\n className={cn(\n 'w-72 rounded-lg border bg-popover p-4 text-popover-foreground shadow-md outline-none z-50',\n className,\n )}\n anchor={anchor}\n {...rest}\n >\n {children}\n </PopoverPanelPrimitive>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Popover,\n PopoverButton,\n PopoverPanel,\n PopoverBackdrop,\n PopoverGroup,\n type PopoverProps,\n type PopoverButtonProps,\n type PopoverPanelProps,\n type PopoverBackdropProps,\n type PopoverGroupProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-popover';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-popover',
},
'headless-switch': {
name: 'headless-switch',
description:
'Switches are a pleasant interface for toggling a value between two states, and offer the same semantics and keyboard navigation as native checkbox elements.',
type: 'registry:ui',
dependencies: ['@headlessui/react', 'motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/headless/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/switch.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n Switch as SwitchPrimitive,\n type SwitchProps as SwitchPrimitiveProps,\n} from '@headlessui/react';\nimport { motion, type HTMLMotionProps } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype SwitchProps<TTag extends React.ElementType = typeof motion.button> =\n SwitchPrimitiveProps<TTag> &\n Omit<HTMLMotionProps<'button'>, 'children'> & {\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n thumbIcon?: React.ReactNode;\n onCheckedChange?: (checked: boolean) => void;\n as?: TTag;\n };\n\nfunction Switch({\n className,\n leftIcon,\n rightIcon,\n thumbIcon,\n onChange,\n as = motion.button,\n ...props\n}: SwitchProps) {\n const [isChecked, setIsChecked] = React.useState(\n props.checked ?? props.defaultChecked ?? false,\n );\n const [isTapped, setIsTapped] = React.useState(false);\n\n React.useEffect(() => {\n setIsChecked(props.checked ?? props.defaultChecked ?? false);\n }, [props.checked, props.defaultChecked]);\n\n const handleChange = React.useCallback(\n (checked: boolean) => {\n setIsChecked(checked);\n onChange?.(checked);\n },\n [onChange],\n );\n\n return (\n <SwitchPrimitive\n data-slot=\"switch\"\n checked={isChecked}\n onChange={handleChange}\n className={cn(\n 'relative flex p-[3px] h-6 w-10 shrink-0 cursor-pointer items-center rounded-full transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[checked]:bg-primary bg-input data-[checked]:justify-end justify-start',\n className,\n )}\n as={as}\n whileTap=\"tap\"\n initial={false}\n onTapStart={() => setIsTapped(true)}\n onTapCancel={() => setIsTapped(false)}\n onTap={() => setIsTapped(false)}\n {...props}\n >\n {leftIcon && (\n <motion.div\n data-slot=\"switch-left-icon\"\n animate={\n isChecked ? { scale: 1, opacity: 1 } : { scale: 0, opacity: 0 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute [&_svg]:size-3 left-1 top-1/2 -translate-y-1/2 dark:text-neutral-500 text-neutral-400\"\n >\n {typeof leftIcon !== 'string' ? leftIcon : null}\n </motion.div>\n )}\n\n {rightIcon && (\n <motion.div\n data-slot=\"switch-right-icon\"\n animate={\n isChecked ? { scale: 0, opacity: 0 } : { scale: 1, opacity: 1 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute [&_svg]:size-3 right-1 top-1/2 -translate-y-1/2 dark:text-neutral-400 text-neutral-500\"\n >\n {typeof rightIcon !== 'string' ? rightIcon : null}\n </motion.div>\n )}\n\n <motion.span\n data-slot=\"switch-thumb\"\n whileTap=\"tab\"\n className={cn(\n 'relative z-[1] [&_svg]:size-3 flex items-center justify-center rounded-full bg-background shadow-lg ring-0 dark:text-neutral-400 text-neutral-500',\n )}\n layout\n transition={{ type: 'spring', stiffness: 300, damping: 25 }}\n style={{\n width: 18,\n height: 18,\n }}\n animate={\n isTapped\n ? { width: 21, transition: { duration: 0.1 } }\n : { width: 18, transition: { duration: 0.1 } }\n }\n >\n {thumbIcon && typeof thumbIcon !== 'string' ? thumbIcon : null}\n </motion.span>\n </SwitchPrimitive>\n );\n}\n\nexport { Switch, type SwitchProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-switch';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-switch',
},
'headless-tabs': {
name: 'headless-tabs',
description:
'Easily create accessible, fully customizable tab interfaces, with robust focus management and keyboard navigation support.',
type: 'registry:ui',
dependencies: ['motion', '@headlessui/react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/headless/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/headless/tabs.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Transition } from 'motion/react';\nimport {\n TabGroup as TabGroupPrimitive,\n TabList as TabListPrimitive,\n Tab as TabPrimitive,\n TabPanels as TabPanelsPrimitive,\n TabPanel as TabPanelPrimitive,\n type TabGroupProps as TabGroupPrimitiveProps,\n type TabListProps as TabListPrimitiveProps,\n type TabProps as TabPrimitiveProps,\n type TabPanelsProps as TabPanelsPrimitiveProps,\n type TabPanelProps as TabPanelPrimitiveProps,\n} from '@headlessui/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype TabGroupProps<TTag extends React.ElementType = 'div'> =\n TabGroupPrimitiveProps<TTag> & {\n className?: string;\n as?: TTag;\n };\n\nfunction TabGroup<TTag extends React.ElementType = 'div'>({\n className,\n ...props\n}: TabGroupProps<TTag>) {\n return (\n <TabGroupPrimitive\n data-slot=\"tab-group\"\n className={cn('flex flex-col gap-2', className)}\n {...props}\n />\n );\n}\n\ntype TabListProps<TTag extends React.ElementType = 'div'> =\n TabListPrimitiveProps<TTag> & {\n as?: TTag;\n className?: string;\n activeClassName?: string;\n transition?: Transition;\n };\n\nfunction TabList<TTag extends React.ElementType = 'div'>({\n children,\n className,\n activeClassName,\n transition = {\n type: 'spring',\n stiffness: 200,\n damping: 25,\n },\n ...props\n}: TabListProps<TTag>) {\n return (\n <TabListPrimitive\n data-slot=\"tab-list\"\n className={cn(\n 'bg-muted text-muted-foreground inline-flex h-10 w-fit items-center justify-center rounded-lg p-[4px]',\n className,\n )}\n {...props}\n >\n {(bag) => (\n <MotionHighlight\n controlledItems\n className={cn('rounded-sm bg-background shadow-sm', activeClassName)}\n value={bag.selectedIndex.toString()}\n transition={transition}\n >\n {typeof children === 'function' ? children(bag) : children}\n </MotionHighlight>\n )}\n </TabListPrimitive>\n );\n}\n\ntype TabProps<TTag extends React.ElementType = 'button'> = Omit<\n TabPrimitiveProps<TTag>,\n 'children'\n> &\n Required<Pick<TabPrimitiveProps<TTag>, 'children'>> & {\n index: number;\n className?: string;\n as?: TTag;\n };\n\nfunction Tab<TTag extends React.ElementType = 'button'>(props: TabProps<TTag>) {\n const { children, className, index, as = 'button', ...rest } = props;\n\n return (\n <MotionHighlightItem value={index.toString()} className=\"size-full\">\n <TabPrimitive\n data-slot=\"tabs-trigger\"\n className={cn(\n 'inline-flex cursor-pointer items-center size-full justify-center whitespace-nowrap rounded-sm px-2 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-selected:text-foreground z-[1]',\n className,\n )}\n as={as as React.ElementType}\n {...rest}\n >\n {children}\n </TabPrimitive>\n </MotionHighlightItem>\n );\n}\n\ntype TabPanelProps<TTag extends React.ElementType = typeof motion.div> = Omit<\n TabPanelPrimitiveProps<TTag>,\n 'transition'\n> & {\n children: React.ReactNode;\n className?: string;\n as?: TTag;\n transition?: Transition;\n};\n\nfunction TabPanel<TTag extends React.ElementType = typeof motion.div>(\n props: TabPanelProps<TTag>,\n) {\n const {\n className,\n as = motion.div,\n transition = {\n duration: 0.5,\n ease: 'easeInOut',\n },\n ...rest\n } = props;\n\n return (\n <TabPanelPrimitive\n data-slot=\"tabs-content\"\n className={cn('flex-1 outline-none', className)}\n layout\n initial={{ opacity: 0, y: -10, filter: 'blur(4px)' }}\n animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}\n exit={{ opacity: 0, y: 10, filter: 'blur(4px)' }}\n transition={transition}\n as={as as React.ElementType}\n {...rest}\n />\n );\n}\n\ntype TabPanelsProps<TTag extends React.ElementType = typeof motion.div> = Omit<\n TabPanelsPrimitiveProps<TTag>,\n 'transition'\n> & {\n className?: string;\n as?: TTag;\n transition?: Transition;\n};\n\nfunction TabPanels<TTag extends React.ElementType = typeof motion.div>(\n props: TabPanelsProps<TTag>,\n) {\n const {\n children,\n className,\n as = motion.div,\n transition = { type: 'spring', stiffness: 200, damping: 25 },\n ...rest\n } = props;\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n\n const [height, setHeight] = React.useState(0);\n\n React.useEffect(() => {\n if (!containerRef.current) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n const newHeight = entries[0]?.contentRect.height ?? 0;\n requestAnimationFrame(() => {\n setHeight(newHeight);\n });\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [children]);\n\n React.useLayoutEffect(() => {\n if (containerRef.current) {\n const initialHeight = containerRef.current.getBoundingClientRect().height;\n setHeight(initialHeight);\n }\n }, [children]);\n\n return (\n <TabPanelsPrimitive\n data-slot=\"tabs-contents\"\n layout\n animate={{ height: height }}\n transition={transition}\n as={as as React.ElementType}\n className={className}\n {...rest}\n >\n <div ref={containerRef}>{children}</div>\n </TabPanelsPrimitive>\n );\n}\n\nexport {\n TabGroup,\n TabList,\n Tab,\n TabPanel,\n TabPanels,\n type TabGroupProps,\n type TabListProps,\n type TabProps,\n type TabPanelProps,\n type TabPanelsProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/headless/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'headless-tabs';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/headless-tabs',
},
'activity-icon': {
name: 'activity-icon',
description: 'Activity icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/activity/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/activity.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ActivityProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [0, 1],\n pathLength: [0, 1],\n pathOffset: [1, 0],\n transition: {\n duration: 0.8,\n ease: 'easeInOut',\n opacity: { duration: 0.01 },\n },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-return': {\n path: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [0, 1, 1, 1],\n pathLength: [0, 1, 0, 1],\n pathOffset: [1, 0, 0.01, 0],\n transition: {\n duration: 2.5,\n ease: 'easeInOut',\n opacity: { duration: 0.01 },\n },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [0, 1, 1, 1, 1],\n pathLength: [0, 1, 0, 1, 0],\n pathOffset: [1, 0, 0.01, 0, 0.999],\n transition: {\n duration: 3,\n ease: 'easeInOut',\n repeat: Infinity,\n repeatType: 'loop',\n opacity: { duration: 0.01 },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ActivityProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2\"\n variants={variants.path}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Activity(props: ActivityProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Activity,\n Activity as ActivityIcon,\n type ActivityProps,\n type ActivityProps as ActivityIconProps,\n};",
},
],
keywords: [
'activity',
'pulse',
'action',
'motion',
'healthcare',
'fitness',
'medical',
'health',
'siesmic',
'magnitude',
'intensive care',
'hospital',
'emergency',
'ambulance',
'vitals',
'vital signs',
'heart rate monitor',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/activity/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'activity-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/activity-icon',
},
'alarm-clock-icon': {
name: 'alarm-clock-icon',
description: 'Alarm clock icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/alarm-clock/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/alarm-clock.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype AlarmClockProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [\n 0,\n '2%',\n '-2%',\n '2%',\n '-2%',\n '2%',\n '-2%',\n '2%',\n '-2%',\n '2%',\n '-2%',\n 0,\n ],\n y: [\n 0,\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n '-5%',\n 0,\n ],\n transition: {\n ease: 'easeInOut',\n duration: 0.6,\n },\n },\n },\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 5, -5, 5, -5, 5, -5, 5, -5, 5, -5, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 5, -5, 5, -5, 5, -5, 5, -5, 5, -5, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: ['2%', '-2%', '2%', '-2%', '2%', '-2%', '2%', '-2%', '2%', '-2%'],\n y: '-5%',\n transition: {\n duration: 0.5,\n x: {\n repeat: Infinity,\n repeatType: 'loop',\n },\n y: {\n duration: 0.2,\n },\n },\n },\n },\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 10, -10, 10, -10, 10, -10, 10, -10, 10, -10, 0],\n transition: { duration: 0.5, repeat: Infinity, repeatType: 'loop' },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 10, -10, 10, -10, 10, -10, 10, -10, 10, -10, 0],\n transition: { duration: 0.5, repeat: Infinity, repeatType: 'loop' },\n },\n },\n path1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 0],\n transition: { duration: 0.5, repeat: Infinity, repeatType: 'loop' },\n },\n },\n path2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 0],\n transition: { duration: 0.5, repeat: Infinity, repeatType: 'loop' },\n },\n },\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: AlarmClockProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n variants={variants.group}\n initial=\"initial\"\n animate={controls}\n {...props}\n >\n <motion.circle\n cx={12}\n cy={13}\n r={8}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={9}\n x2={12}\n y2={13}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={14}\n y1={15}\n x2={12}\n y2={13}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M5 3 2 6\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m22 6-3-3\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M6.38 18.7 4 21\"\n variants={variants.path3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M17.64 18.67 20 21\"\n variants={variants.path4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction AlarmClock(props: AlarmClockProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n AlarmClock,\n AlarmClock as AlarmClockIcon,\n type AlarmClockProps,\n type AlarmClockProps as AlarmClockIconProps,\n};",
},
],
keywords: ['morning'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/alarm-clock/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'alarm-clock-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/alarm-clock-icon',
},
'arrow-down-icon': {
name: 'arrow-down-icon',
description: 'Arrow down icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/arrow-down/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/arrow-down.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ArrowDownProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n y: '25%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '25%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group: {},\n path1: {\n initial: {\n d: 'M12 5v14',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M12 5v10',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'm19 12-7 7-7-7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'm19 8.5-7 7-7-7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group: {},\n path1: {\n initial: {\n d: 'M12 5v14',\n },\n animate: {\n d: ['M12 5v14', 'M12 5v10', 'M12 5v14'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'm19 12-7 7-7-7',\n },\n animate: {\n d: ['m19 12-7 7-7-7', 'm19 8.5-7 7-7-7', 'm19 12-7 7-7-7'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '150%', '-150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n y: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ArrowDownProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M12 5v14\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m19 12-7 7-7-7\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction ArrowDown(props: ArrowDownProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ArrowDown,\n ArrowDown as ArrowDownIcon,\n type ArrowDownProps,\n type ArrowDownProps as ArrowDownIconProps,\n};",
},
],
keywords: ['arrow', 'down', 'backward', 'direction', 'south'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/arrow-down/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'arrow-down-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/arrow-down-icon',
},
'arrow-left-icon': {
name: 'arrow-left-icon',
description: 'Arrow left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/arrow-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/arrow-left.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ArrowLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n x: '-25%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '-25%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group: {},\n path1: {\n initial: {\n d: 'M19 12H5',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M19 12H10',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'm12 19-7-7 7-7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'm15.5 19-7-7 7-7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group: {},\n path1: {\n initial: {\n d: 'M19 12H5',\n },\n animate: {\n d: ['M19 12H5', 'M19 12H10', 'M19 12H5'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'm12 19-7-7 7-7',\n },\n animate: {\n d: ['m12 19-7-7 7-7', 'm15.5 19-7-7 7-7', 'm12 19-7-7 7-7'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '-150%', '150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n x: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ArrowLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M19 12H5\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m12 19-7-7 7-7\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction ArrowLeft(props: ArrowLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ArrowLeft,\n ArrowLeft as ArrowLeftIcon,\n type ArrowLeftProps,\n type ArrowLeftProps as ArrowLeftIconProps,\n};",
},
],
keywords: ['arrow', 'left', 'back', 'previous', 'direction', 'west', '<-'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/arrow-left/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'arrow-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/arrow-left-icon',
},
'arrow-right-icon': {
name: 'arrow-right-icon',
description: 'Arrow right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/arrow-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/arrow-right.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ArrowRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n x: '25%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '25%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group: {},\n path1: {\n initial: {\n d: 'M5 12h14',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M5 12h10',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'm12 5 7 7-7 7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'm8 5 7 7-7 7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group: {},\n path1: {\n initial: {\n d: 'M5 12h14',\n },\n animate: {\n d: ['M5 12h14', 'M5 12h10', 'M5 12h14'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'm12 5 7 7-7 7',\n },\n animate: {\n d: ['m12 5 7 7-7 7', 'm8 5 7 7-7 7', 'm12 5 7 7-7 7'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '150%', '-150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n x: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ArrowRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M5 12h14\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m12 5 7 7-7 7\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction ArrowRight(props: ArrowRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ArrowRight,\n ArrowRight as ArrowRightIcon,\n type ArrowRightProps,\n type ArrowRightProps as ArrowRightIconProps,\n};",
},
],
keywords: ['arrow', 'right', 'forward', 'next', 'direction', 'east', '->'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/arrow-right/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'arrow-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/arrow-right-icon',
},
'arrow-up-icon': {
name: 'arrow-up-icon',
description: 'Arrow up icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/arrow-up/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/arrow-up.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ArrowUpProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n y: '-25%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '-25%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group: {},\n path1: {\n initial: {\n d: 'M12 19V5',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M12 19V10',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'm5 12 7-7 7 7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'm5 16 7-7 7 7',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group: {},\n path1: {\n initial: {\n d: 'M12 19V5',\n },\n animate: {\n d: ['M12 19V5', 'M12 19V10', 'M12 19V5'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'm5 12 7-7 7 7',\n },\n animate: {\n d: ['m5 12 7-7 7 7', 'm5 16 7-7 7 7', 'm5 12 7-7 7 7'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '-150%', '150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n y: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ArrowUpProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M12 19V5\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m5 12 7-7 7 7\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction ArrowUp(props: ArrowUpProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ArrowUp,\n ArrowUp as ArrowUpIcon,\n type ArrowUpProps,\n type ArrowUpProps as ArrowUpIconProps,\n};",
},
],
keywords: ['arrow', 'up', 'forward', 'direction', 'north'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/arrow-up/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'arrow-up-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/arrow-up-icon',
},
'audio-lines-icon': {
name: 'audio-lines-icon',
description: 'Audio Lines icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/audio-lines/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/audio-lines.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype AudioLinesProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n line1: {\n initial: {\n y1: 10,\n y2: 13,\n },\n animate: {\n y1: [10, 5, 8, 6, 10],\n y2: [13, 18, 15, 17, 13],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n line2: {\n initial: {\n y1: 6,\n y2: 17,\n },\n animate: {\n y1: [6, 2, 10, 6],\n y2: [17, 22, 13, 17],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n line3: {\n initial: {\n y1: 3,\n y2: 21,\n },\n animate: {\n y1: [3, 6, 3, 8, 3],\n y2: [21, 17, 21, 15, 21],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n line4: {\n initial: {\n y1: 8,\n y2: 15,\n },\n animate: {\n y1: [8, 4, 7, 2, 8],\n y2: [15, 19, 16, 22, 15],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n line5: {\n initial: {\n y1: 5,\n y2: 18,\n },\n animate: {\n y1: [5, 10, 4, 8, 5],\n y2: [18, 13, 19, 15, 18],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n line6: {\n initial: {\n y1: 10,\n y2: 13,\n },\n animate: {\n y1: [10, 8, 5, 10],\n y2: [13, 15, 18, 13],\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: AudioLinesProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.line\n x1={2}\n y1={10}\n x2={2}\n y2={13}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={6}\n y1={6}\n x2={6}\n y2={17}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={10}\n y1={3}\n x2={10}\n y2={21}\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={14}\n y1={8}\n x2={14}\n y2={15}\n variants={variants.line4}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={18}\n y1={5}\n x2={18}\n y2={18}\n variants={variants.line5}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={22}\n y1={10}\n x2={22}\n y2={13}\n variants={variants.line6}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction AudioLines(props: AudioLinesProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n AudioLines,\n AudioLines as AudioLinesIcon,\n type AudioLinesProps,\n type AudioLinesProps as AudioLinesIconProps,\n};',
},
],
keywords: [
'graphic equaliser',
'sound',
'noise',
'listen',
'hearing',
'hertz',
'frequency',
'wavelength',
'vibrate',
'sine',
'synthesizer',
'synthesiser',
'levels',
'track',
'music',
'playback',
'radio',
'broadcast',
'airwaves',
'voice',
'vocals',
'singer',
'song',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/audio-lines/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'audio-lines-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/audio-lines-icon',
},
'axe-icon': {
name: 'axe-icon',
description: 'Axe icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/axe/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/axe.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype AxeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 25, -5, 0],\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: AxeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m14 12-8.381 8.38a1 1 0 0 1-3.001-3L11 9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 15.5a.5.5 0 0 0 .5.5A6.5 6.5 0 0 0 22 9.5a.5.5 0 0 0-.5-.5h-1.672a2 2 0 0 1-1.414-.586l-5.062-5.062a1.205 1.205 0 0 0-1.704 0L9.352 5.648a1.205 1.205 0 0 0 0 1.704l5.062 5.062A2 2 0 0 1 15 13.828z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Axe(props: AxeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Axe,\n Axe as AxeIcon,\n type AxeProps,\n type AxeProps as AxeIconProps,\n};',
},
],
keywords: [
'hatchet',
'weapon',
'chop',
'sharp',
'equipment',
'fireman',
'firefighter',
'brigade',
'lumberjack',
'woodcutter',
'logger',
'forestry',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/axe/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'axe-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/axe-icon',
},
'battery-charging-icon': {
name: 'battery-charging-icon',
description: 'Battery Charging icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/battery-charging/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/battery-charging.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BatteryChargingProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path3: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: [1, 0.5, 1, 0.5, 1],\n scale: [1, 0.9, 1, 0.9, 1],\n transition: {\n duration: 1.8,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BatteryChargingProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M15 7h1a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2h-2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6 7H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h1"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m11 7-3 5h4l-3 5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={22}\n x2={22}\n y1={11}\n y2={13}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BatteryCharging(props: BatteryChargingProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BatteryCharging,\n BatteryCharging as BatteryChargingIcon,\n type BatteryChargingProps,\n type BatteryChargingProps as BatteryChargingIconProps,\n};',
},
],
keywords: ['power', 'electricity', 'energy', 'accumulator', 'charge'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/battery-charging/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'battery-charging-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/battery-charging-icon',
},
'battery-full-icon': {
name: 'battery-full-icon',
description: 'Battery Full icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/battery-full/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/battery-full.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype BatteryFullProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {},\n line2: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0,\n },\n scale: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0,\n },\n },\n },\n },\n line3: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.3,\n },\n scale: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.3,\n },\n },\n },\n },\n line4: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.6,\n },\n scale: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.6,\n },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BatteryFullProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.rect\n width={16}\n height={10}\n x={2}\n y={7}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={22}\n x2={22}\n y1={11}\n y2={13}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={6}\n x2={6}\n y1={11}\n y2={13}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={10}\n x2={10}\n y1={11}\n y2={13}\n variants={variants.line3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={14}\n x2={14}\n y1={11}\n y2={13}\n variants={variants.line4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BatteryFull(props: BatteryFullProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BatteryFull,\n BatteryFull as BatteryFullIcon,\n type BatteryFullProps,\n type BatteryFullProps as BatteryFullIconProps,\n};",
},
],
keywords: ['power', 'electricity', 'energy', 'accumulator', 'charge'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/battery-full/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'battery-full-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/battery-full-icon',
},
'battery-low-icon': {
name: 'battery-low-icon',
description: 'Battery Low icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/battery-low/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/battery-low.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BatteryLowProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {},\n line2: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0,\n },\n scale: {\n duration: 0.3,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0,\n },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BatteryLowProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={16}\n height={10}\n x={2}\n y={7}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={22}\n x2={22}\n y1={11}\n y2={13}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={6}\n x2={6}\n y1={11}\n y2={13}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BatteryLow(props: BatteryLowProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BatteryLow,\n BatteryLow as BatteryLowIcon,\n type BatteryLowProps,\n type BatteryLowProps as BatteryLowIconProps,\n};',
},
],
keywords: ['power', 'electricity', 'energy', 'accumulator', 'charge'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/battery-low/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'battery-low-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/battery-low-icon',
},
'battery-medium-icon': {
name: 'battery-medium-icon',
description: 'Battery Medium icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/battery-medium/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/battery-medium.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype BatteryMediumProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {},\n line2: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0,\n },\n scale: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0,\n },\n },\n },\n },\n line3: {\n initial: {\n opacity: 1,\n scale: 1,\n },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.3,\n },\n scale: {\n duration: 0.3,\n ease: 'easeInOut',\n repeat: 1,\n repeatType: 'reverse',\n repeatDelay: 0.3,\n },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BatteryMediumProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.rect\n width={16}\n height={10}\n x={2}\n y={7}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={22}\n x2={22}\n y1={11}\n y2={13}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={6}\n x2={6}\n y1={11}\n y2={13}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={10}\n x2={10}\n y1={11}\n y2={13}\n variants={variants.line3}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BatteryMedium(props: BatteryMediumProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BatteryMedium,\n BatteryMedium as BatteryMediumIcon,\n type BatteryMediumProps,\n type BatteryMediumProps as BatteryMediumIconProps,\n};",
},
],
keywords: ['power', 'electricity', 'energy', 'accumulator', 'charge'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/battery-medium/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'battery-medium-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/battery-medium-icon',
},
'bell-icon': {
name: 'bell-icon',
description: 'Bell icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bell/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bell.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BellProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 20, -10, 10, -5, 3, 0],\n transformOrigin: \'top center\',\n transition: { duration: 0.9, ease: \'easeInOut\' },\n },\n },\n path1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -6, 5, -5, 4, -3, 2, 0],\n transition: { duration: 1.1, ease: \'easeInOut\' },\n },\n },\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BellProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M10.268 21a2 2 0 0 0 3.464 0"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Bell(props: BellProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Bell,\n Bell as BellIcon,\n type BellProps,\n type BellProps as BellIconProps,\n};',
},
],
keywords: ['alarm', 'notification', 'sound', 'reminder'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/bell/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bell-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bell-icon',
},
'bell-off-icon': {
name: 'bell-off-icon',
description: 'Bell off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bell-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bell-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BellOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BellOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M10.268 21a2 2 0 0 0 3.464 0"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BellOff(props: BellOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BellOff,\n BellOff as BellOffIcon,\n type BellOffProps,\n type BellOffProps as BellOffIconProps,\n};',
},
],
keywords: ['alarm', 'notification', 'sound', 'reminder'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/bell-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bell-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bell-off-icon',
},
'bell-ring-icon': {
name: 'bell-ring-icon',
description: 'Bell ring icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bell-ring/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bell-ring.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BellRingProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 20, -10, 10, -5, 3, 0],\n transformOrigin: \'top center\',\n transition: { duration: 0.9, ease: \'easeInOut\' },\n },\n },\n path1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -6, 5, -5, 4, -3, 2, 0],\n transition: { duration: 1.1, ease: \'easeInOut\' },\n },\n },\n path2: {\n initial: {\n y: 0,\n scale: 1,\n },\n animate: {\n y: [0, 1, -0.5, 0.5, -0.25, 0],\n scale: [1, 0.8, 0.9, 1, 1],\n\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path3: {\n initial: {\n y: 0,\n scale: 1,\n },\n animate: {\n y: [0, -0.5, 1, -0.5, 0.25, 0],\n scale: [1, 0.8, 0.9, 1, 1],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BellRingProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M10.268 21a2 2 0 0 0 3.464 0"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 8c0-2.3-.8-4.3-2-6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M4 2C2.8 3.7 2 5.7 2 8"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BellRing(props: BellRingProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BellRing,\n BellRing as BellRingIcon,\n type BellRingProps,\n type BellRingProps as BellRingIconProps,\n};',
},
],
keywords: ['alarm', 'notification', 'sound', 'reminder'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/bell-ring/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bell-ring-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bell-ring-icon',
},
'bot-icon': {
name: 'bot-icon',
description: 'Bot icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bot/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bot.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BotProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {},\n rect: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -1.5, 1.5, 0],\n y: [0, 1.5, 1.5, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 1.3,\n },\n },\n },\n path5: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -1.5, 1.5, 0],\n y: [0, 1.5, 1.5, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 1.3,\n },\n },\n },\n } satisfies Record<string, Variants>,\n blink: {\n path1: {},\n rect: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path5: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n } satisfies Record<string, Variants>,\n wink: {\n path1: {},\n rect: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path5: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BotProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12 8V4H8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.rect\n width={16}\n height={12}\n x={4}\n y={8}\n rx={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 14h2"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M20 14h2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 13v2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 13v2"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Bot(props: BotProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Bot,\n Bot as BotIcon,\n type BotProps,\n type BotProps as BotIconProps,\n};',
},
],
keywords: ['robot', 'ai', 'chat', 'assistant'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/bot/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bot-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bot-icon',
},
'bot-message-square-icon': {
name: 'bot-message-square-icon',
description: 'Bot message square icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bot-message-square/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bot-message-square.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BotMessageSquareProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path5: {},\n path6: {},\n } satisfies Record<string, Variants>,\n \'look-at\': {\n group: {},\n path1: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -1.5, 1.5, 0],\n y: [0, 1.5, 1.5, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 1.3,\n },\n },\n },\n path5: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -1.5, 1.5, 0],\n y: [0, 1.5, 1.5, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 1.3,\n },\n },\n },\n path6: {},\n } satisfies Record<string, Variants>,\n blink: {\n group: {},\n path1: {},\n path2: {},\n path3: {},\n path4: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path5: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path6: {},\n } satisfies Record<string, Variants>,\n wink: {\n group: {},\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {\n initial: {\n scaleY: 1,\n },\n animate: {\n scaleY: [1, 0.5, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path6: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BotMessageSquareProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 6V2H8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m8 18-4 4V8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2Z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 12h2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 11v2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 11v2"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M20 12h2"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction BotMessageSquare(props: BotMessageSquareProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BotMessageSquare,\n BotMessageSquare as BotMessageSquareIcon,\n type BotMessageSquareProps,\n type BotMessageSquareProps as BotMessageSquareIconProps,\n};',
},
],
keywords: ['robot', 'ai', 'chat', 'assistant'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/bot-message-square/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bot-message-square-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bot-message-square-icon',
},
'bot-off-icon': {
name: 'bot-off-icon',
description: 'Bot off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/bot-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/bot-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BotOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BotOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M13.67 8H18a2 2 0 0 1 2 2v4.33"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 14h2"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M20 14h2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 22 2 2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8 8H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h12a2 2 0 0 0 1.414-.586"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 13v2"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.67 4H12v2.33"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BotOff(props: BotOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BotOff,\n BotOff as BotOffIcon,\n type BotOffProps,\n type BotOffProps as BotOffIconProps,\n};',
},
],
keywords: ['robot', 'ai', 'chat', 'assistant'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/bot-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'bot-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/bot-off-icon',
},
'brush-icon': {
name: 'brush-icon',
description: 'Brush icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/brush/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/brush.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BrushProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n animate: {\n rotate: [0, -6, 6, 0],\n transformOrigin: \'top right\',\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BrushProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m11 10 3 3"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6.5 21A3.5 3.5 0 1 0 3 17.5a2.62 2.62 0 0 1-.708 1.792A1 1 0 0 0 3 21z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.969 17.031 21.378 5.624a1 1 0 0 0-3.002-3.002L6.967 14.031"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Brush(props: BrushProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Brush,\n Brush as BrushIcon,\n type BrushProps,\n type BrushProps as BrushIconProps,\n};',
},
],
keywords: [
'clean',
'sweep',
'refactor',
'remove',
'draw',
'paint',
'color',
'artist',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/brush/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'brush-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/brush-icon',
},
'brush-cleaning-icon': {
name: 'brush-cleaning-icon',
description: 'Brush cleaning icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/brush-cleaning/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/brush-cleaning.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype BrushCleaningProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n animate: {\n rotate: [0, -10, 10, 0],\n transformOrigin: \'top center\',\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: BrushCleaningProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m16 22-1-4"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19 13.99a1 1 0 0 0 1-1V12a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v.99a1 1 0 0 0 1 1"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5 14h14l1.973 6.767A1 1 0 0 1 20 22H4a1 1 0 0 1-.973-1.233z"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m8 22 1-4"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction BrushCleaning(props: BrushCleaningProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n BrushCleaning,\n BrushCleaning as BrushCleaningIcon,\n type BrushCleaningProps,\n type BrushCleaningProps as BrushCleaningIconProps,\n};',
},
],
keywords: [
'cleaning',
'utensil',
'housekeeping',
'tool',
'sweeping',
'scrubbing',
'hygiene',
'maintenance',
'household',
'cleaner',
'chores',
'equipment',
'sanitation',
'bristles',
'handle',
'home care',
'sanitize',
'purify',
'wash',
'disinfect',
'sterilize',
'scrub',
'polish',
'decontaminate',
'wipe',
'spotless',
'remove',
'empty',
'erase',
'purge',
'eliminate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/brush-cleaning/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'brush-cleaning-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/brush-cleaning-icon',
},
'cherry-icon': {
name: 'cherry-icon',
description: 'Cherry icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/cherry/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/cherry.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CherryProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, -12, 7, -4, 0],\n transformOrigin: \'top center\',\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CherryProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M2 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M7 14c3.22-2.91 4.29-8.75 5-12 1.66 2.38 4.94 9 5 12"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 9c-4.29 0-7.14-2.33-10-7 5.71 0 10 4.67 10 7Z"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Cherry(props: CherryProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Cherry,\n Cherry as CherryIcon,\n type CherryProps,\n type CherryProps as CherryIconProps,\n};',
},
],
keywords: ['fruit', 'food'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/cherry/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cherry-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cherry-icon',
},
'chevron-down-icon': {
name: 'chevron-down-icon',
description: 'Chevron down icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-down/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-down.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ChevronDownProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: 4,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronDownProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="m6 9 6 6 6-6"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronDown(props: ChevronDownProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronDown,\n ChevronDown as ChevronDownIcon,\n type ChevronDownProps,\n type ChevronDownProps as ChevronDownIconProps,\n};',
},
],
keywords: ['backwards', 'reverse', 'slow', 'dropdown'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/chevron-down/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-down-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-down-icon',
},
'chevron-left-icon': {
name: 'chevron-left-icon',
description: 'Chevron left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-left.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ChevronLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n x: -4,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -4, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="m15 18-6-6 6-6"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronLeft(props: ChevronLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronLeft,\n ChevronLeft as ChevronLeftIcon,\n type ChevronLeftProps,\n type ChevronLeftProps as ChevronLeftIconProps,\n};',
},
],
keywords: ['back', 'previous', 'less than', 'fewer', 'menu', '<'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/chevron-left/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-left-icon',
},
'chevron-left-right-icon': {
name: 'chevron-left-right-icon',
description: 'Chevron left right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-left-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-left-right.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ChevronLeftRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n x: -3,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n x: 3,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -3, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 3, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronLeftRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"m9 7-5 5 5 5\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m15 7 5 5-5 5\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronLeftRight(props: ChevronLeftRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronLeftRight,\n ChevronLeftRight as ChevronLeftRightIcon,\n type ChevronLeftRightProps,\n type ChevronLeftRightProps as ChevronLeftRightIconProps,\n};",
},
],
keywords: ['expand', 'horizontal', 'unfold', '<>'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/chevron-left-right/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-left-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-left-right-icon',
},
'chevron-right-icon': {
name: 'chevron-right-icon',
description: 'Chevron right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-right.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ChevronRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n x: 4,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 4, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="m9 18 6-6-6-6"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronRight(props: ChevronRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronRight,\n ChevronRight as ChevronRightIcon,\n type ChevronRightProps,\n type ChevronRightProps as ChevronRightIconProps,\n};',
},
],
keywords: [
'forward',
'next',
'more than',
'greater',
'menu',
'code',
'coding',
'command line',
'terminal',
'prompt',
'shell',
'>',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/chevron-right/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-right-icon',
},
'chevron-up-icon': {
name: 'chevron-up-icon',
description: 'Chevron up icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-up/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-up.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ChevronUpProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: -4,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, -4, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronUpProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="m18 15-6-6-6 6"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronUp(props: ChevronUpProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronUp,\n ChevronUp as ChevronUpIcon,\n type ChevronUpProps,\n type ChevronUpProps as ChevronUpIconProps,\n};',
},
],
keywords: [
'caret',
'keyboard',
'mac',
'control',
'ctrl',
'superscript',
'exponential',
'power',
'ahead',
'fast',
'^',
'dropdown',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/chevron-up/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-up-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-up-icon',
},
'chevron-up-down-icon': {
name: 'chevron-up-down-icon',
description: 'Chevron up down icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/chevron-up-down/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/chevron-up-down.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ChevronUpDownProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 3,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -3,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 3, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, -3, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ChevronUpDownProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"m7 15 5 5 5-5\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"m7 9 5-5 5 5\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ChevronUpDown(props: ChevronUpDownProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ChevronUpDown,\n ChevronUpDown as ChevronUpDownIcon,\n type ChevronUpDownProps,\n type ChevronUpDownProps as ChevronUpDownIconProps,\n};",
},
],
keywords: ['expand', 'vertical', 'unfold'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/chevron-up-down/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'chevron-up-down-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/chevron-up-down-icon',
},
'circle-plus-icon': {
name: 'circle-plus-icon',
description: 'Circle plus icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/circle-plus/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/circle-plus.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CirclePlusProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CirclePlusProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={12}\n x2={16}\n y2={12}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={16}\n x2={12}\n y2={8}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction CirclePlus(props: CirclePlusProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n CirclePlus,\n CirclePlus as CirclePlusIcon,\n type CirclePlusProps,\n type CirclePlusProps as CirclePlusIconProps,\n};',
},
],
keywords: [
'circle',
'plus',
'add',
'sum',
'addition',
'math',
'maths',
'new',
'+',
'increase',
'positive',
'calculate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/circle-plus/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'circle-plus-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/circle-plus-icon',
},
'circle-x-icon': {
name: 'circle-x-icon',
description: 'Circle x icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/circle-x/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/circle-x.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CircleXProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CircleXProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={9}\n y1={15}\n x2={15}\n y2={9}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={9}\n y1={9}\n x2={15}\n y2={15}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction CircleX(props: CircleXProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n CircleX,\n CircleX as CircleXIcon,\n type CircleXProps,\n type CircleXProps as CircleXIconProps,\n};',
},
],
keywords: [
'x',
'circle',
'cross',
'delete',
'close',
'cancel',
'remove',
'clear',
'math',
'multiply',
'multiplication',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/circle-x/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'circle-x-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/circle-x-icon',
},
'clock-icon': {
name: 'clock-icon',
description: 'Clock icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ClockProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ClockProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={12}\n x2={16}\n y2={14}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock(props: ClockProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock,\n Clock as ClockIcon,\n type ClockProps,\n type ClockProps as ClockIconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-icon',
},
'clock-1-icon': {
name: 'clock-1-icon',
description: 'Clock 1 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-1/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-1.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock1Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock1Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={14.5}\n y1={8}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock1(props: Clock1Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock1,\n Clock1 as Clock1Icon,\n type Clock1Props,\n type Clock1Props as Clock1IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-1/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-1-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-1-icon',
},
'clock-10-icon': {
name: 'clock-10-icon',
description: 'Clock 10 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-10/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-10.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock10Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock10Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={10}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock10(props: Clock10Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock10,\n Clock10 as Clock10Icon,\n type Clock10Props,\n type Clock10Props as Clock10IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-10/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-10-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-10-icon',
},
'clock-11-icon': {
name: 'clock-11-icon',
description: 'Clock 11 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-11/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-11.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock11Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock11Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={9.5}\n y1={8}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock11(props: Clock11Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock11,\n Clock11 as Clock11Icon,\n type Clock11Props,\n type Clock11Props as Clock11IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-11/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-11-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-11-icon',
},
'clock-12-icon': {
name: 'clock-12-icon',
description: 'Clock 12 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-12/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-12.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock12Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock12Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={7.5}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock12(props: Clock12Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock12,\n Clock12 as Clock12Icon,\n type Clock12Props,\n type Clock12Props as Clock12IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-12/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-12-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-12-icon',
},
'clock-2-icon': {
name: 'clock-2-icon',
description: 'Clock 2 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-2/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-2.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock2Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock2Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={16}\n y1={10}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock2(props: Clock2Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock2,\n Clock2 as Clock2Icon,\n type Clock2Props,\n type Clock2Props as Clock2IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-2/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-2-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-2-icon',
},
'clock-3-icon': {
name: 'clock-3-icon',
description: 'Clock 3 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-3/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-3.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock3Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock3Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={16.5}\n y1={12}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock3(props: Clock3Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock3,\n Clock3 as Clock3Icon,\n type Clock3Props,\n type Clock3Props as Clock3IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-3/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-3-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-3-icon',
},
'clock-4-icon': {
name: 'clock-4-icon',
description: 'Clock 4 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-4/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-4.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock4Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock4Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={12}\n x2={16}\n y2={14}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock4(props: Clock4Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock4,\n Clock4 as Clock4Icon,\n type Clock4Props,\n type Clock4Props as Clock4IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-4/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-4-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-4-icon',
},
'clock-5-icon': {
name: 'clock-5-icon',
description: 'Clock 5 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-5/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-5.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock5Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock5Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={14.5}\n y1={16}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock5(props: Clock5Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock5,\n Clock5 as Clock5Icon,\n type Clock5Props,\n type Clock5Props as Clock5IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-5/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-5-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-5-icon',
},
'clock-6-icon': {
name: 'clock-6-icon',
description: 'Clock 6 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-6/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-6.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock6Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top left',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock6Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={16.5}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock6(props: Clock6Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock6,\n Clock6 as Clock6Icon,\n type Clock6Props,\n type Clock6Props as Clock6IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-6/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-6-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-6-icon',
},
'clock-7-icon': {
name: 'clock-7-icon',
description: 'Clock 7 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-7/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-7.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock7Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock7Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={9.5}\n y1={16}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock7(props: Clock7Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock7,\n Clock7 as Clock7Icon,\n type Clock7Props,\n type Clock7Props as Clock7IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-7/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-7-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-7-icon',
},
'clock-8-icon': {
name: 'clock-8-icon',
description: 'Clock 8 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-8/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-8.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock8Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock8Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={14}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock8(props: Clock8Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock8,\n Clock8 as Clock8Icon,\n type Clock8Props,\n type Clock8Props as Clock8IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-8/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-8-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-8-icon',
},
'clock-9-icon': {
name: 'clock-9-icon',
description: 'Clock 9 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/clock-9/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/clock-9.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype Clock9Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'top right',\n rotate: [0, 20, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 360,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Clock9Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={7.5}\n y1={12}\n x2={12}\n y2={12}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={6}\n x2={12}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Clock9(props: Clock9Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Clock9,\n Clock9 as Clock9Icon,\n type Clock9Props,\n type Clock9Props as Clock9IconProps,\n};",
},
],
keywords: ['clock', 'time', 'watch', 'alarm', 'timer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/clock-9/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'clock-9-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/clock-9-icon',
},
'cloud-download-icon': {
name: 'cloud-download-icon',
description: 'Cloud download icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/cloud-download/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/cloud-download.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CloudDownloadProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CloudDownloadProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 13v8l-4-4"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m12 21 4-4"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M4.393 15.269A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.436 8.284"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction CloudDownload(props: CloudDownloadProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n CloudDownload,\n CloudDownload as CloudDownloadIcon,\n type CloudDownloadProps,\n type CloudDownloadProps as CloudDownloadIconProps,\n};',
},
],
keywords: ['import'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/cloud-download/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cloud-download-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cloud-download-icon',
},
'cloud-upload-icon': {
name: 'cloud-upload-icon',
description: 'Cloud upload icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/cloud-upload/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/cloud-upload.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CloudUploadProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: -2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, -2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CloudUploadProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 13v8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m8 17 4-4 4 4"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction CloudUpload(props: CloudUploadProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n CloudUpload,\n CloudUpload as CloudUploadIcon,\n type CloudUploadProps,\n type CloudUploadProps as CloudUploadIconProps,\n};',
},
],
keywords: ['file'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/cloud-upload/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cloud-upload-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cloud-upload-icon',
},
'cog-icon': {
name: 'cog-icon',
description: 'Cog icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/cog/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/cog.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CogProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 90, 180],\n transition: {\n duration: 1.25,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n path9: {},\n path10: {},\n path11: {},\n path12: {},\n path13: {},\n path14: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 90, 180, 270, 360],\n transition: {\n duration: 2.5,\n ease: \'easeInOut\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n path9: {},\n path10: {},\n path11: {},\n path12: {},\n path13: {},\n path14: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: 360,\n transition: {\n duration: 2,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n path9: {},\n path10: {},\n path11: {},\n path12: {},\n path13: {},\n path14: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CogProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 2v2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 22v-2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m17 20.66-1-1.73"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M11 10.27 7 3.34"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m20.66 17-1.73-1"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m3.34 7 1.73 1"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 12h8"\n variants={variants.path9}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 12h2"\n variants={variants.path10}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m20.66 7-1.73 1"\n variants={variants.path11}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m3.34 17 1.73-1"\n variants={variants.path12}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m17 3.34-1 1.73"\n variants={variants.path13}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m11 13.73-4 6.93"\n variants={variants.path14}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction Cog(props: CogProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Cog,\n Cog as CogIcon,\n type CogProps,\n type CogProps as CogIconProps,\n};',
},
],
keywords: [
'computing',
'settings',
'cog',
'edit',
'gear',
'preferences',
'controls',
'configuration',
'fixed',
'build',
'construction',
'parts',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/cog/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'cog-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/cog-icon',
},
'compass-icon': {
name: 'compass-icon',
description: 'Compass icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/compass/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/compass.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CompassProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 95, 75],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 95, 75, -20, 0],\n transition: {\n duration: 1.2,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CompassProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="m16.24 7.76-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Compass(props: CompassProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Compass,\n Compass as CompassIcon,\n type CompassProps,\n type CompassProps as CompassIconProps,\n};',
},
],
keywords: [
'direction',
'north',
'south',
'east',
'west',
'safari',
'browser',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/compass/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'compass-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/compass-icon',
},
'copy-icon': {
name: 'copy-icon',
description: 'Copy icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/copy/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/copy.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype CopyProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: -3,\n x: -3,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n path: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: 3,\n x: 3,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n rect: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -3, 0],\n x: [0, -3, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n path: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 3, 0],\n x: [0, 3, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: CopyProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={14}\n height={14}\n x={8}\n y={8}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Copy(props: CopyProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Copy,\n Copy as CopyIcon,\n type CopyProps,\n type CopyProps as CopyIconProps,\n};',
},
],
keywords: ['clone', 'duplicate', 'multiple'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/copy/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'copy-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/copy-icon',
},
'disc-3-icon': {
name: 'disc-3-icon',
description: 'Disc 3 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/disc-3/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/disc-3.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype Disc3Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: { rotate: 0 },\n animate: {\n rotate: 360,\n transition: {\n duration: 1,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n circle1: {},\n circle2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Disc3Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.circle\n cx="12"\n cy="12"\n r="10"\n variants={variants.circle1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6 12c0-1.7.7-3.2 1.8-4.2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx="12"\n cy="12"\n r="2"\n variants={variants.circle2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M18 12c0 1.7-.7 3.2-1.8 4.2"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Disc3(props: Disc3Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Disc3,\n Disc3 as Disc3Icon,\n type Disc3Props,\n type Disc3Props as Disc3IconProps,\n};',
},
],
keywords: [
'album',
'album',
'vinyl',
'record',
'cd',
'dvd',
'format',
'dj',
'spin',
'rotate',
'rpm',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/disc-3/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'disc-3-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/disc-3-icon',
},
'download-icon': {
name: 'download-icon',
description: 'Download icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/download/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/download.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype DownloadProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: DownloadProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 15V3"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m7 10 5 5 5-5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Download(props: DownloadProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Download,\n Download as DownloadIcon,\n type DownloadProps,\n type DownloadProps as DownloadIconProps,\n};',
},
],
keywords: ['import', 'export', 'save'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/download/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'download-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/download-icon',
},
'expand-icon': {
name: 'expand-icon',
description: 'Expand icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/expand/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/expand.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ExpandProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group1: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: 2,\n x: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n group2: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: -2,\n x: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n group3: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: 2,\n x: -2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n group4: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: -2,\n x: -2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group1: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 2, 0],\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n group2: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -2, 0],\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n group3: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 2, 0],\n x: [0, -2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n group4: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -2, 0],\n x: [0, -2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ExpandProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group1} initial="initial" animate={controls}>\n <motion.path\n d="m15 15 6 6"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 16v5h-5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.g variants={variants.group2} initial="initial" animate={controls}>\n <motion.path\n d="m15 9 6-6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 8V3h-5"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.g variants={variants.group3} initial="initial" animate={controls}>\n <motion.path\n d="M3 16v5h5"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m3 21 6-6"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.g variants={variants.group4} initial="initial" animate={controls}>\n <motion.path\n d="M3 8V3h5"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 9 3 3"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction Expand(props: ExpandProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Expand,\n Expand as ExpandIcon,\n type ExpandProps,\n type ExpandProps as ExpandIconProps,\n};',
},
],
keywords: ['scale', 'fullscreen', 'maximize', 'minimize', 'contract'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/expand/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'expand-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/expand-icon',
},
'external-link-icon': {
name: 'external-link-icon',
description: 'External link icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/external-link/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/external-link.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ExternalLinkProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n x: 2,\n y: -2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 2, 0],\n y: [0, -2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ExternalLinkProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M15 3h6v6"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 14 21 3"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ExternalLink(props: ExternalLinkProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ExternalLink,\n ExternalLink as ExternalLinkIcon,\n type ExternalLinkProps,\n type ExternalLinkProps as ExternalLinkIconProps,\n};',
},
],
keywords: ['outbound', 'open', 'share'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/external-link/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'external-link-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/external-link-icon',
},
'fingerprint-icon': {
name: 'fingerprint-icon',
description: 'Fingerprint icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/fingerprint/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/fingerprint.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n pathClassName,\n} from \'@/components/animate-ui/icons/icon\';\nimport { cn } from \'@/lib/utils\';\n\ntype FingerprintProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const variants: Record<string, Variants> = {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.1, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 1.5,\n },\n },\n },\n path: {\n initial: {\n strokeOpacity: 0.2,\n },\n },\n };\n new Array(9).fill(0).forEach((_, i) => {\n variants[`path${i + 1}`] = {\n initial: {\n pathLength: 1,\n },\n animate: {\n pathLength: [1, 0.05, 1],\n transition: {\n pathLength: { duration: 1.5, ease: \'easeInOut\' },\n },\n },\n };\n });\n return variants;\n })() satisfies Record<string, Variants>,\n \'default-2\': (() => {\n const variants: Record<string, Variants> = {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.1, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 1.5,\n },\n },\n },\n path: {\n initial: {\n strokeOpacity: 0,\n },\n },\n };\n new Array(9).fill(0).forEach((_, i) => {\n variants[`path${i + 1}`] = {\n initial: {\n pathLength: 1,\n },\n animate: {\n pathLength: [1, 0.05, 1],\n transition: {\n pathLength: { duration: 1.5, ease: \'easeInOut\' },\n },\n },\n };\n });\n return variants;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, className, ...props }: FingerprintProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n className={cn(pathClassName, className)}\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n stroke="currentColor"\n variants={variants.path}\n initial="initial"\n animate={controls}\n d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4 M14 13.12c0 2.38 0 6.38-1 8.88 M17.29 21.02c.12-.6.43-2.3.5-3.02 M2 12a10 10 0 0 1 18-6 M2 16h.01 M21.8 16c.2-2 .131-5.354 0-6 M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2 M8.65 22c.21-.66.45-1.32.57-2 M9 6.8a6 6 0 0 1 9 5.2v2"\n />\n <motion.path\n d="M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 13.12c0 2.38 0 6.38-1 8.88"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17.29 21.02c.12-.6.43-2.3.5-3.02"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 12a10 10 0 0 1 18-6"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 16h.01"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21.8 16c.2-2 .131-5.354 0-6"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.65 22c.21-.66.45-1.32.57-2"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 6.8a6 6 0 0 1 9 5.2v2"\n variants={variants.path9}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Fingerprint(props: FingerprintProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Fingerprint,\n Fingerprint as FingerprintIcon,\n type FingerprintProps,\n type FingerprintProps as FingerprintIconProps,\n};',
},
],
keywords: ['2fa', 'authentication', 'biometric', 'identity', 'security'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/fingerprint/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'fingerprint-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/fingerprint-icon',
},
'forklift-icon': {
name: 'forklift-icon',
description: 'Forklift icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/forklift/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/forklift.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ForkliftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle1: {},\n circle2: {},\n path1: {},\n path2: {},\n line: {\n initial: {\n y1: 19,\n y2: 19,\n },\n animate: {\n y1: [19, 5, 6],\n y2: [19, 5, 6],\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n circle1: {},\n circle2: {},\n path1: {},\n path2: {},\n line: {\n initial: {\n y1: 19,\n y2: 19,\n },\n animate: {\n y1: [19, 5, 6, 19],\n y2: [19, 5, 6, 19],\n transition: {\n duration: 1.2,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ForkliftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12,12h-7c-1.1,0-2,.9-2,2v5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={13}\n cy={19}\n r={2}\n variants={variants.circle1}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={5}\n cy={19}\n r={2}\n variants={variants.circle2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8,19h3M16,2v17M6,12v-5c0-1.1.9-2,2-2h3l5,5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={22}\n y1={19}\n x2={16}\n y2={19}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Forklift(props: ForkliftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Forklift,\n Forklift as ForkliftIcon,\n type ForkliftProps,\n type ForkliftProps as ForkliftIconProps,\n};',
},
],
keywords: ['vehicle', 'transport', 'logistics'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/forklift/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'forklift-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/forklift-icon',
},
'gauge-icon': {
name: 'gauge-icon',
description: 'Gauge icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/gauge/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/gauge.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype GaugeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: 70,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n animate: {\n transformOrigin: 'bottom left',\n rotate: [0, 70, 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: GaugeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"m12 14 4-4\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M3.34 19a10 10 0 1 1 17.32 0\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Gauge(props: GaugeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Gauge,\n Gauge as GaugeIcon,\n type GaugeProps,\n type GaugeProps as GaugeIconProps,\n};",
},
],
keywords: [
'dashboard',
'dial',
'meter',
'speed',
'pressure',
'measure',
'level',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/gauge/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gauge-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gauge-icon',
},
'gavel-icon': {
name: 'gavel-icon',
description: 'Gavel icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/gavel/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/gavel.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype GavelProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 30, -5, 0],\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: GavelProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m14.5 12.5-8 8a2.119 2.119 0 1 1-3-3l8-8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m16 16 6-6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m8 8 6-6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m9 7 8 8"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m21 11-8-8"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Gavel(props: GavelProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Gavel,\n Gavel as GavelIcon,\n type GavelProps,\n type GavelProps as GavelIconProps,\n};',
},
],
keywords: ['mallet', 'hammer'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/gavel/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gavel-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gavel-icon',
},
'hammer-icon': {
name: 'hammer-icon',
description: 'Hammer icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/hammer/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/hammer.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype HammerProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 30, -5, 0],\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: HammerProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m15 12-8.373 8.373a1 1 0 1 1-3-3L12 9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m18 15 4-4"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m21.5 11.5-1.914-1.914A2 2 0 0 1 19 8.172V7l-2.26-2.26a6 6 0 0 0-4.202-1.756L9 2.96l.92.82A6.18 6.18 0 0 1 12 8.4V10l2 2h1.172a2 2 0 0 1 1.414.586L18.5 14.5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Hammer(props: HammerProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Hammer,\n Hammer as HammerIcon,\n type HammerProps,\n type HammerProps as HammerIconProps,\n};',
},
],
keywords: ['mallet', 'nails', 'diy', 'toolbox', 'build', 'construction'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/hammer/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'hammer-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/hammer-icon',
},
'heart-icon': {
name: 'heart-icon',
description: 'Heart icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/heart/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/heart.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype HeartProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.9, 1.2, 1],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path: {},\n } satisfies Record<string, Variants>,\n fill: {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.9, 1.2, 1],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path: {\n initial: {\n fill: \'currentColor\',\n fillOpacity: 0,\n },\n animate: {\n fillOpacity: 1,\n transition: { delay: 0.2 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: HeartProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Heart(props: HeartProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Heart,\n Heart as HeartIcon,\n type HeartProps,\n type HeartProps as HeartIconProps,\n};',
},
],
keywords: ['like', 'love', 'emotion', 'suit', 'playing', 'cards'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/heart/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'heart-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/heart-icon',
},
'house-wifi-icon': {
name: 'house-wifi-icon',
description: 'House wifi icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/house-wifi/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/house-wifi.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype HouseWifiProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const animation: Record<string, Variants> = {};\n\n for (let i = 1; i <= 3; i++) {\n animation[`path${i}`] = {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n },\n },\n };\n }\n\n return animation;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: HouseWifiProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12 17h.01"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.5 13.866a4 4 0 0 1 5 .01"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M7 10.754a8 8 0 0 1 10 0"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction HouseWifi(props: HouseWifiProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n HouseWifi,\n HouseWifi as HouseWifiIcon,\n type HouseWifiProps,\n type HouseWifiProps as HouseWifiIconProps,\n};',
},
],
keywords: ['home', 'living', 'building', 'wifi', 'connectivity'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/house-wifi/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'house-wifi-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/house-wifi-icon',
},
icon: {
name: 'icon',
description: 'Base component to use animated icons.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/icon/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/icon.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n SVGMotionProps,\n useAnimation,\n type LegacyAnimationControls,\n type Variants,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\nconst staticAnimations = {\n path: {\n initial: { pathLength: 1, opacity: 1 },\n animate: {\n pathLength: [0.05, 1],\n opacity: [0, 1],\n transition: {\n duration: 0.8,\n ease: 'easeInOut',\n opacity: { duration: 0.01 },\n },\n },\n } as Variants,\n 'path-loop': {\n initial: { pathLength: 1, opacity: 1 },\n animate: {\n pathLength: [1, 0.05, 1],\n opacity: [1, 0, 1],\n transition: {\n duration: 1.6,\n ease: 'easeInOut',\n opacity: { duration: 0.01 },\n },\n },\n } as Variants,\n} as const;\n\ntype StaticAnimations = keyof typeof staticAnimations;\ntype TriggerProp<T = string> = boolean | StaticAnimations | T;\n\ninterface AnimateIconContextValue {\n controls: LegacyAnimationControls | undefined;\n animation: StaticAnimations | string;\n loop: boolean;\n loopDelay: number;\n}\n\ninterface DefaultIconProps<T = string> {\n animate?: TriggerProp<T>;\n onAnimateChange?: (\n value: boolean,\n animation: StaticAnimations | string,\n ) => void;\n animateOnHover?: TriggerProp<T>;\n animateOnTap?: TriggerProp<T>;\n animation?: T | StaticAnimations;\n loop?: boolean;\n loopDelay?: number;\n onAnimateStart?: () => void;\n onAnimateEnd?: () => void;\n}\n\ninterface AnimateIconProps<T = string> extends DefaultIconProps<T> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n children: React.ReactElement<any, any>;\n}\n\ninterface IconProps<T>\n extends DefaultIconProps<T>,\n Omit<\n SVGMotionProps<SVGSVGElement>,\n 'animate' | 'onAnimationStart' | 'onAnimationEnd'\n > {\n size?: number;\n}\n\ninterface IconWrapperProps<T> extends IconProps<T> {\n icon: React.ComponentType<IconProps<T>>;\n}\n\nconst AnimateIconContext = React.createContext<AnimateIconContextValue | null>(\n null,\n);\n\nfunction useAnimateIconContext() {\n const context = React.useContext(AnimateIconContext);\n if (!context)\n return {\n controls: undefined,\n animation: 'default',\n loop: false,\n loopDelay: 0,\n };\n return context;\n}\n\nfunction AnimateIcon({\n animate,\n onAnimateChange,\n animateOnHover,\n animateOnTap,\n animation = 'default',\n loop = false,\n loopDelay = 0,\n onAnimateStart,\n onAnimateEnd,\n children,\n}: AnimateIconProps) {\n const controls = useAnimation();\n const [localAnimate, setLocalAnimate] = React.useState(!!animate);\n const currentAnimation = React.useRef(animation);\n\n const startAnimation = React.useCallback(\n (trigger: TriggerProp) => {\n currentAnimation.current =\n typeof trigger === 'string' ? trigger : animation;\n setLocalAnimate(true);\n },\n [animation],\n );\n\n const stopAnimation = React.useCallback(() => {\n setLocalAnimate(false);\n }, []);\n\n React.useEffect(() => {\n currentAnimation.current =\n typeof animate === 'string' ? animate : animation;\n setLocalAnimate(!!animate);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [animate]);\n\n React.useEffect(\n () => onAnimateChange?.(localAnimate, currentAnimation.current),\n [localAnimate, onAnimateChange],\n );\n\n React.useEffect(() => {\n if (localAnimate) onAnimateStart?.();\n controls.start(localAnimate ? 'animate' : 'initial').then(() => {\n if (localAnimate) onAnimateEnd?.();\n });\n }, [localAnimate, controls, onAnimateStart, onAnimateEnd]);\n\n const handleMouseEnter = (e: MouseEvent) => {\n if (animateOnHover) startAnimation(animateOnHover);\n children.props?.onMouseEnter?.(e);\n };\n const handleMouseLeave = (e: MouseEvent) => {\n if (animateOnHover || animateOnTap) stopAnimation();\n children.props?.onMouseLeave?.(e);\n };\n const handlePointerDown = (e: PointerEvent) => {\n if (animateOnTap) startAnimation(animateOnTap);\n children.props?.onPointerDown?.(e);\n };\n const handlePointerUp = (e: PointerEvent) => {\n if (animateOnTap) stopAnimation();\n children.props?.onPointerUp?.(e);\n };\n\n const child = React.Children.only(children);\n const cloned = React.cloneElement(child, {\n onMouseEnter: handleMouseEnter,\n onMouseLeave: handleMouseLeave,\n onPointerDown: handlePointerDown,\n onPointerUp: handlePointerUp,\n });\n\n return (\n <AnimateIconContext.Provider\n value={{\n controls,\n animation: currentAnimation.current,\n loop,\n loopDelay,\n }}\n >\n {cloned}\n </AnimateIconContext.Provider>\n );\n}\n\nconst pathClassName =\n \"[&_[stroke-dasharray='1px_1px']]:![stroke-dasharray:1px_0px]\";\n\nfunction IconWrapper<T extends string>({\n size = 28,\n animation: animationProp,\n animate,\n onAnimateChange,\n animateOnHover = false,\n animateOnTap = false,\n icon: IconComponent,\n loop = false,\n loopDelay = 0,\n onAnimateStart,\n onAnimateEnd,\n className,\n ...props\n}: IconWrapperProps<T>) {\n const context = React.useContext(AnimateIconContext);\n\n if (context) {\n const {\n controls,\n animation: parentAnimation,\n loop: parentLoop,\n loopDelay: parentLoopDelay,\n } = context;\n const animationToUse = animationProp ?? parentAnimation;\n const loopToUse = loop || parentLoop;\n const loopDelayToUse = loopDelay || parentLoopDelay;\n\n return (\n <AnimateIconContext.Provider\n value={{\n controls,\n animation: animationToUse,\n loop: loopToUse,\n loopDelay: loopDelayToUse,\n }}\n >\n <IconComponent\n size={size}\n className={cn(\n className,\n (animationToUse === 'path' || animationToUse === 'path-loop') &&\n pathClassName,\n )}\n {...props}\n />\n </AnimateIconContext.Provider>\n );\n }\n\n if (\n animate !== undefined ||\n onAnimateChange !== undefined ||\n animateOnHover ||\n animateOnTap ||\n animationProp\n ) {\n return (\n <AnimateIcon\n animate={animate}\n onAnimateChange={onAnimateChange}\n animateOnHover={animateOnHover}\n animateOnTap={animateOnTap}\n animation={animationProp}\n loop={loop}\n loopDelay={loopDelay}\n onAnimateStart={onAnimateStart}\n onAnimateEnd={onAnimateEnd}\n >\n <IconComponent\n size={size}\n className={cn(\n className,\n (animationProp === 'path' || animationProp === 'path-loop') &&\n pathClassName,\n )}\n {...props}\n />\n </AnimateIcon>\n );\n }\n\n return (\n <IconComponent\n size={size}\n className={cn(\n className,\n (animationProp === 'path' || animationProp === 'path-loop') &&\n pathClassName,\n )}\n {...props}\n />\n );\n}\n\nfunction getVariants<\n V extends { default: T; [key: string]: T },\n T extends Record<string, Variants>,\n>(animations: V): T {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const { animation: animationType, loop, loopDelay } = useAnimateIconContext();\n\n let result: T;\n\n if (animationType in staticAnimations) {\n const variant = staticAnimations[animationType as StaticAnimations];\n result = {} as T;\n for (const key in animations.default) {\n if (\n (animationType === 'path' || animationType === 'path-loop') &&\n key.includes('group')\n )\n continue;\n result[key] = variant as T[Extract<keyof T, string>];\n }\n } else {\n result = (animations[animationType as keyof V] as T) ?? animations.default;\n }\n\n if (loop) {\n for (const key in result) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const state = result[key] as any;\n const transition = state.animate?.transition;\n if (!transition) continue;\n\n const hasNestedKeys = Object.values(transition).some(\n (v) =>\n typeof v === 'object' &&\n v !== null &&\n ('ease' in v || 'duration' in v || 'times' in v),\n );\n\n if (hasNestedKeys) {\n for (const prop in transition) {\n const subTrans = transition[prop];\n if (typeof subTrans === 'object' && subTrans !== null) {\n transition[prop] = {\n ...subTrans,\n repeat: Infinity,\n repeatType: 'loop',\n repeatDelay: loopDelay,\n };\n }\n }\n } else {\n state.animate.transition = {\n ...transition,\n repeat: Infinity,\n repeatType: 'loop',\n repeatDelay: loopDelay,\n };\n }\n }\n }\n\n return result;\n}\n\nexport {\n pathClassName,\n staticAnimations,\n AnimateIcon,\n IconWrapper,\n useAnimateIconContext,\n getVariants,\n type IconProps,\n type IconWrapperProps,\n type AnimateIconProps,\n type AnimateIconContextValue,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/icon/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/icon',
},
'kanban-icon': {
name: 'kanban-icon',
description: 'Kanban icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/kanban/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/kanban.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype KanbanProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n line1: {\n initial: {\n y2: 19,\n },\n animate: {\n y2: [19, 11, 16, 19],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line2: {\n initial: {\n y2: 11,\n },\n animate: {\n y2: [11, 16, 19, 11],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line3: {\n initial: {\n y2: 16,\n },\n animate: {\n y2: [16, 19, 11, 16],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: KanbanProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.line\n x1={18}\n y1={5}\n x2={18}\n y2={19}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={5}\n x2={12}\n y2={11}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={6}\n y1={5}\n x2={6}\n y2={16}\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Kanban(props: KanbanProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Kanban,\n Kanban as KanbanIcon,\n type KanbanProps,\n type KanbanProps as KanbanIconProps,\n};',
},
],
keywords: [
'projects',
'manage',
'overview',
'board',
'tickets',
'issues',
'roadmap',
'plan',
'intentions',
'productivity',
'work',
'agile',
'code',
'coding',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/kanban/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'kanban-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/kanban-icon',
},
'layers-icon': {
name: 'layers-icon',
description: 'Layers icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/layers/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/layers.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LayersProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: 5,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n path2: {},\n path3: {\n initial: {\n y: 0,\n },\n animate: {\n y: -5,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 5, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n path2: {},\n path3: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, -5, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LayersProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Layers(props: LayersProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Layers,\n Layers as LayersIcon,\n type LayersProps,\n type LayersProps as LayersIconProps,\n};',
},
],
keywords: [
'stack',
'pile',
'pages',
'sheets',
'paperwork',
'copies',
'copy',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/layers/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'layers-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/layers-icon',
},
'layers-2-icon': {
name: 'layers-2-icon',
description: 'Layers 2 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/layers-2/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/layers-2.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype Layers2Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: 4,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: -4,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, -4, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Layers2Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M13 13.74a2 2 0 0 1-2 0L2.5 8.87a1 1 0 0 1 0-1.74L11 2.26a2 2 0 0 1 2 0l8.5 4.87a1 1 0 0 1 0 1.74z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m20 14.285 1.5.845a1 1 0 0 1 0 1.74L13 21.74a2 2 0 0 1-2 0l-8.5-4.87a1 1 0 0 1 0-1.74l1.5-.845"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Layers2(props: Layers2Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Layers2,\n Layers2 as Layers2Icon,\n type Layers2Props,\n type Layers2Props as Layers2IconProps,\n};',
},
],
keywords: [
'stack',
'pile',
'pages',
'sheets',
'paperwork',
'copies',
'copy',
'duplicate',
'double',
'shortcuts',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/layers-2/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'layers-2-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/layers-2-icon',
},
'layout-dashboard-icon': {
name: 'layout-dashboard-icon',
description: 'Layout dashboard icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/layout-dashboard/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/layout-dashboard.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype LayoutDashboardProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect1: {\n initial: {\n height: 9,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n height: 5,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n rect2: {\n initial: {\n height: 5,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n height: 9,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n rect3: {\n initial: {\n height: 9,\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n height: 5,\n y: 4,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n rect4: {\n initial: {\n height: 5,\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n height: 9,\n y: -4,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n rect1: {\n initial: {\n height: 9,\n },\n animate: {\n height: [9, 5, 9],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n rect2: {\n initial: {\n height: 5,\n },\n animate: {\n height: [5, 9, 5],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n rect3: {\n initial: {\n height: 9,\n y: 0,\n },\n animate: {\n height: [9, 5, 9],\n y: [0, 4, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n rect4: {\n initial: {\n height: 5,\n y: 0,\n },\n animate: {\n height: [5, 9, 5],\n y: [0, -4, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LayoutDashboardProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.rect\n width={7}\n height={9}\n x={3}\n y={3}\n rx={1}\n ry={1}\n variants={variants.rect1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.rect\n width={7}\n height={5}\n x={14}\n y={3}\n rx={1}\n ry={1}\n variants={variants.rect2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.rect\n width={7}\n height={9}\n x={14}\n y={12}\n rx={1}\n ry={1}\n variants={variants.rect3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.rect\n width={7}\n height={5}\n x={3}\n y={16}\n rx={1}\n ry={1}\n variants={variants.rect4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction LayoutDashboard(props: LayoutDashboardProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LayoutDashboard,\n LayoutDashboard as LayoutDashboardIcon,\n type LayoutDashboardProps,\n type LayoutDashboardProps as LayoutDashboardIconProps,\n};",
},
],
keywords: ['masonry', 'brick'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/layout-dashboard/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'layout-dashboard-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/layout-dashboard-icon',
},
'lightbulb-icon': {
name: 'lightbulb-icon',
description: 'Lightbulb icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/lightbulb/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/lightbulb.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LightbulbProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n rotate: 0,\n fill: \'transparent\',\n },\n animate: {\n transformOrigin: \'bottom center\',\n fill: \'currentColor\',\n rotate: [0, -20, 15, -7, 0],\n fillOpacity: [0, 1, 0, 1, 0],\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n rotate: {\n duration: 0.8,\n ease: \'easeInOut\',\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n fillOpacity: {\n duration: 0.3,\n ease: \'easeInOut\',\n times: [0, 0.4, 0.6, 0.8, 1],\n delay: 0.4,\n },\n },\n },\n },\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom center\',\n rotate: [0, 0, 10, -5, 0],\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LightbulbProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 18h6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 22h4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Lightbulb(props: LightbulbProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Lightbulb,\n Lightbulb as LightbulbIcon,\n type LightbulbProps,\n type LightbulbProps as LightbulbIconProps,\n};',
},
],
keywords: ['idea', 'bright', 'lights'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/lightbulb/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'lightbulb-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/lightbulb-icon',
},
'lightbulb-off-icon': {
name: 'lightbulb-off-icon',
description: 'Lightbulb off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/lightbulb-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/lightbulb-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LightbulbOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LightbulbOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M16.8 11.2c.8-.9 1.2-2 1.2-3.2a6 6 0 0 0-9.3-5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6.3 6.3a4.67 4.67 0 0 0 1.2 5.2c.7.7 1.3 1.5 1.5 2.5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 18h6"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 22h4"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction LightbulbOff(props: LightbulbOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LightbulbOff,\n LightbulbOff as LightbulbOffIcon,\n type LightbulbOffProps,\n type LightbulbOffProps as LightbulbOffIconProps,\n};',
},
],
keywords: ['lights'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/lightbulb-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'lightbulb-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/lightbulb-off-icon',
},
'loader-icon': {
name: 'loader-icon',
description: 'Loader icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/loader/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/loader.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LoaderProps = IconProps<keyof typeof animations>;\n\nconst SEGMENT_COUNT = 8;\nconst DURATION = 1.2;\nconst BASE_OPACITY = 0.25;\n\nconst animations = {\n default: (() => {\n const spinner: Record<string, Variants> = {\n group: { initial: {}, animate: {} },\n };\n\n for (let i = 1; i <= SEGMENT_COUNT; i++) {\n const reverseIndex = SEGMENT_COUNT - i;\n const delay = -(reverseIndex * DURATION) / SEGMENT_COUNT;\n\n spinner[`path${i}`] = {\n initial: { opacity: 1 },\n animate: {\n opacity: [1, BASE_OPACITY],\n transition: {\n duration: DURATION,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n delay,\n },\n },\n };\n }\n\n return spinner as Record<string, Variants>;\n })() satisfies Record<string, Variants>,\n spin: {\n group: {\n initial: { rotate: 0 },\n animate: {\n rotate: 360,\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LoaderProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M12 2v4"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m16.2 7.8 2.9-2.9"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M18 12h4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m16.2 16.2 2.9 2.9"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 18v4"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m4.9 19.1 2.9-2.9"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 12h4"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m4.9 4.9 2.9 2.9"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Loader(props: LoaderProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Loader,\n Loader as LoaderIcon,\n type LoaderProps,\n type LoaderProps as LoaderIconProps,\n};',
},
],
keywords: [
'loading',
'wait',
'busy',
'progress',
'throbber',
'spinner',
'spinning',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/loader/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'loader-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/loader-icon',
},
'loader-circle-icon': {
name: 'loader-circle-icon',
description: 'Loader circle icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/loader-circle/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/loader-circle.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LoaderCircleProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: { rotate: 0 },\n animate: {\n rotate: 360,\n transition: {\n duration: 1,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LoaderCircleProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 12a9 9 0 1 1-6.219-8.56"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction LoaderCircle(props: LoaderCircleProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LoaderCircle,\n LoaderCircle as LoaderCircleIcon,\n type LoaderCircleProps,\n type LoaderCircleProps as LoaderCircleIconProps,\n};',
},
],
keywords: [
'loading',
'wait',
'busy',
'progress',
'throbber',
'spinner',
'spinning',
'circle',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/loader-circle/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'loader-circle-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/loader-circle-icon',
},
'loader-pinwheel-icon': {
name: 'loader-pinwheel-icon',
description: 'Loader pinwheel icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/loader-pinwheel/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/loader-pinwheel.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LoaderPinwheelProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: 360,\n transition: {\n duration: 1.5,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n circle: {},\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LoaderPinwheelProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.circle\n cx={12}\n cy={12}\n r={10}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 12a1 1 0 0 1-10 0 1 1 0 0 0-10 0"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M7 20.7a1 1 0 1 1 5-8.7 1 1 0 1 0 5-8.6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M7 3.3a1 1 0 1 1 5 8.6 1 1 0 1 0 5 8.6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction LoaderPinwheel(props: LoaderPinwheelProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LoaderPinwheel,\n LoaderPinwheel as LoaderPinwheelIcon,\n type LoaderPinwheelProps,\n type LoaderPinwheelProps as LoaderPinwheelIconProps,\n};',
},
],
keywords: [
'loading',
'wait',
'busy',
'progress',
'throbber',
'spinner',
'spinning',
'beach ball',
'frozen',
'freeze',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/loader-pinwheel/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'loader-pinwheel-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/loader-pinwheel-icon',
},
'log-in-icon': {
name: 'log-in-icon',
description: 'Log in icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/log-in/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/log-in.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LogInProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n x: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LogInProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m10 17 5-5-5-5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 12H3"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction LogIn(props: LogInProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LogIn,\n LogIn as LogInIcon,\n type LogInProps,\n type LogInProps as LogInIconProps,\n};',
},
],
keywords: ['sign in', 'arrow', 'enter', 'auth'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/log-in/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'log-in-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/log-in-icon',
},
'log-out-icon': {
name: 'log-out-icon',
description: 'Log out icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/log-out/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/log-out.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype LogOutProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n x: 2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: LogOutProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m16 17 5-5-5-5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 12H9"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction LogOut(props: LogOutProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n LogOut,\n LogOut as LogOutIcon,\n type LogOutProps,\n type LogOutProps as LogOutIconProps,\n};',
},
],
keywords: ['sign out', 'arrow', 'exit', 'auth'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/log-out/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'log-out-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/log-out-icon',
},
'map-pin-icon': {
name: 'map-pin-icon',
description: 'Map pin icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/map-pin/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/map-pin.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MapPinProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n rotate: 0,\n x: 0,\n y: 0,\n transformOrigin: 'bottom center',\n },\n animate: {\n scale: [1, 0.75, 1, 1],\n rotate: [0, 30, -15, 0],\n x: [0, 0, 0, 0],\n y: [0, -6, 0, 0],\n transformOrigin: 'bottom center',\n transition: { ease: 'easeInOut', duration: 1 },\n },\n },\n circle: {},\n path: {},\n } satisfies Record<string, Variants>,\n wiggle: {\n group: {\n initial: {\n rotate: 0,\n transformOrigin: 'bottom center',\n },\n animate: {\n rotate: [0, 12, -10, 0],\n transformOrigin: 'bottom center',\n transition: { ease: 'easeInOut', duration: 1 },\n },\n },\n circle: {},\n path: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n transform: 'rotate3d(0, 1, 0, 0deg)',\n perspective: 600,\n },\n animate: {\n transform: 'rotate3d(0, 1, 0, 360deg)',\n perspective: 600,\n transition: { ease: 'easeInOut', duration: 0.7 },\n },\n },\n circle: {},\n path: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MapPinProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.circle\n cx={12}\n cy={10}\n r={3}\n variants={variants.circle}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0\"\n variants={variants.path}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MapPin(props: MapPinProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MapPin,\n MapPin as MapPinIcon,\n type MapPinProps,\n type MapPinProps as MapPinIconProps,\n};",
},
],
keywords: ['map', 'pin', 'location', 'waypoint', 'marker', 'drop'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/map-pin/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'map-pin-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/map-pin-icon',
},
'map-pin-off-icon': {
name: 'map-pin-off-icon',
description: 'Map pin off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/map-pin-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/map-pin-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MapPinOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MapPinOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M12.75 7.09a3 3 0 0 1 2.16 2.16"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17.072 17.072c-1.634 2.17-3.527 3.912-4.471 4.727a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 1.432-4.568"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.475 2.818A8 8 0 0 1 20 10c0 1.183-.31 2.377-.81 3.533"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.13 9.13a3 3 0 0 0 3.74 3.74"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction MapPinOff(props: MapPinOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MapPinOff,\n MapPinOff as MapPinOffIcon,\n type MapPinOffProps,\n type MapPinOffProps as MapPinOffIconProps,\n};',
},
],
keywords: ['location', 'waypoint', 'marker', 'remove'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/map-pin-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'map-pin-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/map-pin-off-icon',
},
'maximize-icon': {
name: 'maximize-icon',
description: 'Maximize icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/maximize/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/maximize.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MaximizeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n x: -2,\n y: -2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -2,\n x: 2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 2,\n x: -2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 2,\n x: 2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -2, 0],\n y: [0, -2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -2, 0],\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 2, 0],\n x: [0, -2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 2, 0],\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MaximizeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"M8 3H5a2 2 0 0 0-2 2v3\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M21 8V5a2 2 0 0 0-2-2h-3\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M3 16v3a2 2 0 0 0 2 2h3\"\n variants={variants.path3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M16 21h3a2 2 0 0 0 2-2v-3\"\n variants={variants.path4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Maximize(props: MaximizeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Maximize,\n Maximize as MaximizeIcon,\n type MaximizeProps,\n type MaximizeProps as MaximizeIconProps,\n};",
},
],
keywords: ['fullscreen', 'expand', 'dashed'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/maximize/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'maximize-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/maximize-icon',
},
'menu-icon': {
name: 'menu-icon',
description: 'Menu icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/menu/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/menu.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MenuProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n line1: {\n initial: {\n rotate: 0,\n x: 0,\n y: 0,\n },\n animate: {\n rotate: -45,\n x: -2.35,\n y: 0.35,\n transformOrigin: \'top right\',\n transition: {\n type: \'spring\',\n stiffness: 200,\n damping: 20,\n },\n },\n },\n line2: {\n initial: {\n opacity: 1,\n },\n animate: {\n opacity: 0,\n transition: {\n ease: \'easeInOut\',\n duration: 0.2,\n },\n },\n },\n line3: {\n initial: {\n rotate: 0,\n x: 0,\n y: 0,\n },\n animate: {\n rotate: 45,\n x: -2.35,\n y: -0.35,\n transformOrigin: \'bottom right\',\n transition: {\n type: \'spring\',\n stiffness: 200,\n damping: 20,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MenuProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.line\n x1={4}\n y1={6}\n x2={20}\n y2={6}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={4}\n y1={12}\n x2={20}\n y2={12}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={4}\n y1={18}\n x2={20}\n y2={18}\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Menu(props: MenuProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Menu,\n Menu as MenuIcon,\n type MenuProps,\n type MenuProps as MenuIconProps,\n};',
},
],
keywords: ['bars', 'navigation', 'hamburger', 'options'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/menu/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'menu-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/menu-icon',
},
'message-circle-icon': {
name: 'message-circle-icon',
description: 'Message circle icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction MessageCircle(props: MessageCircleProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircle,\n MessageCircle as MessageCircleIcon,\n type MessageCircleProps,\n type MessageCircleProps as MessageCircleIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/message-circle/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-icon',
},
'message-circle-code-icon': {
name: 'message-circle-code-icon',
description: 'Message circle code icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-code/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-code.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleCodeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -1.5, 0.75, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1.5, -0.75, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleCodeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 9.5 8 12l2 2.5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m14 9.5 2 2.5-2 2.5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleCode(props: MessageCircleCodeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleCode,\n MessageCircleCode as MessageCircleCodeIcon,\n type MessageCircleCodeProps,\n type MessageCircleCodeProps as MessageCircleCodeIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'code review',
'coding',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-code/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-code-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-code-icon',
},
'message-circle-dashed-icon': {
name: 'message-circle-dashed-icon',
description: 'Message circle dashed icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-dashed/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-dashed.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleDashedProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n } satisfies Record<string, Variants>,\n draw: {\n group: {},\n ...(() => {\n const paths: Record<string, Variants> = {};\n\n for (let i = 1; i <= 8; i++) {\n paths[`path${i}`] = {\n initial: { opacity: 0, scale: 0 },\n animate: {\n opacity: [0, 1],\n scale: [0, 1],\n transition: {\n delay: i * 0.2,\n duration: 0.4,\n },\n },\n };\n }\n\n return paths;\n })(),\n },\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleDashedProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M13.5 3.1c-.5 0-1-.1-1.5-.1s-1 .1-1.5.1"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19.3 6.8a10.45 10.45 0 0 0-2.1-2.1"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M20.9 13.5c.1-.5.1-1 .1-1.5s-.1-1-.1-1.5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17.2 19.3a10.45 10.45 0 0 0 2.1-2.1"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10.5 20.9c.5.1 1 .1 1.5.1s1-.1 1.5-.1"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3.5 17.5 2 22l4.5-1.5"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3.1 10.5c0 .5-.1 1-.1 1.5s.1 1 .1 1.5"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6.8 4.7a10.45 10.45 0 0 0-2.1 2.1"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleDashed(props: MessageCircleDashedProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleDashed,\n MessageCircleDashed as MessageCircleDashedIcon,\n type MessageCircleDashedProps,\n type MessageCircleDashedProps as MessageCircleDashedIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'draft',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-dashed/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-dashed-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-dashed-icon',
},
'message-circle-heart-icon': {
name: 'message-circle-heart-icon',
description: 'Message circle heart icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-heart/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-heart.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleHeartProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.7, 1.1, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleHeartProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15.8 9.2a2.5 2.5 0 0 0-3.5 0l-.3.4-.35-.3a2.42 2.42 0 1 0-3.2 3.6l3.6 3.5 3.6-3.5c1.2-1.2 1.1-2.7.2-3.7"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleHeart(props: MessageCircleHeartProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleHeart,\n MessageCircleHeart as MessageCircleHeartIcon,\n type MessageCircleHeartProps,\n type MessageCircleHeartProps as MessageCircleHeartIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'positive',
'like',
'love',
'interest',
'valentine',
'dating',
'date',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-heart/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-heart-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-heart-icon',
},
'message-circle-more-icon': {
name: 'message-circle-more-icon',
description: 'Message circle more icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-more/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-more.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleMoreProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path: {},\n line1: {\n initial: {\n y1: 12,\n y2: 12,\n },\n animate: {\n y1: [12, 10.5, 12],\n y2: [12, 13.5, 12],\n transition: { ease: \'easeInOut\', duration: 0.6, delay: 0.2 },\n },\n },\n line2: {\n initial: {\n y1: 12,\n y2: 12,\n },\n animate: {\n y1: [12, 10.5, 12],\n y2: [12, 13.5, 12],\n transition: { ease: \'easeInOut\', duration: 0.6, delay: 0.1 },\n },\n },\n line3: {\n initial: {\n y1: 12,\n y2: 12,\n },\n animate: {\n y1: [12, 10.5, 12],\n y2: [12, 13.5, 12],\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n pulse: {\n group: {},\n path: {},\n line1: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n delay: 0.4,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n line2: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n delay: 0.2,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n line3: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n jump: {\n group: {},\n path: {},\n line1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n delay: 0.4,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n line2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n delay: 0.2,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n line3: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleMoreProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="16"\n y1="12"\n x2="16"\n y2="12"\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="12"\n y1="12"\n x2="12"\n y2="12"\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="8"\n y1="12"\n x2="8"\n y2="12"\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleMore(props: MessageCircleMoreProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleMore,\n MessageCircleMore as MessageCircleMoreIcon,\n type MessageCircleMoreProps,\n type MessageCircleMoreProps as MessageCircleMoreIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'typing',
'writing',
'responding',
'ellipsis',
'etc',
'et cetera',
'...',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-more/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-more-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-more-icon',
},
'message-circle-off-icon': {
name: 'message-circle-off-icon',
description: 'Message circle off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M20.5 14.9A9 9 0 0 0 9.1 3.5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5.6 5.6C3 8.3 2.2 12.5 4 16l-2 6 6-2c3.4 1.8 7.6 1.1 10.3-1.7"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction MessageCircleOff(props: MessageCircleOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleOff,\n MessageCircleOff as MessageCircleOffIcon,\n type MessageCircleOffProps,\n type MessageCircleOffProps as MessageCircleOffIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'clear',
'close',
'delete',
'remove',
'cancel',
'silence',
'mute',
'moderate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-off/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-off-icon',
},
'message-circle-plus-icon': {
name: 'message-circle-plus-icon',
description: 'Message circle plus icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-plus/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-plus.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCirclePlusProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n delay: 0.05,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCirclePlusProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8 12h8"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 8v8"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCirclePlus(props: MessageCirclePlusProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCirclePlus,\n MessageCirclePlus as MessageCirclePlusIcon,\n type MessageCirclePlusProps,\n type MessageCirclePlusProps as MessageCirclePlusIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'add',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-plus/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-plus-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-plus-icon',
},
'message-circle-question-icon': {
name: 'message-circle-question-icon',
description: 'Message circle question icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-question/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-question.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleQuestionProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -0.25, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.7, 1],\n },\n },\n },\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleQuestionProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 17h.01"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleQuestion(props: MessageCircleQuestionProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleQuestion,\n MessageCircleQuestion as MessageCircleQuestionIcon,\n type MessageCircleQuestionProps,\n type MessageCircleQuestionProps as MessageCircleQuestionIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'help',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-question/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-question-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-question-icon',
},
'message-circle-warning-icon': {
name: 'message-circle-warning-icon',
description: 'Message circle warning icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-warning/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-warning.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleWarningProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -0.25, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.7, 1],\n },\n },\n },\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleWarningProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 8v4"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 16h.01"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleWarning(props: MessageCircleWarningProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleWarning,\n MessageCircleWarning as MessageCircleWarningIcon,\n type MessageCircleWarningProps,\n type MessageCircleWarningProps as MessageCircleWarningIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'report',
'abuse',
'offense',
'alert',
'danger',
'caution',
'protected',
'exclamation mark',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-circle-warning/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-warning-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-warning-icon',
},
'message-circle-x-icon': {
name: 'message-circle-x-icon',
description: 'Message circle x icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-circle-x/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-circle-x.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageCircleXProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n delay: 0.05,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageCircleXProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m15 9-6 6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m9 9 6 6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageCircleX(props: MessageCircleXProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageCircleX,\n MessageCircleX as MessageCircleXIcon,\n type MessageCircleXProps,\n type MessageCircleXProps as MessageCircleXIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'clear',
'close',
'delete',
'remove',
'cancel',
'silence',
'mute',
'moderate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/message-circle-x/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-circle-x-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-circle-x-icon',
},
'message-square-icon': {
name: 'message-square-icon',
description: 'Message square icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction MessageSquare(props: MessageSquareProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquare,\n MessageSquare as MessageSquareIcon,\n type MessageSquareProps,\n type MessageSquareProps as MessageSquareIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/message-square/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-icon',
},
'message-square-code-icon': {
name: 'message-square-code-icon',
description: 'Message square code icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-code/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-code.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareCodeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -1.5, 0.75, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1.5, -0.75, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareCodeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 7.5 8 10l2 2.5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m14 7.5 2 2.5-2 2.5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareCode(props: MessageSquareCodeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareCode,\n MessageSquareCode as MessageSquareCodeIcon,\n type MessageSquareCodeProps,\n type MessageSquareCodeProps as MessageSquareCodeIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'code review',
'coding',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-code/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-code-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-code-icon',
},
'message-square-dashed-icon': {
name: 'message-square-dashed-icon',
description: 'Message square dashed icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-dashed/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-dashed.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareDashedProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n path9: {},\n } satisfies Record<string, Variants>,\n draw: {\n group: {},\n ...(() => {\n const paths: Record<string, Variants> = {};\n\n for (let i = 1; i <= 9; i++) {\n paths[`path${i}`] = {\n initial: { opacity: 0, scale: 0 },\n animate: {\n opacity: [0, 1],\n scale: [0, 1],\n transition: {\n delay: i * 0.2,\n duration: 0.4,\n },\n },\n };\n }\n\n return paths;\n })(),\n },\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareDashedProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M5 3a2 2 0 0 0-2 2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 3h1"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 3h1"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19 3a2 2 0 0 1 2 2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 9v1"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 14v1a2 2 0 0 1-2 2"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 17h1"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M10 17H7l-4 4v-7"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 9v1"\n variants={variants.path9}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareDashed(props: MessageSquareDashedProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareDashed,\n MessageSquareDashed as MessageSquareDashedIcon,\n type MessageSquareDashedProps,\n type MessageSquareDashedProps as MessageSquareDashedIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'draft',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-dashed/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-dashed-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-dashed-icon',
},
'message-square-diff-icon': {
name: 'message-square-diff-icon',
description: 'Message square diff icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-diff/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-diff.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareDiffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n delay: 0.05,\n },\n },\n },\n path4: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -1, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.7,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareDiffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m5 19-2 2V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 7v6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 10h6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 17h6"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareDiff(props: MessageSquareDiffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareDiff,\n MessageSquareDiff as MessageSquareDiffIcon,\n type MessageSquareDiffProps,\n type MessageSquareDiffProps as MessageSquareDiffIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'add',
'patch',
'difference',
'plus',
'minus',
'plus-minus',
'math',
'code review',
'coding',
'version control',
'git',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-diff/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-diff-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-diff-icon',
},
'message-square-dot-icon': {
name: 'message-square-dot-icon',
description: 'Message square dot icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-dot/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-dot.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareDotProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path: {},\n circle: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -2, 0],\n y: [0, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareDotProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M11.7 3H5a2 2 0 0 0-2 2v16l4-4h12a2 2 0 0 0 2-2v-2.7"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx="18"\n cy="6"\n r="3"\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareDot(props: MessageSquareDotProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareDot,\n MessageSquareDot as MessageSquareDotIcon,\n type MessageSquareDotProps,\n type MessageSquareDotProps as MessageSquareDotIconProps,\n};',
},
],
keywords: [
'unread',
'unresolved',
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-dot/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-dot-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-dot-icon',
},
'message-square-heart-icon': {
name: 'message-square-heart-icon',
description: 'Message square heart icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-heart/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-heart.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareHeartProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.7, 1.1, 1],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareHeartProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14.8 7.5a1.84 1.84 0 0 0-2.6 0l-.2.3-.3-.3a1.84 1.84 0 1 0-2.4 2.8L12 13l2.7-2.7c.9-.9.8-2.1.1-2.8"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareHeart(props: MessageSquareHeartProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareHeart,\n MessageSquareHeart as MessageSquareHeartIcon,\n type MessageSquareHeartProps,\n type MessageSquareHeartProps as MessageSquareHeartIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'positive',
'like',
'love',
'interest',
'valentine',
'dating',
'date',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-heart/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-heart-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-heart-icon',
},
'message-square-more-icon': {
name: 'message-square-more-icon',
description: 'Message square more icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-more/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-more.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareMoreProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path: {},\n line1: {\n initial: {\n y1: 10,\n y2: 10,\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n animate: {\n y1: [10, 8.5, 10],\n y2: [10, 11.5, 10],\n transition: { ease: \'easeInOut\', duration: 0.6, delay: 0.2 },\n },\n },\n line2: {\n initial: {\n y1: 10,\n y2: 10,\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n animate: {\n y1: [10, 8.5, 10],\n y2: [10, 11.5, 10],\n transition: { ease: \'easeInOut\', duration: 0.6, delay: 0.1 },\n },\n },\n line3: {\n initial: {\n y1: 10,\n y2: 10,\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n animate: {\n y1: [10, 8.5, 10],\n y2: [10, 11.5, 10],\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n pulse: {\n group: {},\n path: {},\n line1: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n delay: 0.4,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n line2: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n delay: 0.2,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n line3: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 1.5, 1],\n transition: {\n duration: 1,\n repeat: Infinity,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n jump: {\n group: {},\n path: {},\n line1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n delay: 0.4,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n line2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n delay: 0.2,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n line3: {\n initial: {\n y: 0,\n },\n animate: {\n y: [-0.75, 0.75],\n transition: {\n duration: 0.8,\n repeat: Infinity,\n repeatType: \'mirror\',\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareMoreProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="16"\n y1="10"\n x2="16"\n y2="10"\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="12"\n y1="10"\n x2="12"\n y2="10"\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1="8"\n y1="10"\n x2="8"\n y2="10"\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareMore(props: MessageSquareMoreProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareMore,\n MessageSquareMore as MessageSquareMoreIcon,\n type MessageSquareMoreProps,\n type MessageSquareMoreProps as MessageSquareMoreIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'typing',
'writing',
'responding',
'ellipsis',
'etc',
'et cetera',
'...',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-more/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-more-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-more-icon',
},
'message-square-off-icon': {
name: 'message-square-off-icon',
description: 'Message square off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 15V5a2 2 0 0 0-2-2H9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3.6 3.6c-.4.3-.6.8-.6 1.4v16l4-4h10"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction MessageSquareOff(props: MessageSquareOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareOff,\n MessageSquareOff as MessageSquareOffIcon,\n type MessageSquareOffProps,\n type MessageSquareOffProps as MessageSquareOffIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'clear',
'close',
'delete',
'remove',
'cancel',
'silence',
'mute',
'moderate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-off/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-off-icon',
},
'message-square-plus-icon': {
name: 'message-square-plus-icon',
description: 'Message square plus icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-plus/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-plus.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquarePlusProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n delay: 0.05,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquarePlusProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 7v6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 10h6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquarePlus(props: MessageSquarePlusProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquarePlus,\n MessageSquarePlus as MessageSquarePlusIcon,\n type MessageSquarePlusProps,\n type MessageSquarePlusProps as MessageSquarePlusIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'add',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-plus/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-plus-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-plus-icon',
},
'message-square-quote-icon': {
name: 'message-square-quote-icon',
description: 'Message square quote icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-quote/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-quote.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareQuoteProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 1.5, 0],\n y: [0, -0.5, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path3: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 1, 0],\n y: [0, -0.5, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareQuoteProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8 12a2 2 0 0 0 2-2V8H8"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 12a2 2 0 0 0 2-2V8h-2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareQuote(props: MessageSquareQuoteProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareQuote,\n MessageSquareQuote as MessageSquareQuoteIcon,\n type MessageSquareQuoteProps,\n type MessageSquareQuoteProps as MessageSquareQuoteIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'blockquote',
'quotation',
'indent',
'reply',
'response',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-quote/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-quote-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-quote-icon',
},
'message-square-share-icon': {
name: 'message-square-share-icon',
description: 'Message square share icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-share/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-share.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareShareProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'arrow-up\': {\n group: {},\n group2: {\n initial: {\n x: 0,\n y: 0,\n transition: { ease: \'easeInOut\', duration: 0.3 },\n },\n animate: {\n x: 2,\n y: -2,\n transition: { ease: \'easeInOut\', duration: 0.3 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'arrow-up-loop\': {\n group: {},\n group2: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 2, 0],\n y: [0, -2, 0],\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareShareProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 12v3a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h7"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.g\n variants={variants.group2}\n initial="initial"\n animate={controls}\n >\n <motion.path\n d="M16 3h5v5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m16 8 5-5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareShare(props: MessageSquareShareProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareShare,\n MessageSquareShare as MessageSquareShareIcon,\n type MessageSquareShareProps,\n type MessageSquareShareProps as MessageSquareShareIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'network',
'forward',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-share/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-share-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-share-icon',
},
'message-square-text-icon': {
name: 'message-square-text-icon',
description: 'Message square text icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-text/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-text.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareTextProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [1, 0, 1],\n pathLength: [1, 0, 1],\n pathOffset: [0, 1, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n opacity: { duration: 0.01 },\n },\n },\n },\n path3: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [1, 0, 1],\n pathLength: [1, 0, 1],\n pathOffset: [0, 1, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n opacity: { duration: 0.01 },\n },\n },\n },\n } satisfies Record<string, Variants>,\n write: {\n group: {},\n path1: {},\n path2: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [0, 1],\n pathLength: [0, 1],\n pathOffset: [1, 0],\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n opacity: { duration: 0.01 },\n },\n },\n },\n path3: {\n initial: {\n opacity: 1,\n pathLength: 1,\n pathOffset: 0,\n },\n animate: {\n opacity: [0, 1],\n pathLength: [0, 1],\n pathOffset: [1, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n opacity: { duration: 0.01 },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareTextProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M13 8H7"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17 12H7"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareText(props: MessageSquareTextProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareText,\n MessageSquareText as MessageSquareTextIcon,\n type MessageSquareTextProps,\n type MessageSquareTextProps as MessageSquareTextIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-text/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-text-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-text-icon',
},
'message-square-warning-icon': {
name: 'message-square-warning-icon',
description: 'Message square warning icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-warning/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-warning.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareWarningProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -0.25, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.7, 1],\n },\n },\n },\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareWarningProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 7v2"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 13h.01"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareWarning(props: MessageSquareWarningProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareWarning,\n MessageSquareWarning as MessageSquareWarningIcon,\n type MessageSquareWarningProps,\n type MessageSquareWarningProps as MessageSquareWarningIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'report',
'abuse',
'offense',
'alert',
'danger',
'caution',
'protected',
'exclamation mark',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/message-square-warning/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-warning-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-warning-icon',
},
'message-square-x-icon': {
name: 'message-square-x-icon',
description: 'Message square x icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/message-square-x/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/message-square-x.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype MessageSquareXProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 8, -8, 2, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.8,\n times: [0, 0.4, 0.6, 0.8, 1],\n },\n },\n },\n path1: {},\n path2: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n },\n },\n },\n path3: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 45, 0],\n transition: {\n ease: \'easeInOut\',\n duration: 0.6,\n delay: 0.05,\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MessageSquareXProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m14.5 7.5-5 5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m9.5 7.5 5 5"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MessageSquareX(props: MessageSquareXProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MessageSquareX,\n MessageSquareX as MessageSquareXIcon,\n type MessageSquareXProps,\n type MessageSquareXProps as MessageSquareXIconProps,\n};',
},
],
keywords: [
'comment',
'chat',
'conversation',
'dialog',
'feedback',
'speech bubble',
'clear',
'close',
'delete',
'remove',
'cancel',
'silence',
'mute',
'moderate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/message-square-x/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'message-square-x-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/message-square-x-icon',
},
'minimize-icon': {
name: 'minimize-icon',
description: 'Minimize icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/minimize/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/minimize.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MinimizeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n x: 2,\n y: 2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 2,\n x: -2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -2,\n x: 2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -2,\n x: -2,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 2, 0],\n y: [0, 2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 2, 0],\n x: [0, -2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -2, 0],\n x: [0, 2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -2, 0],\n x: [0, -2, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MinimizeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"M8 3v3a2 2 0 0 1-2 2H3\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M21 8h-3a2 2 0 0 1-2-2V3\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M3 16h3a2 2 0 0 1 2 2v3\"\n variants={variants.path3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M16 21v-3a2 2 0 0 1 2-2h3\"\n variants={variants.path4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Minimize(props: MinimizeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Minimize,\n Minimize as MinimizeIcon,\n type MinimizeProps,\n type MinimizeProps as MinimizeIconProps,\n};",
},
],
keywords: ['exit fullscreen', 'close', 'shrink'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/minimize/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'minimize-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/minimize-icon',
},
'move-down-icon': {
name: 'move-down-icon',
description: 'Move down icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/move-down/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/move-down.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MoveDownProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group1: {\n initial: {\n y: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n y: '15%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '15%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M12 2V22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M12 2V12',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'M8 18L12 22L16 18',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M8 8L12 12L16 8',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M12 2V22',\n },\n animate: {\n d: ['M12 2V22', 'M12 2V12', 'M12 2V22'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'M8 18L12 22L16 18',\n },\n animate: {\n d: ['M8 18L12 22L16 18', 'M8 8L12 12L16 8', 'M8 18L12 22L16 18'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group1: {},\n group2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '150%', '-150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n y: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MoveDownProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n variants={variants.group1}\n initial=\"initial\"\n animate={controls}\n {...props}\n >\n <motion.g variants={variants.group2} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M12 2V22\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M8 18L12 22L16 18\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MoveDown(props: MoveDownProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MoveDown,\n MoveDown as MoveDownIcon,\n type MoveDownProps,\n type MoveDownProps as MoveDownIconProps,\n};",
},
],
keywords: ['move', 'arrow', 'down', 'direction', 'south', '↓'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/move-down/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'move-down-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/move-down-icon',
},
'move-left-icon': {
name: 'move-left-icon',
description: 'Move left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/move-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/move-left.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MoveLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group1: {\n initial: {\n x: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n x: '-15%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '-15%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M2 12H22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M12 12H22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'M6 8L2 12L6 16',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M15 8L11 12L15 16',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M2 12H22',\n },\n animate: {\n d: ['M2 12H22', 'M12 12H22', 'M2 12H22'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'M6 8L2 12L6 16',\n },\n animate: {\n d: ['M6 8L2 12L6 16', 'M15 8L11 12L15 16', 'M6 8L2 12L6 16'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group1: {},\n group2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '-150%', '150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n x: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MoveLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n variants={variants.group1}\n initial=\"initial\"\n animate={controls}\n {...props}\n >\n <motion.g variants={variants.group2} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M2 12H22\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M6 8L2 12L6 16\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MoveLeft(props: MoveLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MoveLeft,\n MoveLeft as MoveLeftIcon,\n type MoveLeftProps,\n type MoveLeftProps as MoveLeftIconProps,\n};",
},
],
keywords: [
'move',
'arrow',
'left',
'back',
'previous',
'direction',
'east',
'<-',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/move-left/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'move-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/move-left-icon',
},
'move-right-icon': {
name: 'move-right-icon',
description: 'Move right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/move-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/move-right.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MoveRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group1: {\n initial: {\n x: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n x: '15%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '15%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M2 12H22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M2 12H12',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'M18 8L22 12L18 16',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M8 8L12 12L8 16',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M2 12H22',\n },\n animate: {\n d: ['M2 12H22', 'M2 12H12', 'M2 12H22'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'M18 8L22 12L18 16',\n },\n animate: {\n d: ['M18 8L22 12L18 16', 'M8 8L12 12L8 16', 'M18 8L22 12L18 16'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group1: {},\n group2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, '150%', '-150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n x: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MoveRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n variants={variants.group1}\n initial=\"initial\"\n animate={controls}\n {...props}\n >\n <motion.g variants={variants.group2} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M2 12H22\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M18 8L22 12L18 16\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MoveRight(props: MoveRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MoveRight,\n MoveRight as MoveRightIcon,\n type MoveRightProps,\n type MoveRightProps as MoveRightIconProps,\n};",
},
],
keywords: [
'move',
'arrow',
'right',
'forward',
'next',
'direction',
'east',
'->',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/move-right/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'move-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/move-right-icon',
},
'move-up-icon': {
name: 'move-up-icon',
description: 'Move up icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/move-up/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/move-up.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype MoveUpProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group1: {\n initial: {\n y: 0,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n y: '-15%',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n 'default-loop': {\n group1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '-15%', 0],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n group2: {},\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n pointing: {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M12 2V22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M12 12V22',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n path2: {\n initial: {\n d: 'M8 6L12 2L16 6',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n d: 'M8 16L12 12L16 16',\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n 'pointing-loop': {\n group1: {},\n group2: {},\n path1: {\n initial: {\n d: 'M12 2V22',\n },\n animate: {\n d: ['M12 2V22', 'M12 12V22', 'M12 2V22'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n path2: {\n initial: {\n d: 'M8 6L12 2L16 6',\n },\n animate: {\n d: ['M8 6L12 2L16 6', 'M8 16L12 12L16 16', 'M8 6L12 2L16 6'],\n transition: { ease: 'easeInOut', duration: 0.6 },\n },\n },\n } satisfies Record<string, Variants>,\n out: {\n group1: {},\n group2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, '-150%', '150%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 0.8 },\n y: {\n ease: 'easeInOut',\n duration: 0.8,\n times: [0, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: MoveUpProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n variants={variants.group1}\n initial=\"initial\"\n animate={controls}\n {...props}\n >\n <motion.g variants={variants.group2} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M12 2V22\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M8 6L12 2L16 6\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction MoveUp(props: MoveUpProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n MoveUp,\n MoveUp as MoveUpIcon,\n type MoveUpProps,\n type MoveUpProps as MoveUpIconProps,\n};",
},
],
keywords: ['move', 'arrow', 'up', 'direction', 'north', '↑'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/move-up/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'move-up-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/move-up-icon',
},
'paintbrush-icon': {
name: 'paintbrush-icon',
description: 'Paintbrush icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/paintbrush/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/paintbrush.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PaintbrushProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n animate: {\n rotate: [0, -6, 6, 0],\n transformOrigin: \'top right\',\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PaintbrushProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m14.622 17.897-10.68-2.913"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Paintbrush(props: PaintbrushProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Paintbrush,\n Paintbrush as PaintbrushIcon,\n type PaintbrushProps,\n type PaintbrushProps as PaintbrushIconProps,\n};',
},
],
keywords: [
'brush',
'paintbrush',
'design',
'color',
'colour',
'decoration',
'diy',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/paintbrush/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'paintbrush-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/paintbrush-icon',
},
'panel-bottom-icon': {
name: 'panel-bottom-icon',
description: 'Panel bottom icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/panel-bottom/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/panel-bottom.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PanelBottomProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line: {\n initial: { x1: 3, y1: 15, x2: 21, y2: 15 },\n animate: {\n x1: 3,\n y1: 17,\n x2: 21,\n y2: 17,\n transition: { type: \'spring\', damping: 20, stiffness: 200 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PanelBottomProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={3}\n y1={15}\n x2={21}\n y2={15}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction PanelBottom(props: PanelBottomProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n PanelBottom,\n PanelBottom as PanelBottomIcon,\n type PanelBottomProps,\n type PanelBottomProps as PanelBottomIconProps,\n};',
},
],
keywords: ['sidebar', 'panel', 'bottom', 'menu', 'drawer', 'navigation'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/panel-bottom/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'panel-bottom-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/panel-bottom-icon',
},
'panel-left-icon': {
name: 'panel-left-icon',
description: 'Panel left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/panel-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/panel-left.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PanelLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line: {\n initial: { x1: 9, y1: 3, x2: 9, y2: 21 },\n animate: {\n x1: 7,\n y1: 3,\n x2: 7,\n y2: 21,\n transition: { type: \'spring\', damping: 20, stiffness: 200 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PanelLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={9}\n y1={3}\n x2={9}\n y2={21}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction PanelLeft(props: PanelLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n PanelLeft,\n PanelLeft as PanelLeftIcon,\n type PanelLeftProps,\n type PanelLeftProps as PanelLeftIconProps,\n};',
},
],
keywords: ['sidebar', 'panel', 'left', 'menu', 'drawer', 'navigation'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/panel-left/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'panel-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/panel-left-icon',
},
'panel-right-icon': {
name: 'panel-right-icon',
description: 'Panel right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/panel-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/panel-right.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PanelRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line: {\n initial: { x1: 15, y1: 3, x2: 15, y2: 21 },\n animate: {\n x1: 17,\n y1: 3,\n x2: 17,\n y2: 21,\n transition: { type: \'spring\', damping: 20, stiffness: 200 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PanelRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={15}\n y1={3}\n x2={15}\n y2={21}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction PanelRight(props: PanelRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n PanelRight,\n PanelRight as PanelRightIcon,\n type PanelRightProps,\n type PanelRightProps as PanelRightIconProps,\n};',
},
],
keywords: ['sidebar', 'panel', 'right', 'menu', 'drawer', 'navigation'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/panel-right/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'panel-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/panel-right-icon',
},
'panel-top-icon': {
name: 'panel-top-icon',
description: 'Panel top icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/panel-top/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/panel-top.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PanelTopProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line: {\n initial: { x1: 3, y1: 9, x2: 21, y2: 9 },\n animate: {\n x1: 3,\n y1: 7,\n x2: 21,\n y2: 7,\n transition: { type: \'spring\', damping: 20, stiffness: 200 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PanelTopProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={3}\n y1={9}\n x2={21}\n y2={9}\n variants={variants.line}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction PanelTop(props: PanelTopProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n PanelTop,\n PanelTop as PanelTopIcon,\n type PanelTopProps,\n type PanelTopProps as PanelTopIconProps,\n};',
},
],
keywords: ['sidebar', 'panel', 'top', 'menu', 'drawer', 'navigation'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/panel-top/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'panel-top-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/panel-top-icon',
},
'pause-icon': {
name: 'pause-icon',
description: 'Pause icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/pause/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/pause.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype PauseProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect1: {\n initial: {\n x: 0,\n },\n animate: {\n x: 1.5,\n transition: {\n duration: 0.3,\n ease: 'easeInOut',\n },\n },\n },\n rect2: {\n initial: {\n x: 0,\n },\n animate: {\n x: -1.5,\n transition: {\n duration: 0.3,\n ease: 'easeInOut',\n },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n rect1: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 1.5, 0],\n transition: {\n duration: 0.6,\n ease: 'easeInOut',\n },\n },\n },\n rect2: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -1.5, 0],\n transition: {\n duration: 0.6,\n ease: 'easeInOut',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PauseProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.rect\n x={14}\n y={4}\n width={4}\n height={16}\n rx={1}\n variants={variants.rect1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.rect\n x={6}\n y={4}\n width={4}\n height={16}\n rx={1}\n variants={variants.rect2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Pause(props: PauseProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Pause,\n Pause as PauseIcon,\n type PauseProps,\n type PauseProps as PauseIconProps,\n};",
},
],
keywords: ['music', 'stop'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/pause/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pause-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pause-icon',
},
'pickaxe-icon': {
name: 'pickaxe-icon',
description: 'Pickaxe icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/pickaxe/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/pickaxe.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PickaxeProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: [0, 25, -5, 0],\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PickaxeProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M14.531 12.469 6.619 20.38a1 1 0 1 1-3-3l7.912-7.912"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15.686 4.314A12.5 12.5 0 0 0 5.461 2.958 1 1 0 0 0 5.58 4.71a22 22 0 0 1 6.318 3.393"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M17.7 3.7a1 1 0 0 0-1.4 0l-4.6 4.6a1 1 0 0 0 0 1.4l2.6 2.6a1 1 0 0 0 1.4 0l4.6-4.6a1 1 0 0 0 0-1.4z"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19.686 8.314a12.501 12.501 0 0 1 1.356 10.225 1 1 0 0 1-1.751-.119 22 22 0 0 0-3.393-6.319"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Pickaxe(props: PickaxeProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Pickaxe,\n Pickaxe as PickaxeIcon,\n type PickaxeProps,\n type PickaxeProps as PickaxeIconProps,\n};',
},
],
keywords: [
'mining',
'mine',
'land worker',
'extraction',
'labor',
'construction',
'progress',
'advancement',
'crafting',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/pickaxe/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pickaxe-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pickaxe-icon',
},
'pin-icon': {
name: 'pin-icon',
description: 'Pin icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/pin/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/pin.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype PinProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n rotate: 0,\n x: 0,\n y: 0,\n transformOrigin: 'bottom center',\n },\n animate: {\n scale: [1, 0.75, 1, 1],\n rotate: [0, 30, -15, 0],\n x: [0, 0, 0, 0],\n y: [0, -6, 0, 0],\n transformOrigin: 'bottom center',\n transition: { ease: 'easeInOut', duration: 1 },\n },\n },\n line: {},\n path: {},\n } satisfies Record<string, Variants>,\n wiggle: {\n group: {\n initial: {\n rotate: 0,\n transformOrigin: 'bottom center',\n },\n animate: {\n rotate: [0, 15, -10, 0],\n transformOrigin: 'bottom center',\n transition: { ease: 'easeInOut', duration: 1 },\n },\n },\n line: {},\n path: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n transform: 'rotate3d(0, 1, 0, 0deg)',\n perspective: 600,\n },\n animate: {\n transform: 'rotate3d(0, 1, 0, 360deg)',\n perspective: 600,\n transition: { ease: 'easeInOut', duration: 0.7 },\n },\n },\n line: {},\n path: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PinProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.line\n x1={12}\n y1={17.1}\n x2={12}\n y2={22}\n variants={variants.line}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M9,10.8c0,.8-.4,1.5-1.1,1.8l-1.8.9c-.7.3-1.1,1-1.1,1.8v.8c0,.6.4,1,1,1h12c.6,0,1-.4,1-1v-.8c0-.8-.4-1.5-1.1-1.8l-1.8-.9c-.7-.3-1.1-1-1.1-1.8v-3.8c0-.6.4-1,1-1,1.1,0,2-.9,2-2s-.9-2-2-2h-8c-1.1,0-2,.9-2,2s.9,2,2,2,1,.4,1,1v3.8Z\"\n variants={variants.path}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction Pin(props: PinProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Pin,\n Pin as PinIcon,\n type PinProps,\n type PinProps as PinIconProps,\n};",
},
],
keywords: ['pin', 'map', 'location', 'lock', 'fixed', 'anchor'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/pin/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pin-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pin-icon',
},
'pin-off-icon': {
name: 'pin-off-icon',
description: 'Pin off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/pin-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/pin-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype PinOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PinOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M12 17v5"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 9.34V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H7.89"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 9v1.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h11"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction PinOff(props: PinOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n PinOff,\n PinOff as PinOffIcon,\n type PinOffProps,\n type PinOffProps as PinOffIconProps,\n};',
},
],
keywords: ['unpin', 'map', 'unlock', 'unfix', 'unsave', 'remove'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/pin-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'pin-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/pin-off-icon',
},
'play-icon': {
name: 'play-icon',
description: 'Play icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/play/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/play.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype PlayProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n polygon: {\n initial: {\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n x: 3,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n polygon: {\n initial: {\n x: 0,\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n animate: {\n x: [0, 3, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PlayProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.polygon\n points=\"6 3 20 12 6 21 6 3\"\n variants={variants.polygon}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Play(props: PlayProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Play,\n Play as PlayIcon,\n type PlayProps,\n type PlayProps as PlayIconProps,\n};",
},
],
keywords: ['music', 'audio', 'video', 'start', 'run'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/play/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'play-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/play-icon',
},
'plus-icon': {
name: 'plus-icon',
description: 'Plus icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/plus/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/plus.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype PlusProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: 'easeInOut', duration: 0.4, delay: 0.1 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: 'easeInOut', duration: 0.4 },\n },\n },\n } satisfies Record<string, Variants>,\n x: {\n line1: {\n initial: {\n rotate: 0,\n x1: 12,\n y1: 19,\n x2: 12,\n y2: 5,\n transition: { ease: 'easeInOut', duration: 0.3, delay: 0.1 },\n },\n animate: {\n rotate: 45,\n x1: 12,\n y1: 20.5,\n x2: 12,\n y2: 3.5,\n transition: { ease: 'easeInOut', duration: 0.3, delay: 0.1 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n x1: 5,\n y1: 12,\n x2: 19,\n y2: 12,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n rotate: 45,\n x1: 3.5,\n y1: 12,\n x2: 20.5,\n y2: 12,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: PlusProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.line\n x1={12}\n y1={19}\n x2={12}\n y2={5}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={5}\n y1={12}\n x2={19}\n y2={12}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Plus(props: PlusProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Plus,\n Plus as PlusIcon,\n type PlusProps,\n type PlusProps as PlusIconProps,\n};",
},
],
keywords: [
'plus',
'add',
'sum',
'addition',
'math',
'maths',
'new',
'+',
'increase',
'positive',
'calculate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/plus/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'plus-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/plus-icon',
},
'refresh-ccw-icon': {
name: 'refresh-ccw-icon',
description: 'Refresh ccw icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/refresh-ccw/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/refresh-ccw.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RefreshCcwProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: -45,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n animate: {\n rotate: -360,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RefreshCcwProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 3v5h5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M16 16h5v5"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RefreshCcw(props: RefreshCcwProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RefreshCcw,\n RefreshCcw as RefreshCcwIcon,\n type RefreshCcwProps,\n type RefreshCcwProps as RefreshCcwIconProps,\n};',
},
],
keywords: [
'rotate',
'arrows',
'synchronise',
'reload',
'rerun',
'circular',
'cycle',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/refresh-ccw/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'refresh-ccw-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/refresh-ccw-icon',
},
'refresh-ccw-dot-icon': {
name: 'refresh-ccw-dot-icon',
description: 'Refresh ccw dot icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/refresh-ccw-dot/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/refresh-ccw-dot.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RefreshCcwProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: -45,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n circle: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n animate: {\n rotate: -360,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RefreshCcwProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 12A9 9 0 0 0 6 5.3L3 8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 2v6h6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 12a9 9 0 0 0 15 6.7l3-2.7"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 22v-6h-6"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx="12"\n cy="12"\n r="1"\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RefreshCcw(props: RefreshCcwProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RefreshCcw,\n RefreshCcw as RefreshCcwIcon,\n type RefreshCcwProps,\n type RefreshCcwProps as RefreshCcwIconProps,\n};',
},
],
keywords: [
'rotate',
'arrows',
'synchronise',
'reload',
'rerun',
'circular',
'cycle',
'issue',
'code',
'coding',
'version control',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/refresh-ccw-dot/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'refresh-ccw-dot-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/refresh-ccw-dot-icon',
},
'refresh-cw-icon': {
name: 'refresh-cw-icon',
description: 'Refresh cw icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/refresh-cw/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/refresh-cw.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RefreshCwProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: 45,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n animate: {\n rotate: 360,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RefreshCwProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 3v5h-5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8 16H3v5"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RefreshCw(props: RefreshCwProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RefreshCw,\n RefreshCw as RefreshCwIcon,\n type RefreshCwProps,\n type RefreshCwProps as RefreshCwIconProps,\n};',
},
],
keywords: [
'rotate',
'arrows',
'synchronise',
'reload',
'rerun',
'circular',
'cycle',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/refresh-cw/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'refresh-cw-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/refresh-cw-icon',
},
'refresh-cw-off-icon': {
name: 'refresh-cw-off-icon',
description: 'Refresh cw off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/refresh-cw-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/refresh-cw-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RefreshCwOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RefreshCwOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 8L18.74 5.74A9.75 9.75 0 0 0 12 3C11 3 10.03 3.16 9.13 3.47"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8 16H3v5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 12C3 9.51 4 7.26 5.64 5.64"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m3 16 2.26 2.26A9.75 9.75 0 0 0 12 21c2.49 0 4.74-1 6.36-2.64"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 12c0 1-.16 1.97-.47 2.87"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 3v5h-5"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 22 2 2"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RefreshCwOff(props: RefreshCwOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RefreshCwOff,\n RefreshCwOff as RefreshCwOffIcon,\n type RefreshCwOffProps,\n type RefreshCwOffProps as RefreshCwOffIconProps,\n};',
},
],
keywords: [
'rotate',
'arrows',
'synchronise',
'reload',
'rerun',
'circular',
'cycle',
'cancel',
'no',
'stop',
'error',
'disconnect',
'ignore',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/refresh-cw-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'refresh-cw-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/refresh-cw-off-icon',
},
'rotate-ccw-icon': {
name: 'rotate-ccw-icon',
description: 'Rotate ccw icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/rotate-ccw/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/rotate-ccw.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RotateCcwProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: -45,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: -360,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RotateCcwProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 3v5h5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RotateCcw(props: RotateCcwProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RotateCcw,\n RotateCcw as RotateCcwIcon,\n type RotateCcwProps,\n type RotateCcwProps as RotateCcwIconProps,\n};',
},
],
keywords: [
'rotate',
'arrow',
'left',
'counter-clockwise',
'restart',
'reload',
'rerun',
'refresh',
'backup',
'undo',
'replay',
'redo',
'retry',
'rewind',
'reverse',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/rotate-ccw/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rotate-ccw-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rotate-ccw-icon',
},
'rotate-cw-icon': {
name: 'rotate-cw-icon',
description: 'Rotate cw icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/rotate-cw/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/rotate-cw.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype RotateCwProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n animate: {\n rotate: 45,\n transition: { type: \'spring\', stiffness: 150, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n animate: {\n rotate: 360,\n transition: { type: \'spring\', stiffness: 100, damping: 25 },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: RotateCwProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 3v5h-5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction RotateCw(props: RotateCwProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n RotateCw,\n RotateCw as RotateCwIcon,\n type RotateCwProps,\n type RotateCwProps as RotateCwIconProps,\n};',
},
],
keywords: [
'rotate',
'arrow',
'right',
'clockwise',
'refresh',
'reload',
'rerun',
'redo',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/rotate-cw/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rotate-cw-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rotate-cw-icon',
},
'search-icon': {
name: 'search-icon',
description: 'Search icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/search/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/search.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SearchProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n transformOrigin: \'bottom right\',\n rotate: [0, 17, -10, 5, -1, 0],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path: {},\n circle: {},\n } satisfies Record<string, Variants>,\n find: {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, \'-15%\', 0, 0],\n y: [0, 0, \'-15%\', 0],\n transition: { duration: 1, ease: \'easeInOut\' },\n },\n },\n path: {},\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SearchProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="m21 21-4.34-4.34"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={11}\n cy={11}\n r={8}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Search(props: SearchProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Search,\n Search as SearchIcon,\n type SearchProps,\n type SearchProps as SearchIconProps,\n};',
},
],
keywords: ['find', 'scan', 'magnifier', 'magnifying glass', 'lens'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/search/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'search-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/search-icon',
},
'send-icon': {
name: 'send-icon',
description: 'Send icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/send/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/send.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype SendProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n x: 0,\n y: 0,\n },\n animate: {\n scale: [1, 0.8, 1, 1, 1],\n x: [0, '-10%', '100%', '-125%', 0],\n y: [0, '10%', '-100%', '125%', 0],\n transition: {\n default: { ease: 'easeInOut', duration: 1.2 },\n x: {\n ease: 'easeInOut',\n duration: 1.2,\n times: [0, 0.25, 0.5, 0.5, 1],\n },\n y: {\n ease: 'easeInOut',\n duration: 1.2,\n times: [0, 0.25, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SendProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.g variants={variants.group} initial=\"initial\" animate={controls}>\n <motion.path\n d=\"M14.5,21.7c.1.3.4.4.7.3.1,0,.2-.2.3-.3L22,2.7c0-.3,0-.5-.3-.6-.1,0-.2,0-.3,0L2.3,8.5c-.3,0-.4.4-.3.6,0,.1.2.2.3.3l7.9,3.2c.5.2.9.6,1.1,1.1l3.2,7.9Z\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M21.9,2.1l-10.9,10.9\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction Send(props: SendProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Send,\n Send as SendIcon,\n type SendProps,\n type SendProps as SendIconProps,\n};",
},
],
keywords: ['send', 'email', 'message', 'mail', 'paper aeroplane', 'submit'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/send/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'send-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/send-icon',
},
'send-horizontal-icon': {
name: 'send-horizontal-icon',
description: 'Send horizontal icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/send-horizontal/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/send-horizontal.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SendHorizontalProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n x: 0,\n },\n animate: {\n scale: [1, 0.8, 1, 1, 1],\n x: [0, \'-10%\', \'125%\', \'-150%\', 0],\n transition: {\n default: { ease: \'easeInOut\', duration: 1.2 },\n x: {\n ease: \'easeInOut\',\n duration: 1.2,\n times: [0, 0.25, 0.5, 0.5, 1],\n },\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SendHorizontalProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M3.7,3c-.2-.1-.5,0-.7.2,0,.1,0,.3,0,.4l2.8,7.6c.2.5.2.9,0,1.4l-2.8,7.6c0,.3,0,.5.3.6.1,0,.3,0,.4,0l18-8.5c.2-.1.4-.4.2-.7,0-.1-.1-.2-.2-.2L3.7,3Z"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M6,12h16"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction SendHorizontal(props: SendHorizontalProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SendHorizontal,\n SendHorizontal as SendHorizontalIcon,\n type SendHorizontalProps,\n type SendHorizontalProps as SendHorizontalIconProps,\n};',
},
],
keywords: ['send', 'email', 'message', 'mail', 'paper aeroplane', 'submit'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/send-horizontal/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'send-horizontal-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/send-horizontal-icon',
},
'settings-icon': {
name: 'settings-icon',
description: 'Settings icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/settings/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/settings.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SettingsProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 90, 180],\n transition: {\n duration: 1.25,\n ease: \'easeInOut\',\n },\n },\n },\n path: {},\n circle: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, 90, 180, 270, 360],\n transition: {\n duration: 2.5,\n ease: \'easeInOut\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path: {},\n circle: {},\n } satisfies Record<string, Variants>,\n rotate: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: 360,\n transition: {\n duration: 2,\n ease: \'linear\',\n repeat: Infinity,\n repeatType: \'loop\',\n },\n },\n },\n path: {},\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SettingsProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={12}\n cy={12}\n r={3}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n </motion.svg>\n );\n}\n\nfunction Settings(props: SettingsProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Settings,\n Settings as SettingsIcon,\n type SettingsProps,\n type SettingsProps as SettingsIconProps,\n};',
},
],
keywords: ['cog', 'edit', 'gear', 'preferences'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/settings/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'settings-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/settings-icon',
},
'shrink-icon': {
name: 'shrink-icon',
description: 'Shrink icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/shrink/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/shrink.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype ShrinkProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -1,\n x: -1,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 1,\n x: -1,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: -1,\n x: 1,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n animate: {\n y: 1,\n x: 1,\n transition: { duration: 0.3, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n 'default-loop': {\n path1: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -1, 0],\n x: [0, -1, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path2: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 1, 0],\n x: [0, -1, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path3: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, -1, 0],\n x: [0, 1, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n path4: {\n initial: {\n y: 0,\n x: 0,\n },\n animate: {\n y: [0, 1, 0],\n x: [0, 1, 0],\n transition: { duration: 0.6, ease: 'easeInOut' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ShrinkProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.path\n d=\"m15 15 6 6m-6-6v4.8m0-4.8h4.8\"\n variants={variants.path1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M9 19.8V15m0 0H4.2M9 15l-6 6\"\n variants={variants.path3}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M15 4.2V9m0 0h4.8M15 9l6-6\"\n variants={variants.path2}\n initial=\"initial\"\n animate={controls}\n />\n <motion.path\n d=\"M9 4.2V9m0 0H4.2M9 9 3 3\"\n variants={variants.path4}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Shrink(props: ShrinkProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Shrink,\n Shrink as ShrinkIcon,\n type ShrinkProps,\n type ShrinkProps as ShrinkIconProps,\n};",
},
],
keywords: ['scale', 'fullscreen', 'maximize', 'minimize', 'contract'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/shrink/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'shrink-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/shrink-icon',
},
'square-arrow-out-down-left-icon': {
name: 'square-arrow-out-down-left-icon',
description: 'Square arrow out down left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-arrow-out-down-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-arrow-out-down-left.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareArrowOutDownLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n animate: {\n x: -2,\n y: 2,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -2, 0],\n y: [0, 2, 0],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareArrowOutDownLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m3 21 9-9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 21H3v-6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M13 21h6a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareArrowOutDownLeft(props: SquareArrowOutDownLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareArrowOutDownLeft,\n SquareArrowOutDownLeft as SquareArrowOutDownLeftIcon,\n type SquareArrowOutDownLeftProps,\n type SquareArrowOutDownLeftProps as SquareArrowOutDownLeftIconProps,\n};',
},
],
keywords: ['outwards', 'direction', 'south-west', 'diagonal'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/square-arrow-out-down-left/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-arrow-out-down-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-arrow-out-down-left-icon',
},
'square-arrow-out-down-right-icon': {
name: 'square-arrow-out-down-right-icon',
description: 'Square arrow out down right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-arrow-out-down-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-arrow-out-down-right.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareArrowOutDownRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n animate: {\n x: 2,\n y: 2,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 2, 0],\n y: [0, 2, 0],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareArrowOutDownRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m21 21-9-9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 15v6h-6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M21 11V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareArrowOutDownRight(props: SquareArrowOutDownRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareArrowOutDownRight,\n SquareArrowOutDownRight as SquareArrowOutDownRightIcon,\n type SquareArrowOutDownRightProps,\n type SquareArrowOutDownRightProps as SquareArrowOutDownRightIconProps,\n};',
},
],
keywords: ['outwards', 'direction', 'south-east', 'diagonal'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/square-arrow-out-down-right/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-arrow-out-down-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-arrow-out-down-right-icon',
},
'square-arrow-out-up-left-icon': {
name: 'square-arrow-out-up-left-icon',
description: 'Square arrow out up left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-arrow-out-up-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-arrow-out-up-left.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareArrowOutUpLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n animate: {\n x: -2,\n y: -2,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, -2, 0],\n y: [0, -2, 0],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareArrowOutUpLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m3 3 9 9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 9V3h6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M13 3h6a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareArrowOutUpLeft(props: SquareArrowOutUpLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareArrowOutUpLeft,\n SquareArrowOutUpLeft as SquareArrowOutUpLeftIcon,\n type SquareArrowOutUpLeftProps,\n type SquareArrowOutUpLeftProps as SquareArrowOutUpLeftIconProps,\n};',
},
],
keywords: ['outwards', 'direction', 'north-west', 'diagonal'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/square-arrow-out-up-left/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-arrow-out-up-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-arrow-out-up-left-icon',
},
'square-arrow-out-up-right-icon': {
name: 'square-arrow-out-up-right-icon',
description: 'Square arrow out up right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-arrow-out-up-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-arrow-out-up-right.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareArrowOutUpRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n y: 0,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n animate: {\n x: 2,\n y: -2,\n transition: { duration: 0.4, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n x: 0,\n y: 0,\n },\n animate: {\n x: [0, 2, 0],\n y: [0, -2, 0],\n transition: { duration: 0.8, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareArrowOutUpRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="m21 3-9 9"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 3h6v6"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M21 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareArrowOutUpRight(props: SquareArrowOutUpRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareArrowOutUpRight,\n SquareArrowOutUpRight as SquareArrowOutUpRightIcon,\n type SquareArrowOutUpRightProps,\n type SquareArrowOutUpRightProps as SquareArrowOutUpRightIconProps,\n};',
},
],
keywords: [
'outwards',
'direction',
'north-east',
'diagonal',
'share',
'open',
'external',
'link',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/square-arrow-out-up-right/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-arrow-out-up-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-arrow-out-up-right-icon',
},
'square-dashed-kanban-icon': {
name: 'square-dashed-kanban-icon',
description: 'Square Dashed Kanban icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-dashed-kanban/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-dashed-kanban.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareDashedKanbanProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n path6: {},\n path7: {},\n path8: {},\n path9: {},\n path10: {},\n path11: {},\n path12: {},\n line1: {\n initial: {\n y2: 16,\n },\n animate: {\n y2: [16, 11, 14, 16],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line2: {\n initial: {\n y2: 11,\n },\n animate: {\n y2: [11, 14, 16, 11],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line3: {\n initial: {\n y2: 14,\n },\n animate: {\n y2: [14, 16, 11, 14],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareDashedKanbanProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M5 3a2 2 0 0 0-2 2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 3h1"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 3h1"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19 3a2 2 0 0 1 2 2"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 9v1"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 14v1"\n variants={variants.path6}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M21 19a2 2 0 0 1-2 2"\n variants={variants.path7}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M14 21h1"\n variants={variants.path8}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 21h1"\n variants={variants.path9}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5 21a2 2 0 0 1-2-2"\n variants={variants.path10}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 14v1"\n variants={variants.path11}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 9v1"\n variants={variants.path12}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={16}\n y1={7}\n x2={16}\n y2={16}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={7}\n x2={12}\n y2={11}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={7}\n x2={8}\n y2={14}\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareDashedKanban(props: SquareDashedKanbanProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareDashedKanban,\n SquareDashedKanban as SquareDashedKanbanIcon,\n type SquareDashedKanbanProps,\n type SquareDashedKanbanProps as SquareDashedKanbanIconProps,\n};',
},
],
keywords: [
'projects',
'manage',
'overview',
'board',
'tickets',
'issues',
'roadmap',
'plan',
'intentions',
'productivity',
'work',
'agile',
'code',
'coding',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/icons/square-dashed-kanban/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-dashed-kanban-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-dashed-kanban-icon',
},
'square-kanban-icon': {
name: 'square-kanban-icon',
description: 'Square Kanban icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-kanban/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-kanban.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareKanbanProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {\n initial: {\n y2: 16,\n },\n animate: {\n y2: [16, 11, 14, 16],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line2: {\n initial: {\n y2: 11,\n },\n animate: {\n y2: [11, 14, 16, 11],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n line3: {\n initial: {\n y2: 14,\n },\n animate: {\n y2: [14, 16, 11, 14],\n transition: { duration: 0.6, ease: \'linear\' },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareKanbanProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n x={3}\n y={3}\n width={18}\n height={18}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={16}\n y1={7}\n x2={16}\n y2={16}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={7}\n x2={12}\n y2={11}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={7}\n x2={8}\n y2={14}\n variants={variants.line3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareKanban(props: SquareKanbanProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareKanban,\n SquareKanban as SquareKanbanIcon,\n type SquareKanbanProps,\n type SquareKanbanProps as SquareKanbanIconProps,\n};',
},
],
keywords: [
'projects',
'manage',
'overview',
'board',
'tickets',
'issues',
'roadmap',
'plan',
'intentions',
'productivity',
'work',
'agile',
'code',
'coding',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/square-kanban/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-kanban-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-kanban-icon',
},
'square-plus-icon': {
name: 'square-plus-icon',
description: 'Square plus icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-plus/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-plus.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquarePlusProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquarePlusProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={8}\n y1={12}\n x2={16}\n y2={12}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n y1={16}\n x2={12}\n y2={8}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquarePlus(props: SquarePlusProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquarePlus,\n SquarePlus as SquarePlusIcon,\n type SquarePlusProps,\n type SquarePlusProps as SquarePlusIconProps,\n};',
},
],
keywords: [
'square',
'rect',
'plus',
'add',
'sum',
'addition',
'math',
'maths',
'new',
'+',
'increase',
'positive',
'calculate',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/square-plus/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-plus-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-plus-icon',
},
'square-x-icon': {
name: 'square-x-icon',
description: 'Square x icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/square-x/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/square-x.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype SquareXProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: \'easeInOut\', duration: 0.4, delay: 0.1 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: SquareXProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={18}\n height={18}\n x={3}\n y={3}\n rx={2}\n ry={2}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={9}\n y1={15}\n x2={15}\n y2={9}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={9}\n y1={9}\n x2={15}\n y2={15}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction SquareX(props: SquareXProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n SquareX,\n SquareX as SquareXIcon,\n type SquareXProps,\n type SquareXProps as SquareXIconProps,\n};',
},
],
keywords: [
'square',
'x',
'cross',
'delete',
'close',
'cancel',
'remove',
'clear',
'math',
'multiply',
'multiplication',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/square-x/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'square-x-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/square-x-icon',
},
'star-icon': {
name: 'star-icon',
description: 'Star icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/star/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/star.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype StarProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.9, 1.2, 1],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path: {},\n } satisfies Record<string, Variants>,\n fill: {\n group: {\n initial: {\n scale: 1,\n },\n animate: {\n scale: [1, 0.9, 1.2, 1],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path: {\n initial: {\n fill: \'currentColor\',\n fillOpacity: 0,\n },\n animate: {\n fillOpacity: 1,\n transition: { delay: 0.2 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: StarProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Star(props: StarProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Star,\n Star as StarIcon,\n type StarProps,\n type StarProps as StarIconProps,\n};',
},
],
keywords: ['bookmark', 'favorite', 'like', 'review', 'rating'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/star/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'star-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/star-icon',
},
'thumbs-down-icon': {
name: 'thumbs-down-icon',
description: 'Thumbs down icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/thumbs-down/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/thumbs-down.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ThumbsDownProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, -20, -12],\n transformOrigin: \'top right\',\n transition: {\n duration: 0.4,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, -20, 5, 0],\n transformOrigin: \'top right\',\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ThumbsDownProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M17 14V2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ThumbsDown(props: ThumbsDownProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ThumbsDown,\n ThumbsDown as ThumbsDownIcon,\n type ThumbsDownProps,\n type ThumbsDownProps as ThumbsDownIconProps,\n};',
},
],
keywords: ['dislike', 'bad', 'emotion'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/thumbs-down/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'thumbs-down-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/thumbs-down-icon',
},
'thumbs-up-icon': {
name: 'thumbs-up-icon',
description: 'Thumbs up icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/thumbs-up/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/thumbs-up.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ThumbsUpProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, -20, -12],\n transformOrigin: \'bottom left\',\n transition: {\n duration: 0.4,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n rotate: 0,\n },\n animate: {\n rotate: [0, -20, 5, 0],\n transformOrigin: \'bottom left\',\n transition: {\n duration: 0.8,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ThumbsUpProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M7 10v12"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ThumbsUp(props: ThumbsUpProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ThumbsUp,\n ThumbsUp as ThumbsUpIcon,\n type ThumbsUpProps,\n type ThumbsUpProps as ThumbsUpIconProps,\n};',
},
],
keywords: ['like', 'good', 'emotion'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/thumbs-up/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'thumbs-up-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/thumbs-up-icon',
},
'timer-icon': {
name: 'timer-icon',
description: 'Timer icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/timer/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/timer.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype TimerProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n circle: {},\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: \'easeInOut\', duration: 0.6 },\n },\n animate: {\n transformOrigin: \'bottom left\',\n rotate: 360,\n transition: { ease: \'easeInOut\', duration: 0.6, delay: 0.15 },\n },\n },\n line2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1.5, 0],\n transition: { ease: \'easeInOut\', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: TimerProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.circle\n cx={12}\n cy={14}\n r={8}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={12}\n x2={15}\n y1={14}\n y2={11}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={10}\n x2={14}\n y1={2}\n y2={2}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Timer(props: TimerProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Timer,\n Timer as TimerIcon,\n type TimerProps,\n type TimerProps as TimerIconProps,\n};',
},
],
keywords: ['time', 'timer', 'stopwatch'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/timer/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'timer-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/timer-icon',
},
'timer-off-icon': {
name: 'timer-off-icon',
description: 'Timer off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/timer-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/timer-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype TimerOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n path5: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: TimerOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M10 2h4"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M4.6 11a8 8 0 0 0 1.7 8.7 8 8 0 0 0 8.7 1.7"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M7.4 7.4a8 8 0 0 1 10.3 1 8 8 0 0 1 .9 10.2"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M12 12v-2"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction TimerOff(props: TimerOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n TimerOff,\n TimerOff as TimerOffIcon,\n type TimerOffProps,\n type TimerOffProps as TimerOffIconProps,\n};',
},
],
keywords: ['time', 'timer', 'stopwatch'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/timer-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'timer-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/timer-off-icon',
},
'toggle-left-icon': {
name: 'toggle-left-icon',
description: 'Toggle left icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/toggle-left/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/toggle-left.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ToggleLeftProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n circle: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 7, 6],\n transition: {\n duration: 0.5,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n rect: {},\n circle: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, 7, 6, -1, 0],\n transition: {\n duration: 1,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ToggleLeftProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={20}\n height={14}\n x={2}\n y={5}\n rx={7}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={9}\n cy={12}\n r={3}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ToggleLeft(props: ToggleLeftProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ToggleLeft,\n ToggleLeft as ToggleLeftIcon,\n type ToggleLeftProps,\n type ToggleLeftProps as ToggleLeftIconProps,\n};',
},
],
keywords: ['on', 'off', 'switch', 'boolean'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/toggle-left/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'toggle-left-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/toggle-left-icon',
},
'toggle-right-icon': {
name: 'toggle-right-icon',
description: 'Toggle right icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/toggle-right/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/toggle-right.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype ToggleRightProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n rect: {},\n circle: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -7, -6],\n transition: {\n duration: 0.5,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n rect: {},\n circle: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, -7, -6, 1, 0],\n transition: {\n duration: 1,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: ToggleRightProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.rect\n width={20}\n height={14}\n x={2}\n y={5}\n rx={7}\n variants={variants.rect}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={15}\n cy={12}\n r={3}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction ToggleRight(props: ToggleRightProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n ToggleRight,\n ToggleRight as ToggleRightIcon,\n type ToggleRightProps,\n type ToggleRightProps as ToggleRightIconProps,\n};',
},
],
keywords: ['on', 'off', 'switch', 'boolean'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/toggle-right/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'toggle-right-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/toggle-right-icon',
},
'trash-icon': {
name: 'trash-icon',
description: 'Trash icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/trash/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/trash.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype TrashProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: -1,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {\n initial: {\n y: 0,\n d: \'M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\',\n },\n animate: {\n y: 1,\n d: \'M19 8v12c0 1-1 2-2 2H7c-1 0-2-1-2-2V8\',\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: TrashProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 6h18"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Trash(props: TrashProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Trash,\n Trash as TrashIcon,\n type TrashProps,\n type TrashProps as TrashIconProps,\n};',
},
],
keywords: ['garbage', 'delete', 'remove', 'bin'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/trash/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'trash-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/trash-icon',
},
'trash-2-icon': {
name: 'trash-2-icon',
description: 'Trash 2 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/trash-2/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/trash-2.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype Trash2Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n },\n animate: {\n y: -1,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n path1: {},\n path2: {},\n path3: {\n initial: {\n y: 0,\n d: \'M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\',\n },\n animate: {\n y: 1,\n d: \'M19 8v12c0 1-1 2-2 2H7c-1 0-2-1-2-2V8\',\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n line1: {\n initial: {\n y: 0,\n },\n animate: {\n y: 1,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n line2: {\n initial: {\n y: 0,\n },\n animate: {\n y: 1,\n transition: {\n duration: 0.3,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Trash2Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M3 6h18"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={10}\n x2={10}\n y1={11}\n y2={17}\n variants={variants.line1}\n initial="initial"\n animate={controls}\n />\n <motion.line\n x1={14}\n x2={14}\n y1={11}\n y2={17}\n variants={variants.line2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Trash2(props: Trash2Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Trash2,\n Trash2 as Trash2Icon,\n type Trash2Props,\n type Trash2Props as Trash2IconProps,\n};',
},
],
keywords: ['garbage', 'delete', 'remove', 'bin'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/trash-2/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'trash-2-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/trash-2-icon',
},
'upload-icon': {
name: 'upload-icon',
description: 'Upload icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/upload/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/upload.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype UploadProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n y: 0,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n animate: {\n y: -2,\n transition: { duration: 0.3, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n \'default-loop\': {\n group: {\n initial: {\n y: 0,\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n animate: {\n y: [0, -2, 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: UploadProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.g variants={variants.group} initial="initial" animate={controls}>\n <motion.path\n d="M12 3v12"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m17 8-5-5-5 5"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.g>\n <motion.path\n d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Upload(props: UploadProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Upload,\n Upload as UploadIcon,\n type UploadProps,\n type UploadProps as UploadIconProps,\n};',
},
],
keywords: ['file'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/upload/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'upload-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/upload-icon',
},
'user-icon': {
name: 'user-icon',
description: 'User icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/user/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/user.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype UserProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 2, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: UserProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={12}\n cy={7}\n r={4}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction User(props: UserProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n User,\n User as UserIcon,\n type UserProps,\n type UserProps as UserIconProps,\n};',
},
],
keywords: ['person', 'account', 'contact'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/user/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'user-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/user-icon',
},
'user-round-icon': {
name: 'user-round-icon',
description: 'User round icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/user-round/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/user-round.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype UserRoundProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: UserRoundProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M20 21a8 8 0 0 0-16 0"\n variants={variants.path}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={12}\n cy={8}\n r={5}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction UserRound(props: UserRoundProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n UserRound,\n UserRound as UserRoundIcon,\n type UserRoundProps,\n type UserRoundProps as UserRoundIconProps,\n};',
},
],
keywords: ['person', 'account', 'contact'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/user-round/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'user-round-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/user-round-icon',
},
'users-icon': {
name: 'users-icon',
description: 'Users icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/users/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/users.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype UsersProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 2, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n delay: 0.1,\n },\n },\n },\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n path3: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 2, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n delay: 0.1,\n },\n },\n },\n } satisfies Record<string, Variants>,\n appear: {\n path1: {},\n path2: {\n initial: {\n x: -6,\n opacity: 0,\n },\n animate: {\n x: 0,\n opacity: 1,\n transition: {\n type: \'spring\',\n stiffness: 100,\n damping: 10,\n },\n },\n },\n path3: {\n initial: {\n x: -6,\n opacity: 0,\n },\n animate: {\n x: 0,\n opacity: 1,\n transition: {\n type: \'spring\',\n stiffness: 100,\n damping: 10,\n },\n },\n },\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: UsersProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M16 3.128a4 4 0 0 1 0 7.744"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22 21v-2a4 4 0 0 0-3-3.87"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={9}\n cy={7}\n r={4}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Users(props: UsersProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Users,\n Users as UsersIcon,\n type UsersProps,\n type UsersProps as UsersIconProps,\n};',
},
],
keywords: ['group', 'people'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/users/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'users-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/users-icon',
},
'users-round-icon': {
name: 'users-round-icon',
description: 'Users round icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/users-round/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/users-round.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype UsersRoundProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n delay: 0.1,\n },\n },\n },\n path2: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n path3: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 4, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n },\n },\n },\n circle: {\n initial: {\n y: 0,\n },\n animate: {\n y: [0, 1, -2, 0],\n transition: {\n duration: 0.6,\n ease: \'easeInOut\',\n delay: 0.1,\n },\n },\n },\n } satisfies Record<string, Variants>,\n appear: {\n path1: {},\n path2: {\n initial: {\n x: -5,\n opacity: 0,\n },\n animate: {\n x: 0,\n opacity: 1,\n transition: {\n type: \'spring\',\n stiffness: 100,\n damping: 10,\n },\n },\n },\n path3: {\n initial: {\n x: -5,\n opacity: 0,\n },\n animate: {\n x: 0,\n opacity: 1,\n transition: {\n type: \'spring\',\n stiffness: 100,\n damping: 10,\n },\n },\n },\n circle: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: UsersRoundProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M18,21c0-4.4-3.6-8-8-8s-8,3.6-8,8"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M18,12c2.2-1.7,2.7-4.8,1-7-.4-.5-.9-1-1.4-1.3"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M22,20c0-3.4-2-6.5-4-8"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.circle\n cx={10}\n cy={8}\n r={5}\n variants={variants.circle}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction UsersRound(props: UsersRoundProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n UsersRound,\n UsersRound as UsersRoundIcon,\n type UsersRoundProps,\n type UsersRoundProps as UsersRoundIconProps,\n};',
},
],
keywords: ['group', 'people'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/users-round/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'users-round-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/users-round-icon',
},
'volume-1-icon': {
name: 'volume-1-icon',
description: 'Volume 1 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/volume-1/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/volume-1.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype Volume1Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n path1: {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n },\n },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Volume1Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M16 9a5 5 0 0 1 0 6"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Volume1(props: Volume1Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Volume1,\n Volume1 as Volume1Icon,\n type Volume1Props,\n type Volume1Props as Volume1IconProps,\n};',
},
],
keywords: ['music', 'sound', 'speaker'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/volume-1/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'volume-1-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/volume-1-icon',
},
'volume-2-icon': {
name: 'volume-2-icon',
description: 'Volume 2 icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/volume-2/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/volume-2.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype Volume2Props = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const animation: Record<string, Variants> = {};\n\n for (let i = 1; i <= 2; i++) {\n animation[`path${i}`] = {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n },\n },\n };\n }\n\n return animation;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: Volume2Props) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M16 9a5 5 0 0 1 0 6"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19.364 18.364a9 9 0 0 0 0-12.728"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Volume2(props: Volume2Props) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Volume2,\n Volume2 as Volume2Icon,\n type Volume2Props,\n type Volume2Props as Volume2IconProps,\n};',
},
],
keywords: ['music', 'sound', 'speaker'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/volume-2/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'volume-2-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/volume-2-icon',
},
'volume-off-icon': {
name: 'volume-off-icon',
description: 'Volume off icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/volume-off/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/volume-off.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype VolumeOffProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n group: {\n initial: {\n x: 0,\n },\n animate: {\n x: [0, \'-7%\', \'7%\', \'-7%\', \'7%\', 0],\n transition: { duration: 0.6, ease: \'easeInOut\' },\n },\n },\n path1: {},\n path2: {},\n path3: {},\n path4: {},\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: VolumeOffProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n variants={variants.group}\n initial="initial"\n animate={controls}\n {...props}\n >\n <motion.path\n d="M16 9a5 5 0 0 1 .95 2.293"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M19.364 5.636a9 9 0 0 1 1.889 9.96"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m2 2 20 20"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="m7 7-.587.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298V11"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M9.828 4.172A.686.686 0 0 1 11 4.657v.686"\n variants={variants.path5}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction VolumeOff(props: VolumeOffProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n VolumeOff,\n VolumeOff as VolumeOffIcon,\n type VolumeOffProps,\n type VolumeOffProps as VolumeOffIconProps,\n};',
},
],
keywords: ['music', 'sound', 'mute', 'speaker'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/volume-off/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'volume-off-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/volume-off-icon',
},
'wifi-icon': {
name: 'wifi-icon',
description: 'Wifi icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/wifi/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/wifi.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype WifiProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const animation: Record<string, Variants> = {};\n\n for (let i = 1; i <= 4; i++) {\n animation[`path${i}`] = {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n },\n },\n };\n }\n\n return animation;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: WifiProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12 20h.01"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.5 16.429a5 5 0 0 1 7 0"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5 12.859a10 10 0 0 1 14 0"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M2 8.82a15 15 0 0 1 20 0"\n variants={variants.path4}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction Wifi(props: WifiProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n Wifi,\n Wifi as WifiIcon,\n type WifiProps,\n type WifiProps as WifiIconProps,\n};',
},
],
keywords: ['connection', 'signal', 'wireless'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/wifi/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'wifi-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/wifi-icon',
},
'wifi-high-icon': {
name: 'wifi-high-icon',
description: 'Wifi high icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/wifi-high/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/wifi-high.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype WifiHighProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const animation: Record<string, Variants> = {};\n\n for (let i = 1; i <= 3; i++) {\n animation[`path${i}`] = {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n },\n },\n };\n }\n\n return animation;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: WifiHighProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12 20h.01"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.5 16.429a5 5 0 0 1 7 0"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M5 12.859a10 10 0 0 1 14 0"\n variants={variants.path3}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction WifiHigh(props: WifiHighProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n WifiHigh,\n WifiHigh as WifiHighIcon,\n type WifiHighProps,\n type WifiHighProps as WifiHighIconProps,\n};',
},
],
keywords: ['connection', 'signal', 'wireless'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/wifi-high/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'wifi-high-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/wifi-high-icon',
},
'wifi-low-icon': {
name: 'wifi-low-icon',
description: 'Wifi low icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/wifi-low/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/wifi-low.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Variants } from \'motion/react\';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from \'@/components/animate-ui/icons/icon\';\n\ntype WifiLowProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: (() => {\n const animation: Record<string, Variants> = {};\n\n for (let i = 1; i <= 2; i++) {\n animation[`path${i}`] = {\n initial: { opacity: 1, scale: 1 },\n animate: {\n opacity: 0,\n scale: 0,\n transition: {\n opacity: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n scale: {\n duration: 0.2,\n ease: \'easeInOut\',\n repeat: 1,\n repeatType: \'reverse\',\n repeatDelay: 0.2,\n delay: 0.2 * (i - 1),\n },\n },\n },\n };\n }\n\n return animation;\n })() satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: WifiLowProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap="round"\n strokeLinejoin="round"\n {...props}\n >\n <motion.path\n d="M12 20h.01"\n variants={variants.path1}\n initial="initial"\n animate={controls}\n />\n <motion.path\n d="M8.5 16.429a5 5 0 0 1 7 0"\n variants={variants.path2}\n initial="initial"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction WifiLow(props: WifiLowProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport {\n animations,\n WifiLow,\n WifiLow as WifiLowIcon,\n type WifiLowProps,\n type WifiLowProps as WifiLowIconProps,\n};',
},
],
keywords: ['connection', 'signal', 'wireless'],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/wifi-low/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'wifi-low-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/wifi-low-icon',
},
'x-icon': {
name: 'x-icon',
description: 'X icon component.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/icons/x/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/icons/x.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Variants } from 'motion/react';\n\nimport {\n getVariants,\n useAnimateIconContext,\n IconWrapper,\n type IconProps,\n} from '@/components/animate-ui/icons/icon';\n\ntype XProps = IconProps<keyof typeof animations>;\n\nconst animations = {\n default: {\n line1: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.4 },\n },\n animate: {\n rotate: 90,\n transition: { ease: 'easeInOut', duration: 0.4 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n transition: { ease: 'easeInOut', duration: 0.4, delay: 0.1 },\n },\n animate: {\n rotate: 90,\n transition: { ease: 'easeInOut', duration: 0.4, delay: 0.1 },\n },\n },\n } satisfies Record<string, Variants>,\n plus: {\n line1: {\n initial: {\n rotate: 0,\n x1: 6,\n y1: 18,\n x2: 18,\n y2: 6,\n transition: { ease: 'easeInOut', duration: 0.3, delay: 0.1 },\n },\n animate: {\n rotate: 45,\n x1: 7.1,\n y1: 16.9,\n x2: 16.9,\n y2: 7.1,\n transition: { ease: 'easeInOut', duration: 0.3, delay: 0.1 },\n },\n },\n line2: {\n initial: {\n rotate: 0,\n x1: 6,\n y1: 6,\n x2: 18,\n y2: 18,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n animate: {\n rotate: 45,\n x1: 7.1,\n y1: 7.1,\n x2: 16.9,\n y2: 16.9,\n transition: { ease: 'easeInOut', duration: 0.3 },\n },\n },\n } satisfies Record<string, Variants>,\n} as const;\n\nfunction IconComponent({ size, ...props }: XProps) {\n const { controls } = useAnimateIconContext();\n const variants = getVariants(animations);\n\n return (\n <motion.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={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <motion.line\n x1={6}\n y1={18}\n x2={18}\n y2={6}\n variants={variants.line1}\n initial=\"initial\"\n animate={controls}\n />\n <motion.line\n x1={6}\n y1={6}\n x2={18}\n y2={18}\n variants={variants.line2}\n initial=\"initial\"\n animate={controls}\n />\n </motion.svg>\n );\n}\n\nfunction X(props: XProps) {\n return <IconWrapper icon={IconComponent} {...props} />;\n}\n\nexport { animations, X, X as XIcon, type XProps, type XProps as XIconProps };",
},
],
keywords: [
'cross',
'x',
'delete',
'close',
'cancel',
'remove',
'clear',
'math',
'multiply',
'multiplication',
],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/icons/x/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'x-icon';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/x-icon',
},
'radix-accordion': {
name: 'radix-accordion',
description:
'A vertically stacked set of interactive headings that each reveal an associated section of content.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/accordion/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/accordion.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Accordion as AccordionPrimitive } from 'radix-ui';\nimport { ChevronDown } from 'lucide-react';\nimport {\n motion,\n AnimatePresence,\n type Transition,\n type HTMLMotionProps,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype AccordionItemContextType = {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n};\n\nconst AccordionItemContext = React.createContext<\n AccordionItemContextType | undefined\n>(undefined);\n\nconst useAccordionItem = (): AccordionItemContextType => {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('useAccordionItem must be used within an AccordionItem');\n }\n return context;\n};\n\ntype AccordionProps = React.ComponentProps<typeof AccordionPrimitive.Root>;\n\nfunction Accordion(props: AccordionProps) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\ntype AccordionItemProps = React.ComponentProps<\n typeof AccordionPrimitive.Item\n> & {\n children: React.ReactNode;\n};\n\nfunction AccordionItem({ className, children, ...props }: AccordionItemProps) {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <AccordionItemContext.Provider value={{ isOpen, setIsOpen }}>\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn('border-b', className)}\n {...props}\n >\n {children}\n </AccordionPrimitive.Item>\n </AccordionItemContext.Provider>\n );\n}\n\ntype AccordionTriggerProps = React.ComponentProps<\n typeof AccordionPrimitive.Trigger\n> & {\n transition?: Transition;\n chevron?: boolean;\n};\n\nfunction AccordionTrigger({\n ref,\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n chevron = true,\n ...props\n}: AccordionTriggerProps) {\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => triggerRef.current as HTMLButtonElement);\n const { isOpen, setIsOpen } = useAccordionItem();\n\n React.useEffect(() => {\n const node = triggerRef.current;\n if (!node) return;\n\n const observer = new MutationObserver((mutationsList) => {\n mutationsList.forEach((mutation) => {\n if (mutation.attributeName === 'data-state') {\n const currentState = node.getAttribute('data-state');\n setIsOpen(currentState === 'open');\n }\n });\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-state'],\n });\n const initialState = node.getAttribute('data-state');\n setIsOpen(initialState === 'open');\n return () => {\n observer.disconnect();\n };\n }, [setIsOpen]);\n\n return (\n <AccordionPrimitive.Header data-slot=\"accordion-header\" className=\"flex\">\n <AccordionPrimitive.Trigger\n ref={triggerRef}\n data-slot=\"accordion-trigger\"\n className={cn(\n 'flex flex-1 text-start items-center justify-between py-4 font-medium hover:underline',\n className,\n )}\n {...props}\n >\n {children}\n\n {chevron && (\n <motion.div\n data-slot=\"accordion-trigger-chevron\"\n animate={{ rotate: isOpen ? 180 : 0 }}\n transition={transition}\n >\n <ChevronDown className=\"size-5 shrink-0\" />\n </motion.div>\n )}\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\ntype AccordionContentProps = React.ComponentProps<\n typeof AccordionPrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction AccordionContent({\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n ...props\n}: AccordionContentProps) {\n const { isOpen } = useAccordionItem();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <AccordionPrimitive.Content forceMount {...props}>\n <motion.div\n key=\"accordion-content\"\n data-slot=\"accordion-content\"\n initial={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n animate={{ height: 'auto', opacity: 1, '--mask-stop': '100%' }}\n exit={{ height: 0, opacity: 0, '--mask-stop': '0%' }}\n transition={transition}\n style={{\n maskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n WebkitMaskImage:\n 'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',\n }}\n className=\"overflow-hidden\"\n {...props}\n >\n <div className={cn('pb-4 pt-0 text-sm', className)}>{children}</div>\n </motion.div>\n </AccordionPrimitive.Content>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n useAccordionItem,\n type AccordionItemContextType,\n type AccordionProps,\n type AccordionItemProps,\n type AccordionTriggerProps,\n type AccordionContentProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/accordion/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-accordion';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-accordion',
},
'radix-checkbox': {
name: 'radix-checkbox',
description:
'A control that allows the user to toggle between checked and not checked.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/checkbox/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/checkbox.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { Checkbox as CheckboxPrimitive } from \'radix-ui\';\nimport { motion, type HTMLMotionProps } from \'motion/react\';\n\nimport { cn } from \'@/lib/utils\';\n\ntype CheckboxProps = React.ComponentProps<typeof CheckboxPrimitive.Root> &\n HTMLMotionProps<\'button\'>;\n\nfunction Checkbox({ className, onCheckedChange, ...props }: CheckboxProps) {\n const [isChecked, setIsChecked] = React.useState(\n props?.checked ?? props?.defaultChecked ?? false,\n );\n\n React.useEffect(() => {\n if (props?.checked !== undefined) setIsChecked(props.checked);\n }, [props?.checked]);\n\n const handleCheckedChange = React.useCallback(\n (checked: boolean) => {\n setIsChecked(checked);\n onCheckedChange?.(checked);\n },\n [onCheckedChange],\n );\n\n return (\n <CheckboxPrimitive.Root\n {...props}\n onCheckedChange={handleCheckedChange}\n asChild\n >\n <motion.button\n data-slot="checkbox"\n className={cn(\n \'peer size-5 flex items-center justify-center shrink-0 rounded-sm bg-input transition-colors duration-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\',\n className,\n )}\n whileTap={{ scale: 0.95 }}\n whileHover={{ scale: 1.05 }}\n {...props}\n >\n <CheckboxPrimitive.Indicator forceMount asChild>\n <motion.svg\n data-slot="checkbox-indicator"\n xmlns="http://www.w3.org/2000/svg"\n fill="none"\n viewBox="0 0 24 24"\n strokeWidth="3.5"\n stroke="currentColor"\n className="size-3.5"\n initial="unchecked"\n animate={isChecked ? \'checked\' : \'unchecked\'}\n >\n <motion.path\n strokeLinecap="round"\n strokeLinejoin="round"\n d="M4.5 12.75l6 6 9-13.5"\n variants={{\n checked: {\n pathLength: 1,\n opacity: 1,\n transition: {\n duration: 0.2,\n delay: 0.2,\n },\n },\n unchecked: {\n pathLength: 0,\n opacity: 0,\n transition: {\n duration: 0.2,\n },\n },\n }}\n />\n </motion.svg>\n </CheckboxPrimitive.Indicator>\n </motion.button>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox, type CheckboxProps };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/checkbox/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-checkbox';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-checkbox',
},
'radix-collapsible': {
name: 'radix-collapsible',
description: 'An interactive component which expands/collapses a panel.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/collapsible/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/collapsible.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Collapsible as CollapsiblePrimitive } from 'radix-ui';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\ntype CollapsibleContextType = {\n isOpen: boolean;\n};\n\nconst CollapsibleContext = React.createContext<\n CollapsibleContextType | undefined\n>(undefined);\n\nconst useCollapsible = (): CollapsibleContextType => {\n const context = React.useContext(CollapsibleContext);\n if (!context) {\n throw new Error('useCollapsible must be used within a Collapsible');\n }\n return context;\n};\n\ntype CollapsibleProps = React.ComponentProps<typeof CollapsiblePrimitive.Root>;\n\nfunction Collapsible({ children, ...props }: CollapsibleProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <CollapsibleContext.Provider value={{ isOpen }}>\n <CollapsiblePrimitive.Root\n data-slot=\"collapsible\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </CollapsiblePrimitive.Root>\n </CollapsibleContext.Provider>\n );\n}\n\ntype CollapsibleTriggerProps = React.ComponentProps<\n typeof CollapsiblePrimitive.Trigger\n>;\n\nfunction CollapsibleTrigger(props: CollapsibleTriggerProps) {\n return (\n <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\n );\n}\n\ntype CollapsibleContentProps = React.ComponentProps<\n typeof CollapsiblePrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction CollapsibleContent({\n className,\n children,\n transition = { type: 'spring', stiffness: 150, damping: 22 },\n ...props\n}: CollapsibleContentProps) {\n const { isOpen } = useCollapsible();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <CollapsiblePrimitive.Content asChild forceMount {...props}>\n <motion.div\n key=\"collapsible-content\"\n data-slot=\"collapsible-content\"\n layout\n initial={{ opacity: 0, height: 0, overflow: 'hidden' }}\n animate={{ opacity: 1, height: 'auto', overflow: 'hidden' }}\n exit={{ opacity: 0, height: 0, overflow: 'hidden' }}\n transition={transition}\n className={className}\n {...props}\n >\n {children}\n </motion.div>\n </CollapsiblePrimitive.Content>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Collapsible,\n CollapsibleTrigger,\n CollapsibleContent,\n useCollapsible,\n type CollapsibleContextType,\n type CollapsibleProps,\n type CollapsibleTriggerProps,\n type CollapsibleContentProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/collapsible/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-collapsible';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-collapsible',
},
'radix-dialog': {
name: 'radix-dialog',
description:
'A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/dialog/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/dialog.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Dialog as DialogPrimitive } from 'radix-ui';\nimport { X } from 'lucide-react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype DialogContextType = {\n isOpen: boolean;\n};\n\nconst DialogContext = React.createContext<DialogContextType | undefined>(\n undefined,\n);\n\nconst useDialog = (): DialogContextType => {\n const context = React.useContext(DialogContext);\n if (!context) {\n throw new Error('useDialog must be used within a Dialog');\n }\n return context;\n};\n\ntype DialogProps = React.ComponentProps<typeof DialogPrimitive.Root>;\n\nfunction Dialog({ children, ...props }: DialogProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <DialogContext.Provider value={{ isOpen }}>\n <DialogPrimitive.Root\n data-slot=\"dialog\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </DialogPrimitive.Root>\n </DialogContext.Provider>\n );\n}\n\ntype DialogTriggerProps = React.ComponentProps<typeof DialogPrimitive.Trigger>;\n\nfunction DialogTrigger(props: DialogTriggerProps) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\ntype DialogPortalProps = React.ComponentProps<typeof DialogPrimitive.Portal>;\n\nfunction DialogPortal(props: DialogPortalProps) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\ntype DialogCloseProps = React.ComponentProps<typeof DialogPrimitive.Close>;\n\nfunction DialogClose(props: DialogCloseProps) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\ntype DialogOverlayProps = React.ComponentProps<typeof DialogPrimitive.Overlay>;\n\nfunction DialogOverlay({ className, ...props }: DialogOverlayProps) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype FlipDirection = 'top' | 'bottom' | 'left' | 'right';\n\ntype DialogContentProps = React.ComponentProps<typeof DialogPrimitive.Content> &\n HTMLMotionProps<'div'> & {\n from?: FlipDirection;\n transition?: Transition;\n };\n\nfunction DialogContent({\n className,\n children,\n from = 'top',\n transition = { type: 'spring', stiffness: 150, damping: 25 },\n ...props\n}: DialogContentProps) {\n const { isOpen } = useDialog();\n\n const initialRotation =\n from === 'top' || from === 'left' ? '20deg' : '-20deg';\n const isVertical = from === 'top' || from === 'bottom';\n const rotateAxis = isVertical ? 'rotateX' : 'rotateY';\n\n return (\n <AnimatePresence>\n {isOpen && (\n <DialogPortal forceMount data-slot=\"dialog-portal\">\n <DialogOverlay asChild forceMount>\n <motion.div\n key=\"dialog-overlay\"\n initial={{ opacity: 0, filter: 'blur(4px)' }}\n animate={{ opacity: 1, filter: 'blur(0px)' }}\n exit={{ opacity: 0, filter: 'blur(4px)' }}\n transition={{ duration: 0.2, ease: 'easeInOut' }}\n />\n </DialogOverlay>\n <DialogPrimitive.Content asChild forceMount {...props}>\n <motion.div\n key=\"dialog-content\"\n data-slot=\"dialog-content\"\n initial={{\n opacity: 0,\n filter: 'blur(4px)',\n transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n }}\n animate={{\n opacity: 1,\n filter: 'blur(0px)',\n transform: `perspective(500px) ${rotateAxis}(0deg) scale(1)`,\n }}\n exit={{\n opacity: 0,\n filter: 'blur(4px)',\n transform: `perspective(500px) ${rotateAxis}(${initialRotation}) scale(0.8)`,\n }}\n transition={transition}\n className={cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg rounded-xl',\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </motion.div>\n </DialogPrimitive.Content>\n </DialogPortal>\n )}\n </AnimatePresence>\n );\n}\n\ntype DialogHeaderProps = React.ComponentProps<'div'>;\n\nfunction DialogHeader({ className, ...props }: DialogHeaderProps) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n 'flex flex-col space-y-1.5 text-center sm:text-left',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogFooterProps = React.ComponentProps<'div'>;\n\nfunction DialogFooter({ className, ...props }: DialogFooterProps) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end gap-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogTitleProps = React.ComponentProps<typeof DialogPrimitive.Title>;\n\nfunction DialogTitle({ className, ...props }: DialogTitleProps) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\n 'text-lg font-semibold leading-none tracking-tight',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DialogDescriptionProps = React.ComponentProps<\n typeof DialogPrimitive.Description\n>;\n\nfunction DialogDescription({ className, ...props }: DialogDescriptionProps) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n useDialog,\n type DialogContextType,\n type DialogProps,\n type DialogTriggerProps,\n type DialogPortalProps,\n type DialogCloseProps,\n type DialogOverlayProps,\n type DialogContentProps,\n type DialogHeaderProps,\n type DialogFooterProps,\n type DialogTitleProps,\n type DialogDescriptionProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/dialog/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dialog';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dialog',
},
'radix-dropdown-menu': {
name: 'radix-dropdown-menu',
description:
'Displays a menu to the user — such as a set of actions or functions — triggered by a button.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react', 'radix-ui'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/radix/dropdown-menu/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/dropdown-menu.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';\nimport { Check, ChevronRight, Circle } from 'lucide-react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype DropdownMenuContextType = {\n isOpen: boolean;\n highlightTransition: Transition;\n animateOnHover: boolean;\n};\n\nconst DropdownMenuContext = React.createContext<\n DropdownMenuContextType | undefined\n>(undefined);\n\nconst useDropdownMenu = (): DropdownMenuContextType => {\n const context = React.useContext(DropdownMenuContext);\n if (!context) {\n throw new Error('useDropdownMenu must be used within a DropdownMenu');\n }\n return context;\n};\n\ntype DropdownMenuProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Root\n> & {\n transition?: Transition;\n animateOnHover?: boolean;\n};\n\nfunction DropdownMenu({\n children,\n transition = { type: 'spring', stiffness: 350, damping: 35 },\n animateOnHover = true,\n ...props\n}: DropdownMenuProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <DropdownMenuContext.Provider\n value={{ isOpen, highlightTransition: transition, animateOnHover }}\n >\n <DropdownMenuPrimitive.Root\n data-slot=\"dropdown-menu\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </DropdownMenuPrimitive.Root>\n </DropdownMenuContext.Provider>\n );\n}\n\ntype DropdownMenuTriggerProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Trigger\n>;\n\nfunction DropdownMenuTrigger(props: DropdownMenuTriggerProps) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\ntype DropdownMenuGroupProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Group\n>;\n\nfunction DropdownMenuGroup(props: DropdownMenuGroupProps) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\ntype DropdownMenuPortalProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Portal\n>;\n\nfunction DropdownMenuPortal(props: DropdownMenuPortalProps) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\ntype DropdownMenuSubProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Sub\n>;\n\nfunction DropdownMenuSub(props: DropdownMenuSubProps) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\ntype DropdownMenuRadioGroupProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.RadioGroup\n>;\n\nfunction DropdownMenuRadioGroup(props: DropdownMenuRadioGroupProps) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\ntype DropdownMenuSubTriggerProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.SubTrigger\n> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuSubTrigger({\n className,\n children,\n inset,\n disabled,\n ...props\n}: DropdownMenuSubTriggerProps) {\n return (\n <MotionHighlightItem disabled={disabled}>\n <DropdownMenuPrimitive.SubTrigger {...props} disabled={disabled} asChild>\n <motion.div\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n data-disabled={disabled}\n whileTap={{ scale: 0.95 }}\n className={cn(\n \"[&:not([data-highlight])]:focus:bg-accent focus:text-accent-foreground [&:not([data-highlight])]:data-[state=open]:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:[&_[data-chevron]]:rotate-90 [&_[data-chevron]]:transition-transform [&_[data-chevron]]:duration-150 [&_[data-chevron]]:ease-in-out [&_svg:not([class*='text-'])]:text-muted-foreground relative z-[1] flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && 'pl-8',\n className,\n )}\n >\n {children}\n <ChevronRight data-chevron className=\"ml-auto\" />\n </motion.div>\n </DropdownMenuPrimitive.SubTrigger>\n </MotionHighlightItem>\n );\n}\n\ntype DropdownMenuSubContentProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.SubContent\n>;\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: DropdownMenuSubContentProps) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n 'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DropdownMenuContentProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction DropdownMenuContent({\n className,\n children,\n sideOffset = 4,\n transition = { duration: 0.2 },\n ...props\n}: DropdownMenuContentProps) {\n const { isOpen, highlightTransition, animateOnHover } = useDropdownMenu();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <DropdownMenuPrimitive.Portal\n forceMount\n data-slot=\"dropdown-menu-portal\"\n >\n <DropdownMenuPrimitive.Content\n sideOffset={sideOffset}\n asChild\n {...props}\n >\n <motion.div\n key=\"dropdown-menu-content\"\n data-slot=\"dropdown-menu-content\"\n className={cn(\n 'z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]',\n className,\n )}\n initial={{\n opacity: 0,\n scale: 0.95,\n }}\n animate={{\n opacity: 1,\n scale: 1,\n }}\n exit={{\n opacity: 0,\n scale: 0.95,\n }}\n transition={transition}\n style={{ willChange: 'opacity, transform' }}\n {...props}\n >\n <MotionHighlight\n hover\n className=\"rounded-sm\"\n controlledItems\n transition={highlightTransition}\n enabled={animateOnHover}\n >\n {children}\n </MotionHighlight>\n </motion.div>\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\ntype DropdownMenuItemProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Item\n> & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n};\n\nfunction DropdownMenuItem({\n className,\n children,\n inset,\n disabled,\n variant = 'default',\n ...props\n}: DropdownMenuItemProps) {\n return (\n <MotionHighlightItem\n activeClassName={\n variant === 'default'\n ? 'bg-accent'\n : 'bg-destructive/10 dark:bg-destructive/20'\n }\n disabled={disabled}\n >\n <DropdownMenuPrimitive.Item {...props} disabled={disabled} asChild>\n <motion.div\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n data-disabled={disabled}\n whileTap={{ scale: 0.95 }}\n className={cn(\n \"[&:not([data-highlight])]:focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive [&:not([data-highlight])]:data-[variant=destructive]:focus:bg-destructive/10 dark:[&:not([data-highlight])]:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative z-[1] flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus-visible:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n inset && 'pl-8',\n className,\n )}\n >\n {children}\n </motion.div>\n </DropdownMenuPrimitive.Item>\n </MotionHighlightItem>\n );\n}\n\ntype DropdownMenuCheckboxItemProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.CheckboxItem\n>;\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n disabled,\n ...props\n}: DropdownMenuCheckboxItemProps) {\n return (\n <MotionHighlightItem disabled={disabled}>\n <DropdownMenuPrimitive.CheckboxItem\n {...props}\n checked={checked}\n disabled={disabled}\n asChild\n >\n <motion.div\n data-slot=\"dropdown-menu-checkbox-item\"\n data-disabled={disabled}\n whileTap={{ scale: 0.95 }}\n className={cn(\n \"[&:not([data-highlight])]:focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n >\n <span className=\"absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator data-slot=\"dropdown-menu-checkbox-item-indicator\">\n <Check className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </motion.div>\n </DropdownMenuPrimitive.CheckboxItem>\n </MotionHighlightItem>\n );\n}\n\ntype DropdownMenuRadioItemProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.RadioItem\n>;\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n disabled,\n ...props\n}: DropdownMenuRadioItemProps) {\n return (\n <MotionHighlightItem disabled={disabled}>\n <DropdownMenuPrimitive.RadioItem {...props} disabled={disabled} asChild>\n <motion.div\n data-slot=\"dropdown-menu-radio-item\"\n data-disabled={disabled}\n whileTap={{ scale: 0.95 }}\n className={cn(\n \"[&:not([data-highlight])]:focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator data-slot=\"dropdown-menu-radio-item-indicator\">\n <Circle className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </motion.div>\n </DropdownMenuPrimitive.RadioItem>\n </MotionHighlightItem>\n );\n}\n\ntype DropdownMenuLabelProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Label\n> & {\n inset?: boolean;\n};\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: DropdownMenuLabelProps) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n 'px-2 py-1.5 text-sm font-semibold',\n inset && 'pl-8',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype DropdownMenuSeparatorProps = React.ComponentProps<\n typeof DropdownMenuPrimitive.Separator\n>;\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: DropdownMenuSeparatorProps) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn('-mx-1 my-1 h-px bg-border', className)}\n {...props}\n />\n );\n}\n\ntype DropdownMenuShortcutProps = React.ComponentProps<'span'>;\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: DropdownMenuShortcutProps) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n 'text-muted-foreground ml-auto text-xs tracking-widest',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuGroup,\n DropdownMenuPortal,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuRadioGroup,\n type DropdownMenuProps,\n type DropdownMenuTriggerProps,\n type DropdownMenuContentProps,\n type DropdownMenuItemProps,\n type DropdownMenuCheckboxItemProps,\n type DropdownMenuRadioItemProps,\n type DropdownMenuLabelProps,\n type DropdownMenuSeparatorProps,\n type DropdownMenuShortcutProps,\n type DropdownMenuGroupProps,\n type DropdownMenuPortalProps,\n type DropdownMenuSubProps,\n type DropdownMenuSubContentProps,\n type DropdownMenuSubTriggerProps,\n type DropdownMenuRadioGroupProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/dropdown-menu/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-dropdown-menu';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-dropdown-menu',
},
'radix-hover-card': {
name: 'radix-hover-card',
description:
'For sighted users to preview content available behind a link.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/hover-card/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/hover-card.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { HoverCard as HoverCardPrimitive } from 'radix-ui';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype HoverCardContextType = {\n isOpen: boolean;\n};\n\nconst HoverCardContext = React.createContext<HoverCardContextType | undefined>(\n undefined,\n);\n\nconst useHoverCard = (): HoverCardContextType => {\n const context = React.useContext(HoverCardContext);\n if (!context) {\n throw new Error('useHoverCard must be used within a HoverCard');\n }\n return context;\n};\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n return { x: 15 };\n case 'right':\n return { x: -15 };\n }\n};\n\ntype HoverCardProps = React.ComponentProps<typeof HoverCardPrimitive.Root>;\n\nfunction HoverCard({ children, ...props }: HoverCardProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <HoverCardContext.Provider value={{ isOpen }}>\n <HoverCardPrimitive.Root\n data-slot=\"hover-card\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </HoverCardPrimitive.Root>\n </HoverCardContext.Provider>\n );\n}\n\ntype HoverCardTriggerProps = React.ComponentProps<\n typeof HoverCardPrimitive.Trigger\n>;\n\nfunction HoverCardTrigger(props: HoverCardTriggerProps) {\n return (\n <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n );\n}\n\ntype HoverCardContentProps = React.ComponentProps<\n typeof HoverCardPrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction HoverCardContent({\n className,\n align = 'center',\n side = 'bottom',\n sideOffset = 4,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n children,\n ...props\n}: HoverCardContentProps) {\n const { isOpen } = useHoverCard();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <HoverCardPrimitive.Portal forceMount data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n forceMount\n align={align}\n sideOffset={sideOffset}\n className=\"z-50\"\n {...props}\n >\n <motion.div\n key=\"hover-card-content\"\n data-slot=\"hover-card-content\"\n initial={{ opacity: 0, scale: 0.5, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.5, ...initialPosition }}\n transition={transition}\n className={cn(\n 'w-64 rounded-lg border bg-popover p-4 text-popover-foreground shadow-md outline-none',\n className,\n )}\n {...props}\n >\n {children}\n </motion.div>\n </HoverCardPrimitive.Content>\n </HoverCardPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n HoverCard,\n HoverCardTrigger,\n HoverCardContent,\n useHoverCard,\n type HoverCardContextType,\n type HoverCardProps,\n type HoverCardTriggerProps,\n type HoverCardContentProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/hover-card/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-hover-card';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-hover-card',
},
'radix-popover': {
name: 'radix-popover',
description: 'Displays rich content in a portal, triggered by a button.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/popover/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/popover.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Popover as PopoverPrimitive } from 'radix-ui';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype PopoverContextType = {\n isOpen: boolean;\n};\n\nconst PopoverContext = React.createContext<PopoverContextType | undefined>(\n undefined,\n);\n\nconst usePopover = (): PopoverContextType => {\n const context = React.useContext(PopoverContext);\n if (!context) {\n throw new Error('usePopover must be used within a Popover');\n }\n return context;\n};\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n return { x: 15 };\n case 'right':\n return { x: -15 };\n }\n};\n\ntype PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root>;\n\nfunction Popover({ children, ...props }: PopoverProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <PopoverContext.Provider value={{ isOpen }}>\n <PopoverPrimitive.Root\n data-slot=\"popover\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </PopoverPrimitive.Root>\n </PopoverContext.Provider>\n );\n}\n\ntype PopoverTriggerProps = React.ComponentProps<\n typeof PopoverPrimitive.Trigger\n>;\n\nfunction PopoverTrigger(props: PopoverTriggerProps) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\n\ntype PopoverContentProps = React.ComponentProps<\n typeof PopoverPrimitive.Content\n> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction PopoverContent({\n className,\n align = 'center',\n side = 'bottom',\n sideOffset = 4,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n children,\n ...props\n}: PopoverContentProps) {\n const { isOpen } = usePopover();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <PopoverPrimitive.Portal forceMount data-slot=\"popover-portal\">\n <PopoverPrimitive.Content\n forceMount\n align={align}\n sideOffset={sideOffset}\n className=\"z-50\"\n {...props}\n >\n <motion.div\n key=\"popover-content\"\n data-slot=\"popover-content\"\n initial={{ opacity: 0, scale: 0.5, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0.5, ...initialPosition }}\n transition={transition}\n className={cn(\n 'w-72 rounded-lg border bg-popover p-4 text-popover-foreground shadow-md outline-none',\n className,\n )}\n {...props}\n >\n {children}\n </motion.div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\ntype PopoverAnchorProps = React.ComponentProps<typeof PopoverPrimitive.Anchor>;\n\nfunction PopoverAnchor({ ...props }: PopoverAnchorProps) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\n\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n usePopover,\n type PopoverContextType,\n type PopoverProps,\n type PopoverTriggerProps,\n type PopoverContentProps,\n type PopoverAnchorProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/popover/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-popover';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-popover',
},
'radix-progress': {
name: 'radix-progress',
description:
'Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/progress/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/progress.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Progress as ProgressPrimitive } from 'radix-ui';\nimport { motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\nconst MotionProgressIndicator = motion.create(ProgressPrimitive.Indicator);\n\ntype ProgressProps = React.ComponentProps<typeof ProgressPrimitive.Root> & {\n transition?: Transition;\n};\n\nfunction Progress({\n className,\n value,\n transition = { type: 'spring', stiffness: 100, damping: 30 },\n ...props\n}: ProgressProps) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n className={cn(\n 'relative h-2 w-full overflow-hidden rounded-full bg-secondary',\n className,\n )}\n value={value}\n {...props}\n >\n <MotionProgressIndicator\n data-slot=\"progress-indicator\"\n className=\"h-full w-full flex-1 bg-primary rounded-full\"\n animate={{ x: `-${100 - (value || 0)}%` }}\n transition={transition}\n />\n </ProgressPrimitive.Root>\n );\n}\n\nexport { Progress, type ProgressProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/progress/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-progress';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-progress',
},
'radix-radio-group': {
name: 'radix-radio-group',
description:
'A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/radio-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/radio-group.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { RadioGroup as RadioGroupPrimitive } from 'radix-ui';\nimport { Circle } from 'lucide-react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype RadioGroupProps = React.ComponentProps<typeof RadioGroupPrimitive.Root> & {\n transition?: Transition;\n};\n\nfunction RadioGroup({ className, ...props }: RadioGroupProps) {\n return (\n <RadioGroupPrimitive.Root\n data-slot=\"radio-group\"\n className={cn('grid gap-2.5', className)}\n {...props}\n />\n );\n}\n\ntype RadioGroupIndicatorProps = React.ComponentProps<\n typeof RadioGroupPrimitive.Indicator\n> & {\n transition: Transition;\n};\n\nfunction RadioGroupIndicator({\n className,\n transition,\n ...props\n}: RadioGroupIndicatorProps) {\n return (\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className={cn('flex items-center justify-center', className)}\n {...props}\n >\n <AnimatePresence>\n <motion.div\n key=\"radio-group-indicator-circle\"\n data-slot=\"radio-group-indicator-circle\"\n initial={{ opacity: 0, scale: 0 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0 }}\n transition={transition}\n >\n <Circle className=\"size-3 fill-current text-current\" />\n </motion.div>\n </AnimatePresence>\n </RadioGroupPrimitive.Indicator>\n );\n}\n\ntype RadioGroupItemProps = React.ComponentProps<\n typeof RadioGroupPrimitive.Item\n> &\n HTMLMotionProps<'button'> & {\n transition?: Transition;\n };\n\nfunction RadioGroupItem({\n className,\n transition = { type: 'spring', stiffness: 200, damping: 16 },\n ...props\n}: RadioGroupItemProps) {\n return (\n <RadioGroupPrimitive.Item asChild {...props}>\n <motion.button\n data-slot=\"radio-group-item\"\n className={cn(\n 'aspect-square size-5 rounded-full flex items-center justify-center border border-input text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n {...props}\n >\n <RadioGroupIndicator\n data-slot=\"radio-group-item-indicator\"\n transition={transition}\n />\n </motion.button>\n </RadioGroupPrimitive.Item>\n );\n}\n\nexport {\n RadioGroup,\n RadioGroupItem,\n type RadioGroupProps,\n type RadioGroupItemProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/radio-group/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-radio-group';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-radio-group',
},
'radix-sheet': {
name: 'radix-sheet',
description:
'Extends the Dialog component to display content that complements the main content of the screen.',
type: 'registry:ui',
dependencies: [
'motion',
'class-variance-authority',
'lucide-react',
'radix-ui',
],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/sheet/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/sheet.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Dialog as SheetPrimitive } from 'radix-ui';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\n\ntype SheetContextType = {\n isOpen: boolean;\n};\n\nconst SheetContext = React.createContext<SheetContextType | undefined>(\n undefined,\n);\n\nconst useSheet = (): SheetContextType => {\n const context = React.useContext(SheetContext);\n if (!context) {\n throw new Error('useSheet must be used within a Sheet');\n }\n return context;\n};\n\ntype SheetProps = React.ComponentProps<typeof SheetPrimitive.Root>;\n\nfunction Sheet({ children, ...props }: SheetProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <SheetContext.Provider value={{ isOpen }}>\n <SheetPrimitive.Root\n data-slot=\"sheet\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </SheetPrimitive.Root>\n </SheetContext.Provider>\n );\n}\n\ntype SheetTriggerProps = React.ComponentProps<typeof SheetPrimitive.Trigger>;\n\nfunction SheetTrigger(props: SheetTriggerProps) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\ntype SheetCloseProps = React.ComponentProps<typeof SheetPrimitive.Close>;\n\nfunction SheetClose(props: SheetCloseProps) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\ntype SheetPortalProps = React.ComponentProps<typeof SheetPrimitive.Portal>;\n\nfunction SheetPortal(props: SheetPortalProps) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\ntype SheetOverlayProps = React.ComponentProps<typeof SheetPrimitive.Overlay>;\n\nfunction SheetOverlay({ className, ...props }: SheetOverlayProps) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-50 bg-black/80', className)}\n {...props}\n />\n );\n}\n\nconst sheetVariants = cva('fixed z-50 gap-4 bg-background p-6 shadow-lg', {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b',\n bottom: 'inset-x-0 bottom-0 border-t',\n left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',\n right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',\n },\n },\n defaultVariants: {\n side: 'right',\n },\n});\n\ntype SheetContentProps = React.ComponentProps<typeof SheetPrimitive.Content> &\n VariantProps<typeof sheetVariants> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n overlay?: boolean;\n };\n\nfunction SheetContent({\n side = 'right',\n className,\n transition = { type: 'spring', stiffness: 150, damping: 25 },\n overlay = true,\n children,\n ...props\n}: SheetContentProps) {\n const { isOpen } = useSheet();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <SheetPortal forceMount data-slot=\"sheet-portal\">\n {overlay && (\n <SheetOverlay asChild forceMount>\n <motion.div\n key=\"sheet-overlay\"\n data-slot=\"sheet-overlay\"\n initial={{ opacity: 0, filter: 'blur(4px)' }}\n animate={{ opacity: 1, filter: 'blur(0px)' }}\n exit={{ opacity: 0, filter: 'blur(4px)' }}\n transition={{ duration: 0.2, ease: 'easeInOut' }}\n />\n </SheetOverlay>\n )}\n <SheetPrimitive.Content asChild forceMount {...props}>\n <motion.div\n key=\"sheet-content\"\n data-slot=\"sheet-content\"\n initial={\n side === 'right'\n ? { x: '100%', opacity: 0 }\n : side === 'left'\n ? { x: '-100%', opacity: 0 }\n : side === 'top'\n ? { y: '-100%', opacity: 0 }\n : { y: '100%', opacity: 0 }\n }\n animate={{ x: 0, y: 0, opacity: 1 }}\n exit={\n side === 'right'\n ? { x: '100%', opacity: 0 }\n : side === 'left'\n ? { x: '-100%', opacity: 0 }\n : side === 'top'\n ? { y: '-100%', opacity: 0 }\n : { y: '100%', opacity: 0 }\n }\n transition={transition}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\"\n >\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </motion.div>\n </SheetPrimitive.Content>\n </SheetPortal>\n )}\n </AnimatePresence>\n );\n}\n\ntype SheetHeaderProps = React.ComponentProps<'div'>;\n\nfunction SheetHeader({ className, ...props }: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\n 'flex flex-col space-y-2 text-center sm:text-left',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SheetFooterProps = React.ComponentProps<'div'>;\n\nfunction SheetFooter({ className, ...props }: SheetFooterProps) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SheetTitleProps = React.ComponentProps<typeof SheetPrimitive.Title>;\n\nfunction SheetTitle({ className, ...props }: SheetTitleProps) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('text-lg font-semibold text-foreground', className)}\n {...props}\n />\n );\n}\n\ntype SheetDescriptionProps = React.ComponentProps<\n typeof SheetPrimitive.Description\n>;\n\nfunction SheetDescription({ className, ...props }: SheetDescriptionProps) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n useSheet,\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n type SheetProps,\n type SheetPortalProps,\n type SheetOverlayProps,\n type SheetTriggerProps,\n type SheetCloseProps,\n type SheetContentProps,\n type SheetHeaderProps,\n type SheetFooterProps,\n type SheetTitleProps,\n type SheetDescriptionProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/sheet/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-sheet';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-sheet',
},
'radix-sidebar': {
name: 'radix-sidebar',
description:
'A composable, themeable and customizable sidebar component. Created by Shadcn and animated by Animate UI.',
type: 'registry:ui',
dependencies: [
'radix-ui',
'class-variance-authority',
'lucide-react',
'motion',
],
devDependencies: undefined,
registryDependencies: [
'https://animate-ui.com/r/radix-sheet',
'https://animate-ui.com/r/radix-tooltip',
'https://animate-ui.com/r/motion-highlight',
'use-mobile',
'button',
'input',
'label',
'separator',
'skeleton',
],
files: [
{
path: 'registry/radix/sidebar/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/sidebar.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Slot } from 'radix-ui';\nimport { VariantProps, cva } from 'class-variance-authority';\nimport { PanelLeftIcon } from 'lucide-react';\nimport { type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport { useIsMobile } from '@/hooks/use-mobile';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Separator } from '@/components/ui/separator';\nimport { Skeleton } from '@/components/ui/skeleton';\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from '@/components/animate-ui/radix/sheet';\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/animate-ui/radix/tooltip';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\nconst SIDEBAR_WIDTH = '16rem';\nconst SIDEBAR_WIDTH_MOBILE = '18rem';\nconst SIDEBAR_WIDTH_ICON = '3rem';\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\n\ntype SidebarContextProps = {\n state: 'expanded' | 'collapsed';\n open: boolean;\n setOpen: (open: boolean) => void;\n openMobile: boolean;\n setOpenMobile: (open: boolean) => void;\n isMobile: boolean;\n toggleSidebar: () => void;\n};\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null);\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider.');\n }\n\n return context;\n}\n\ntype SidebarProviderProps = React.ComponentProps<'div'> & {\n defaultOpen?: boolean;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: SidebarProviderProps) {\n const isMobile = useIsMobile();\n const [openMobile, setOpenMobile] = React.useState(false);\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen);\n const open = openProp ?? _open;\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === 'function' ? value(open) : value;\n if (setOpenProp) {\n setOpenProp(openState);\n } else {\n _setOpen(openState);\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\n },\n [setOpenProp, open],\n );\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);\n }, [isMobile, setOpen, setOpenMobile]);\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault();\n toggleSidebar();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [toggleSidebar]);\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? 'expanded' : 'collapsed';\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],\n );\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n '--sidebar-width': SIDEBAR_WIDTH,\n '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n 'group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n );\n}\n\ntype SidebarProps = React.ComponentProps<'div'> & {\n side?: 'left' | 'right';\n variant?: 'sidebar' | 'floating' | 'inset';\n collapsible?: 'offcanvas' | 'icon' | 'none';\n containerClassName?: string;\n animateOnHover?: boolean;\n transition?: Transition;\n};\n\nfunction Sidebar({\n side = 'left',\n variant = 'sidebar',\n collapsible = 'offcanvas',\n className,\n children,\n animateOnHover = true,\n containerClassName,\n transition = { type: 'spring', stiffness: 350, damping: 35 },\n ...props\n}: SidebarProps) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar();\n\n if (collapsible === 'none') {\n return (\n <MotionHighlight\n enabled={animateOnHover}\n hover\n controlledItems\n mode=\"parent\"\n containerClassName={containerClassName}\n transition={transition}\n >\n <div\n data-slot=\"sidebar\"\n className={cn(\n 'bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </MotionHighlight>\n );\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden\"\n style={\n {\n '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <MotionHighlight\n enabled={animateOnHover}\n hover\n controlledItems\n mode=\"parent\"\n containerClassName={cn('h-full', containerClassName)}\n transition={transition}\n >\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </MotionHighlight>\n </SheetContent>\n </Sheet>\n );\n }\n\n return (\n <div\n className=\"group peer text-sidebar-foreground hidden md:block\"\n data-state={state}\n data-collapsible={state === 'collapsed' ? collapsible : ''}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-400 ease-[cubic-bezier(0.7,-0.15,0.25,1.15)]',\n 'group-data-[collapsible=offcanvas]:w-0',\n 'group-data-[side=right]:rotate-180',\n variant === 'floating' || variant === 'inset'\n ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n 'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-400 ease-[cubic-bezier(0.75,0,0.25,1)] md:flex',\n side === 'left'\n ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n // Adjust the padding for floating and inset variants.\n variant === 'floating' || variant === 'inset'\n ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'\n : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',\n className,\n )}\n {...props}\n >\n <MotionHighlight\n containerClassName={cn('size-full', containerClassName)}\n enabled={animateOnHover}\n hover\n controlledItems\n mode=\"parent\"\n forceUpdateBounds\n transition={transition}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"bg-sidebar group-data-[variant=floating]:border-sidebar-border flex size-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </MotionHighlight>\n </div>\n </div>\n );\n}\n\ntype SidebarTriggerProps = React.ComponentProps<typeof Button>;\n\nfunction SidebarTrigger({ className, onClick, ...props }: SidebarTriggerProps) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('size-7', className)}\n onClick={(event) => {\n onClick?.(event);\n toggleSidebar();\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n );\n}\n\ntype SidebarRailProps = React.ComponentProps<'button'>;\n\nfunction SidebarRail({ className, ...props }: SidebarRailProps) {\n const { toggleSidebar } = useSidebar();\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n 'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',\n 'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\n '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n 'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',\n '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarInsetProps = React.ComponentProps<'main'>;\n\nfunction SidebarInset({ className, ...props }: SidebarInsetProps) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n 'bg-background relative flex w-full flex-1 flex-col',\n 'md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarInputProps = React.ComponentProps<typeof Input>;\n\nfunction SidebarInput({ className, ...props }: SidebarInputProps) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn('bg-background h-8 w-full shadow-none', className)}\n {...props}\n />\n );\n}\n\ntype SidebarHeaderProps = React.ComponentProps<'div'>;\n\nfunction SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n}\n\ntype SidebarFooterProps = React.ComponentProps<'div'>;\n\nfunction SidebarFooter({ className, ...props }: SidebarFooterProps) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n}\n\ntype SidebarSeparatorProps = React.ComponentProps<typeof Separator>;\n\nfunction SidebarSeparator({ className, ...props }: SidebarSeparatorProps) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn('bg-sidebar-border mx-2 w-auto', className)}\n {...props}\n />\n );\n}\n\ntype SidebarContentProps = React.ComponentProps<'div'>;\n\nfunction SidebarContent({ className, ...props }: SidebarContentProps) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n 'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarGroupProps = React.ComponentProps<'div'>;\n\nfunction SidebarGroup({ className, ...props }: SidebarGroupProps) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn('relative flex w-full min-w-0 flex-col p-2', className)}\n {...props}\n />\n );\n}\n\ntype SidebarGroupLabelProps = React.ComponentProps<'div'> & {\n asChild?: boolean;\n};\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: SidebarGroupLabelProps) {\n const Comp = asChild ? Slot.Root : 'div';\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n 'text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-300 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarGroupActionProps = React.ComponentProps<'button'> & {\n asChild?: boolean;\n};\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: SidebarGroupActionProps) {\n const Comp = asChild ? Slot.Root : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n // Increases the hit area of the button on mobile.\n 'after:absolute after:-inset-2 md:after:hidden',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarGroupContentProps = React.ComponentProps<'div'>;\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: SidebarGroupContentProps) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn('w-full text-sm', className)}\n {...props}\n />\n );\n}\n\ntype SidebarMenuProps = React.ComponentProps<'ul'>;\n\nfunction SidebarMenu({ className, ...props }: SidebarMenuProps) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn('flex w-full min-w-0 flex-col gap-1', className)}\n {...props}\n />\n );\n}\n\ntype SidebarMenuItemProps = React.ComponentProps<'li'>;\n\nfunction SidebarMenuItem({ className, ...props }: SidebarMenuItemProps) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn('group/menu-item relative', className)}\n {...props}\n />\n );\n}\n\nconst sidebarMenuButtonActiveVariants = cva(\n 'bg-sidebar-accent text-sidebar-accent-foreground rounded-md',\n {\n variants: {\n variant: {\n default: 'bg-sidebar-accent text-sidebar-accent-foreground',\n outline:\n 'bg-sidebar-accent text-sidebar-accent-foreground shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst sidebarMenuButtonVariants = cva(\n 'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] [&:not([data-highlight])]:hover:bg-sidebar-accent [&:not([data-highlight])]:hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground [&:not([data-highlight])]:data-[state=open]:hover:bg-sidebar-accent [&:not([data-highlight])]:data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n {\n variants: {\n variant: {\n default:\n '[&:not([data-highlight])]:hover:bg-sidebar-accent [&:not([data-highlight])]:hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] [&:not([data-highlight])]:hover:bg-sidebar-accent [&:not([data-highlight])]:hover:text-sidebar-accent-foreground [&:not([data-highlight])]:hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype SidebarMenuButtonProps = React.ComponentProps<'button'> & {\n asChild?: boolean;\n isActive?: boolean;\n tooltip?: string | React.ComponentProps<typeof TooltipContent>;\n} & VariantProps<typeof sidebarMenuButtonVariants>;\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = 'default',\n size = 'default',\n tooltip,\n className,\n ...props\n}: SidebarMenuButtonProps) {\n const Comp = asChild ? Slot.Root : 'button';\n const { isMobile, state } = useSidebar();\n\n const button = (\n <MotionHighlightItem\n activeClassName={sidebarMenuButtonActiveVariants({ variant })}\n >\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n </MotionHighlightItem>\n );\n\n if (!tooltip) {\n return button;\n }\n\n if (typeof tooltip === 'string') {\n tooltip = {\n children: tooltip,\n };\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== 'collapsed' || isMobile}\n {...tooltip}\n />\n </Tooltip>\n );\n}\n\ntype SidebarMenuActionProps = React.ComponentProps<'button'> & {\n asChild?: boolean;\n showOnHover?: boolean;\n};\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: SidebarMenuActionProps) {\n const Comp = asChild ? Slot.Root : 'button';\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n // Increases the hit area of the button on mobile.\n 'z-[1] text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n 'after:absolute after:-inset-2 md:after:hidden',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n showOnHover &&\n 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarMenuBadgeProps = React.ComponentProps<'div'>;\n\nfunction SidebarMenuBadge({ className, ...props }: SidebarMenuBadgeProps) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n 'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',\n 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n 'peer-data-[size=sm]/menu-button:top-1',\n 'peer-data-[size=default]/menu-button:top-1.5',\n 'peer-data-[size=lg]/menu-button:top-2.5',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarMenuSkeletonProps = React.ComponentProps<'div'> & {\n showIcon?: boolean;\n};\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: SidebarMenuSkeletonProps) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`;\n }, []);\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n '--skeleton-width': width,\n } as React.CSSProperties\n }\n />\n </div>\n );\n}\n\ntype SidebarMenuSubProps = React.ComponentProps<'ul'>;\n\nfunction SidebarMenuSub({ className, ...props }: SidebarMenuSubProps) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n 'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SidebarMenuSubItemProps = React.ComponentProps<'li'>;\n\nfunction SidebarMenuSubItem({ className, ...props }: SidebarMenuSubItemProps) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn('group/menu-sub-item relative', className)}\n {...props}\n />\n );\n}\n\ntype SidebarMenuSubButtonProps = React.ComponentProps<'a'> & {\n asChild?: boolean;\n size?: 'sm' | 'md';\n isActive?: boolean;\n};\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = 'md',\n isActive = false,\n className,\n ...props\n}: SidebarMenuSubButtonProps) {\n const Comp = asChild ? Slot.Root : 'a';\n\n return (\n <MotionHighlightItem activeClassName=\"bg-sidebar-accent text-sidebar-accent-foreground rounded-md\">\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n 'text-sidebar-foreground ring-sidebar-ring [&:not([data-highlight])]:hover:bg-sidebar-accent [&:not([data-highlight])]:hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n 'group-data-[collapsible=icon]:hidden',\n className,\n )}\n {...props}\n />\n </MotionHighlightItem>\n );\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n type SidebarProps,\n type SidebarContentProps,\n type SidebarFooterProps,\n type SidebarGroupProps,\n type SidebarGroupActionProps,\n type SidebarGroupContentProps,\n type SidebarGroupLabelProps,\n type SidebarHeaderProps,\n type SidebarInputProps,\n type SidebarInsetProps,\n type SidebarMenuProps,\n type SidebarMenuActionProps,\n type SidebarMenuBadgeProps,\n type SidebarMenuButtonProps,\n type SidebarMenuItemProps,\n type SidebarMenuSkeletonProps,\n type SidebarMenuSubProps,\n type SidebarMenuSubItemProps,\n type SidebarMenuSubButtonProps,\n type SidebarProviderProps,\n type SidebarRailProps,\n type SidebarSeparatorProps,\n type SidebarTriggerProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/sidebar/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-sidebar';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-sidebar',
},
'radix-switch': {
name: 'radix-switch',
description:
'A control that allows the user to toggle between checked and not checked.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/switch/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/switch.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Switch as SwitchPrimitives } from 'radix-ui';\nimport { motion, type HTMLMotionProps } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype SwitchProps = React.ComponentProps<typeof SwitchPrimitives.Root> &\n HTMLMotionProps<'button'> & {\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n thumbIcon?: React.ReactNode;\n };\n\nfunction Switch({\n className,\n leftIcon,\n rightIcon,\n thumbIcon,\n onCheckedChange,\n ...props\n}: SwitchProps) {\n const [isChecked, setIsChecked] = React.useState(\n props?.checked ?? props?.defaultChecked ?? false,\n );\n const [isTapped, setIsTapped] = React.useState(false);\n\n React.useEffect(() => {\n if (props?.checked !== undefined) setIsChecked(props.checked);\n }, [props?.checked]);\n\n const handleCheckedChange = React.useCallback(\n (checked: boolean) => {\n setIsChecked(checked);\n onCheckedChange?.(checked);\n },\n [onCheckedChange],\n );\n\n return (\n <SwitchPrimitives.Root\n {...props}\n onCheckedChange={handleCheckedChange}\n asChild\n >\n <motion.button\n data-slot=\"switch\"\n className={cn(\n 'relative flex p-[3px] h-6 w-10 shrink-0 cursor-pointer items-center rounded-full transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input data-[state=checked]:justify-end data-[state=unchecked]:justify-start',\n className,\n )}\n whileTap=\"tap\"\n initial={false}\n onTapStart={() => setIsTapped(true)}\n onTapCancel={() => setIsTapped(false)}\n onTap={() => setIsTapped(false)}\n {...props}\n >\n {leftIcon && (\n <motion.div\n data-slot=\"switch-left-icon\"\n animate={\n isChecked ? { scale: 1, opacity: 1 } : { scale: 0, opacity: 0 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute [&_svg]:size-3 left-1 top-1/2 -translate-y-1/2 dark:text-neutral-500 text-neutral-400\"\n >\n {typeof leftIcon !== 'string' ? leftIcon : null}\n </motion.div>\n )}\n\n {rightIcon && (\n <motion.div\n data-slot=\"switch-right-icon\"\n animate={\n isChecked ? { scale: 0, opacity: 0 } : { scale: 1, opacity: 1 }\n }\n transition={{ type: 'spring', bounce: 0 }}\n className=\"absolute [&_svg]:size-3 right-1 top-1/2 -translate-y-1/2 dark:text-neutral-400 text-neutral-500\"\n >\n {typeof rightIcon !== 'string' ? rightIcon : null}\n </motion.div>\n )}\n\n <SwitchPrimitives.Thumb asChild>\n <motion.div\n data-slot=\"switch-thumb\"\n whileTap=\"tab\"\n className={cn(\n 'relative z-[1] [&_svg]:size-3 flex items-center justify-center rounded-full bg-background shadow-lg ring-0 dark:text-neutral-400 text-neutral-500',\n )}\n layout\n transition={{ type: 'spring', stiffness: 300, damping: 25 }}\n style={{\n width: 18,\n height: 18,\n }}\n animate={\n isTapped\n ? { width: 21, transition: { duration: 0.1 } }\n : { width: 18, transition: { duration: 0.1 } }\n }\n >\n {thumbIcon && typeof thumbIcon !== 'string' ? thumbIcon : null}\n </motion.div>\n </SwitchPrimitives.Thumb>\n </motion.button>\n </SwitchPrimitives.Root>\n );\n}\n\nexport { Switch, type SwitchProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/switch/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-switch';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-switch',
},
'radix-tabs': {
name: 'radix-tabs',
description:
'A set of layered sections of content—known as tab panels—that are displayed one at a time.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/motion-highlight'],
files: [
{
path: 'registry/radix/tabs/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/tabs.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { type HTMLMotionProps, type Transition, motion } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\nimport {\n MotionHighlight,\n MotionHighlightItem,\n} from '@/components/animate-ui/effects/motion-highlight';\n\ntype TabsProps = React.ComponentProps<typeof TabsPrimitive.Root>;\n\nfunction Tabs({ className, ...props }: TabsProps) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n className={cn('flex flex-col gap-2', className)}\n {...props}\n />\n );\n}\n\ntype TabsListProps = React.ComponentProps<typeof TabsPrimitive.List> & {\n activeClassName?: string;\n transition?: Transition;\n};\n\nfunction TabsList({\n ref,\n children,\n className,\n activeClassName,\n transition = {\n type: 'spring',\n stiffness: 200,\n damping: 25,\n },\n ...props\n}: TabsListProps) {\n const localRef = React.useRef<HTMLDivElement | null>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const [activeValue, setActiveValue] = React.useState<string | undefined>(\n undefined,\n );\n\n const getActiveValue = React.useCallback(() => {\n if (!localRef.current) return;\n const activeTab = localRef.current.querySelector<HTMLElement>(\n '[data-state=\"active\"]',\n );\n if (!activeTab) return;\n setActiveValue(activeTab.getAttribute('data-value') ?? undefined);\n }, []);\n\n React.useEffect(() => {\n getActiveValue();\n\n const observer = new MutationObserver(getActiveValue);\n\n if (localRef.current) {\n observer.observe(localRef.current, {\n attributes: true,\n childList: true,\n subtree: true,\n });\n }\n\n return () => {\n observer.disconnect();\n };\n }, [getActiveValue]);\n\n return (\n <MotionHighlight\n controlledItems\n className={cn('rounded-sm bg-background shadow-sm', activeClassName)}\n value={activeValue}\n transition={transition}\n >\n <TabsPrimitive.List\n ref={localRef}\n data-slot=\"tabs-list\"\n className={cn(\n 'bg-muted text-muted-foreground inline-flex h-10 w-fit items-center justify-center rounded-lg p-[4px]',\n className,\n )}\n {...props}\n >\n {children}\n </TabsPrimitive.List>\n </MotionHighlight>\n );\n}\n\ntype TabsTriggerProps = React.ComponentProps<typeof TabsPrimitive.Trigger>;\n\nfunction TabsTrigger({ className, value, ...props }: TabsTriggerProps) {\n return (\n <MotionHighlightItem value={value} className=\"size-full\">\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n 'inline-flex cursor-pointer items-center size-full justify-center whitespace-nowrap rounded-sm px-2 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:text-foreground z-[1]',\n className,\n )}\n value={value}\n {...props}\n />\n </MotionHighlightItem>\n );\n}\n\ntype TabsContentProps = React.ComponentProps<typeof TabsPrimitive.Content> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n };\n\nfunction TabsContent({\n className,\n children,\n transition = {\n duration: 0.5,\n ease: 'easeInOut',\n },\n ...props\n}: TabsContentProps) {\n return (\n <TabsPrimitive.Content asChild {...props}>\n <motion.div\n data-slot=\"tabs-content\"\n className={cn('flex-1 outline-none', className)}\n layout\n initial={{ opacity: 0, y: -10, filter: 'blur(4px)' }}\n animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}\n exit={{ opacity: 0, y: 10, filter: 'blur(4px)' }}\n transition={transition}\n {...props}\n >\n {children}\n </motion.div>\n </TabsPrimitive.Content>\n );\n}\n\ntype TabsContentsProps = HTMLMotionProps<'div'> & {\n children: React.ReactNode;\n className?: string;\n transition?: Transition;\n};\n\nfunction TabsContents({\n children,\n className,\n transition = { type: 'spring', stiffness: 200, damping: 25 },\n ...props\n}: TabsContentsProps) {\n const containerRef = React.useRef<HTMLDivElement | null>(null);\n\n const [height, setHeight] = React.useState(0);\n\n React.useEffect(() => {\n if (!containerRef.current) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n const newHeight = entries?.[0]?.contentRect.height;\n if (!newHeight) return;\n requestAnimationFrame(() => {\n setHeight(newHeight);\n });\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [children]);\n\n React.useLayoutEffect(() => {\n if (containerRef.current) {\n const initialHeight = containerRef.current.getBoundingClientRect().height;\n setHeight(initialHeight);\n }\n }, [children]);\n\n return (\n <motion.div\n data-slot=\"tabs-contents\"\n layout\n animate={{ height: height }}\n transition={transition}\n className={className}\n {...props}\n >\n <div ref={containerRef}>{children}</div>\n </motion.div>\n );\n}\n\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n TabsContents,\n type TabsProps,\n type TabsListProps,\n type TabsTriggerProps,\n type TabsContentProps,\n type TabsContentsProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/tabs/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-tabs';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-tabs',
},
'radix-toggle-group': {
name: 'radix-toggle-group',
description: 'A set of two-state buttons that can be toggled on or off.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui', 'class-variance-authority'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/toggle-group/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/toggle-group.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';\nimport {\n type HTMLMotionProps,\n type Transition,\n motion,\n AnimatePresence,\n} from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst toggleVariants = cva(\n \"cursor-pointer inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:text-muted-foreground text-accent-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none focus:outline-none aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap\",\n {\n variants: {\n type: {\n single: '',\n multiple: 'data-[state=on]:bg-accent',\n },\n variant: {\n default: 'bg-transparent',\n outline: 'border border-input bg-transparent shadow-xs',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype ToggleGroupContextProps = VariantProps<typeof toggleVariants> & {\n type?: 'single' | 'multiple';\n transition?: Transition;\n activeClassName?: string;\n globalId: string;\n};\n\nconst ToggleGroupContext = React.createContext<\n ToggleGroupContextProps | undefined\n>(undefined);\n\nconst useToggleGroup = (): ToggleGroupContextProps => {\n const context = React.useContext(ToggleGroupContext);\n if (!context) {\n throw new Error('useToggleGroup must be used within a ToggleGroup');\n }\n return context;\n};\n\ntype ToggleGroupProps = React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n transition?: Transition;\n activeClassName?: string;\n };\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n transition = { type: 'spring', bounce: 0, stiffness: 200, damping: 25 },\n activeClassName,\n ...props\n}: ToggleGroupProps) {\n const globalId = React.useId();\n\n return (\n <ToggleGroupContext.Provider\n value={{\n variant,\n size,\n type: props.type,\n transition,\n activeClassName,\n globalId,\n }}\n >\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n className={cn(\n 'flex items-center justify-center gap-1 relative',\n className,\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Root>\n </ToggleGroupContext.Provider>\n );\n}\n\ntype ToggleGroupItemProps = React.ComponentProps<\n typeof ToggleGroupPrimitive.Item\n> &\n Omit<VariantProps<typeof toggleVariants>, 'type'> & {\n children?: React.ReactNode;\n buttonProps?: HTMLMotionProps<'button'>;\n spanProps?: React.ComponentProps<'span'>;\n };\n\nfunction ToggleGroupItem({\n ref,\n className,\n children,\n variant,\n size,\n buttonProps,\n spanProps,\n ...props\n}: ToggleGroupItemProps) {\n const {\n activeClassName,\n transition,\n type,\n variant: contextVariant,\n size: contextSize,\n globalId,\n } = useToggleGroup();\n const itemRef = React.useRef<HTMLButtonElement | null>(null);\n React.useImperativeHandle(ref, () => itemRef.current as HTMLButtonElement);\n const [isActive, setIsActive] = React.useState(false);\n\n React.useEffect(() => {\n const node = itemRef.current;\n if (!node) return;\n const observer = new MutationObserver(() => {\n setIsActive(node.getAttribute('data-state') === 'on');\n });\n observer.observe(node, {\n attributes: true,\n attributeFilter: ['data-state'],\n });\n setIsActive(node.getAttribute('data-state') === 'on');\n return () => observer.disconnect();\n }, []);\n\n return (\n <ToggleGroupPrimitive.Item ref={itemRef} {...props} asChild>\n <motion.button\n data-slot=\"toggle-group-item\"\n initial={{ scale: 1 }}\n whileTap={{ scale: 0.9 }}\n {...buttonProps}\n className={cn('relative', buttonProps?.className)}\n >\n <span\n {...spanProps}\n data-state={isActive ? 'on' : 'off'}\n className={cn(\n 'relative z-[1]',\n toggleVariants({\n variant: variant || contextVariant,\n size: size || contextSize,\n type,\n }),\n className,\n spanProps?.className,\n )}\n >\n {children}\n </span>\n\n <AnimatePresence initial={false}>\n {isActive && type === 'single' && (\n <motion.span\n layoutId={`active-toggle-group-item-${globalId}`}\n data-slot=\"active-toggle-group-item\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={transition}\n className={cn(\n 'absolute inset-0 z-0 rounded-md bg-muted',\n activeClassName,\n )}\n />\n )}\n </AnimatePresence>\n </motion.button>\n </ToggleGroupPrimitive.Item>\n );\n}\n\nexport {\n ToggleGroup,\n ToggleGroupItem,\n type ToggleGroupProps,\n type ToggleGroupItemProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/toggle-group/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-toggle-group';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-toggle-group',
},
'radix-tooltip': {
name: 'radix-tooltip',
description:
'A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.',
type: 'registry:ui',
dependencies: ['motion', 'radix-ui'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/radix/tooltip/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/radix/tooltip.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { AnimatePresence, motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype TooltipContextType = {\n isOpen: boolean;\n};\n\nconst TooltipContext = React.createContext<TooltipContextType | undefined>(\n undefined,\n);\n\nconst useTooltip = (): TooltipContextType => {\n const context = React.useContext(TooltipContext);\n if (!context) {\n throw new Error('useTooltip must be used within a Tooltip');\n }\n return context;\n};\n\ntype Side = 'top' | 'bottom' | 'left' | 'right';\n\nconst getInitialPosition = (side: Side) => {\n switch (side) {\n case 'top':\n return { y: 15 };\n case 'bottom':\n return { y: -15 };\n case 'left':\n return { x: 15 };\n case 'right':\n return { x: -15 };\n }\n};\n\ntype TooltipProviderProps = React.ComponentProps<\n typeof TooltipPrimitive.Provider\n>;\n\nfunction TooltipProvider(props: TooltipProviderProps) {\n return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" {...props} />;\n}\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>;\n\nfunction Tooltip(props: TooltipProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <TooltipContext.Provider value={{ isOpen }}>\n <TooltipPrimitive.Root\n data-slot=\"tooltip\"\n {...props}\n onOpenChange={handleOpenChange}\n />\n </TooltipContext.Provider>\n );\n}\n\ntype TooltipTriggerProps = React.ComponentProps<\n typeof TooltipPrimitive.Trigger\n>;\n\nfunction TooltipTrigger(props: TooltipTriggerProps) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\ntype TooltipContentProps = React.ComponentProps<\n typeof TooltipPrimitive.Content\n> & {\n transition?: Transition;\n arrow?: boolean;\n};\n\nfunction TooltipContent({\n className,\n side = 'top',\n sideOffset = 4,\n transition = { type: 'spring', stiffness: 300, damping: 25 },\n arrow = true,\n children,\n ...props\n}: TooltipContentProps) {\n const { isOpen } = useTooltip();\n const initialPosition = getInitialPosition(side);\n\n return (\n <AnimatePresence>\n {isOpen && (\n <TooltipPrimitive.Portal forceMount data-slot=\"tooltip-portal\">\n <TooltipPrimitive.Content\n forceMount\n sideOffset={sideOffset}\n className=\"z-50\"\n {...props}\n >\n <motion.div\n key=\"tooltip-content\"\n data-slot=\"tooltip-content\"\n initial={{ opacity: 0, scale: 0, ...initialPosition }}\n animate={{ opacity: 1, scale: 1, x: 0, y: 0 }}\n exit={{ opacity: 0, scale: 0, ...initialPosition }}\n transition={transition}\n className={cn(\n 'relative bg-primary text-primary-foreground shadow-md w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-sm text-balance',\n className,\n )}\n >\n {children}\n\n {arrow && (\n <TooltipPrimitive.Arrow\n data-slot=\"tooltip-content-arrow\"\n className=\"bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]\"\n />\n )}\n </motion.div>\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )}\n </AnimatePresence>\n );\n}\n\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n useTooltip,\n type TooltipContextType,\n type TooltipProps,\n type TooltipTriggerProps,\n type TooltipContentProps,\n type TooltipProviderProps,\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/radix/tooltip/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'radix-tooltip';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/radix-tooltip',
},
'counting-number': {
name: 'counting-number',
description:
'A numeric display component that smoothly animates number changes with a counting animation.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/counting-number/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/counting-number.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n type SpringOptions,\n type UseInViewOptions,\n useInView,\n useMotionValue,\n useSpring,\n} from 'motion/react';\n\ntype CountingNumberProps = React.ComponentProps<'span'> & {\n number: number;\n fromNumber?: number;\n padStart?: boolean;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n decimalSeparator?: string;\n transition?: SpringOptions;\n decimalPlaces?: number;\n};\n\nfunction CountingNumber({\n ref,\n number,\n fromNumber = 0,\n padStart = false,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n decimalSeparator = '.',\n transition = { stiffness: 90, damping: 50 },\n decimalPlaces = 0,\n className,\n ...props\n}: CountingNumberProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLSpanElement);\n\n const numberStr = number.toString();\n const decimals =\n typeof decimalPlaces === 'number'\n ? decimalPlaces\n : numberStr.includes('.')\n ? (numberStr.split('.')[1]?.length ?? 0)\n : 0;\n\n const motionVal = useMotionValue(fromNumber);\n const springVal = useSpring(motionVal, transition);\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n React.useEffect(() => {\n if (isInView) motionVal.set(number);\n }, [isInView, number, motionVal]);\n\n React.useEffect(() => {\n const unsubscribe = springVal.on('change', (latest) => {\n if (localRef.current) {\n let formatted =\n decimals > 0\n ? latest.toFixed(decimals)\n : Math.round(latest).toString();\n\n if (decimals > 0) {\n formatted = formatted.replace('.', decimalSeparator);\n }\n\n if (padStart) {\n const finalIntLength = Math.floor(Math.abs(number)).toString().length;\n const [intPart, fracPart] = formatted.split(decimalSeparator);\n const paddedInt = intPart?.padStart(finalIntLength, '0') ?? '';\n formatted = fracPart\n ? `${paddedInt}${decimalSeparator}${fracPart}`\n : paddedInt;\n }\n\n localRef.current.textContent = formatted;\n }\n });\n return () => unsubscribe();\n }, [springVal, decimals, padStart, number, decimalSeparator]);\n\n const finalIntLength = Math.floor(Math.abs(number)).toString().length;\n const initialText = padStart\n ? '0'.padStart(finalIntLength, '0') +\n (decimals > 0 ? decimalSeparator + '0'.repeat(decimals) : '')\n : '0' + (decimals > 0 ? decimalSeparator + '0'.repeat(decimals) : '');\n\n return (\n <span\n ref={localRef}\n data-slot=\"counting-number\"\n className={className}\n {...props}\n >\n {initialText}\n </span>\n );\n}\n\nexport { CountingNumber, type CountingNumberProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/counting-number/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'counting-number';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/counting-number',
},
'gradient-text': {
name: 'gradient-text',
description:
'A text component featuring a smoothly animated gradient effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/gradient/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/gradient.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype GradientTextProps = React.ComponentProps<'span'> & {\n text: string;\n gradient?: string;\n neon?: boolean;\n transition?: Transition;\n};\n\nfunction GradientText({\n text,\n className,\n gradient = 'linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)',\n neon = false,\n transition = { duration: 50, repeat: Infinity, ease: 'linear' },\n ...props\n}: GradientTextProps) {\n const baseStyle: React.CSSProperties = {\n backgroundImage: gradient,\n };\n\n return (\n <span\n data-slot=\"gradient-text\"\n className={cn('relative inline-block', className)}\n {...props}\n >\n <motion.span\n className=\"m-0 text-transparent bg-clip-text bg-[length:700%_100%] bg-[position:0%_0%]\"\n style={baseStyle}\n initial={{ backgroundPosition: '0% 0%' }}\n animate={{ backgroundPosition: '500% 100%' }}\n transition={transition}\n >\n {text}\n </motion.span>\n\n {neon && (\n <motion.span\n className=\"m-0 absolute top-0 left-0 text-transparent bg-clip-text blur-[8px] mix-blend-plus-lighter bg-[length:700%_100%] bg-[position:0%_0%]\"\n style={baseStyle}\n initial={{ backgroundPosition: '0% 0%' }}\n animate={{ backgroundPosition: '500% 100%' }}\n transition={transition}\n >\n {text}\n </motion.span>\n )}\n </span>\n );\n}\n\nexport { GradientText, type GradientTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/gradient/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'gradient-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/gradient-text',
},
'highlight-text': {
name: 'highlight-text',
description:
'A text component that smoothly reveals an animated highlight effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/highlight/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/highlight.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n useInView,\n type HTMLMotionProps,\n type Transition,\n type UseInViewOptions,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype HighlightTextProps = HTMLMotionProps<'span'> & {\n text: string;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n transition?: Transition;\n};\n\nfunction HighlightText({\n ref,\n text,\n className,\n inView = false,\n inViewMargin = '0px',\n transition = { duration: 2, ease: 'easeInOut' },\n ...props\n}: HighlightTextProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLSpanElement);\n\n const inViewResult = useInView(localRef, {\n once: true,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n return (\n <motion.span\n ref={localRef}\n data-slot=\"highlight-text\"\n initial={{\n backgroundSize: '0% 100%',\n }}\n animate={isInView ? { backgroundSize: '100% 100%' } : undefined}\n transition={transition}\n style={{\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'left center',\n display: 'inline',\n }}\n className={cn(\n `relative inline-block px-2 py-1 rounded-lg bg-gradient-to-r from-blue-100 to-purple-100 dark:from-blue-500 dark:to-purple-500`,\n className,\n )}\n {...props}\n >\n {text}\n </motion.span>\n );\n}\n\nexport { HighlightText, type HighlightTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/highlight/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'highlight-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/highlight-text',
},
'rolling-text': {
name: 'rolling-text',
description:
'A text component that reveals content through an engaging rolling animation.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/rolling/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/rolling.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n useInView,\n type UseInViewOptions,\n type Transition,\n} from 'motion/react';\n\nconst ENTRY_ANIMATION = {\n initial: { rotateX: 0 },\n animate: { rotateX: 90 },\n};\n\nconst EXIT_ANIMATION = {\n initial: { rotateX: 90 },\n animate: { rotateX: 0 },\n};\n\nconst formatCharacter = (char: string) => (char === ' ' ? '\\u00A0' : char);\n\ntype RollingTextProps = Omit<React.ComponentProps<'span'>, 'children'> & {\n transition?: Transition;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n text: string;\n};\n\nfunction RollingText({\n ref,\n transition = { duration: 0.5, delay: 0.1, ease: 'easeOut' },\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n text,\n ...props\n}: RollingTextProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current!);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const characters = React.useMemo(() => text.split(''), [text]);\n\n return (\n <span data-slot=\"rolling-text\" {...props} ref={ref}>\n {characters.map((char, idx) => (\n <span\n key={idx}\n className=\"relative inline-block perspective-[9999999px] transform-3d w-auto\"\n aria-hidden=\"true\"\n >\n <motion.span\n className=\"absolute inline-block backface-hidden origin-[50%_25%]\"\n initial={ENTRY_ANIMATION.initial}\n animate={isInView ? ENTRY_ANIMATION.animate : undefined}\n transition={{\n ...transition,\n delay: idx * (transition?.delay ?? 0),\n }}\n >\n {formatCharacter(char)}\n </motion.span>\n <motion.span\n className=\"absolute inline-block backface-hidden origin-[50%_100%]\"\n initial={EXIT_ANIMATION.initial}\n animate={isInView ? EXIT_ANIMATION.animate : undefined}\n transition={{\n ...transition,\n delay: idx * (transition?.delay ?? 0) + 0.3,\n }}\n >\n {formatCharacter(char)}\n </motion.span>\n <span className=\"invisible\">{formatCharacter(char)}</span>\n </span>\n ))}\n\n <span className=\"sr-only\">{text}</span>\n </span>\n );\n}\n\nexport { RollingText, type RollingTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/rolling/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rolling-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rolling-text',
},
'rotating-text': {
name: 'rotating-text',
description:
'A text component that smoothly animates text changes with a rotating transition effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/rotating/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/rotating.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype RotatingTextProps = {\n text: string | string[];\n duration?: number;\n transition?: Transition;\n y?: number;\n containerClassName?: string;\n} & HTMLMotionProps<'div'>;\n\nfunction RotatingText({\n text,\n y = -50,\n duration = 2000,\n transition = { duration: 0.3, ease: 'easeOut' },\n containerClassName,\n ...props\n}: RotatingTextProps) {\n const [index, setIndex] = React.useState(0);\n\n React.useEffect(() => {\n if (!Array.isArray(text)) return;\n const interval = setInterval(() => {\n setIndex((prevIndex) => (prevIndex + 1) % text.length);\n }, duration);\n return () => clearInterval(interval);\n }, [text, duration]);\n\n const currentText = Array.isArray(text) ? text[index] : text;\n\n return (\n <div className={cn('overflow-hidden py-1', containerClassName)}>\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={currentText}\n transition={transition}\n initial={{ opacity: 0, y: -y }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y }}\n {...props}\n >\n {currentText}\n </motion.div>\n </AnimatePresence>\n </div>\n );\n}\n\nexport { RotatingText, type RotatingTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/rotating/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'rotating-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/rotating-text',
},
'shimmering-text': {
name: 'shimmering-text',
description:
'A text component that smoothly animates text with a shimmering effect.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/shimmering/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/shimmering.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { type HTMLMotionProps, motion, type Transition } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\ntype ShimmeringTextProps = {\n text: string;\n duration?: number;\n transition?: Transition;\n wave?: boolean;\n color?: string;\n shimmeringColor?: string;\n} & Omit<HTMLMotionProps<'span'>, 'children'>;\n\nfunction ShimmeringText({\n text,\n duration = 1,\n transition,\n wave = false,\n className,\n color = 'var(--color-neutral-500)',\n shimmeringColor = 'var(--color-neutral-300)',\n ...props\n}: ShimmeringTextProps) {\n return (\n <motion.span\n className={cn('relative inline-block [perspective:500px]', className)}\n style={\n {\n '--shimmering-color': shimmeringColor,\n '--color': color,\n color: 'var(--color)',\n } as React.CSSProperties\n }\n {...props}\n >\n {text?.split('')?.map((char, i) => (\n <motion.span\n key={i}\n className=\"inline-block whitespace-pre [transform-style:preserve-3d]\"\n initial={{\n ...(wave\n ? {\n scale: 1,\n rotateY: 0,\n }\n : {}),\n color: 'var(--color)',\n }}\n animate={{\n ...(wave\n ? {\n x: [0, 5, 0],\n y: [0, -5, 0],\n scale: [1, 1.1, 1],\n rotateY: [0, 15, 0],\n }\n : {}),\n color: ['var(--color)', 'var(--shimmering-color)', 'var(--color)'],\n }}\n transition={{\n duration,\n repeat: Infinity,\n repeatType: 'loop',\n repeatDelay: text.length * 0.05,\n delay: (i * duration) / text.length,\n ease: 'easeInOut',\n ...transition,\n }}\n >\n {char}\n </motion.span>\n ))}\n </motion.span>\n );\n}\n\nexport { ShimmeringText, type ShimmeringTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/shimmering/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'shimmering-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/shimmering-text',
},
'sliding-number': {
name: 'sliding-number',
description:
'A numeric display component that smoothly animates number changes with a sliding transition effect.',
type: 'registry:ui',
dependencies: ['motion', 'react-use-measure'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/sliding-number/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/sliding-number.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n useSpring,\n useTransform,\n motion,\n useInView,\n type MotionValue,\n type SpringOptions,\n type UseInViewOptions,\n} from 'motion/react';\nimport useMeasure from 'react-use-measure';\n\nimport { cn } from '@/lib/utils';\n\ntype SlidingNumberRollerProps = {\n prevValue: number;\n value: number;\n place: number;\n transition: SpringOptions;\n};\n\nfunction SlidingNumberRoller({\n prevValue,\n value,\n place,\n transition,\n}: SlidingNumberRollerProps) {\n const startNumber = Math.floor(prevValue / place) % 10;\n const targetNumber = Math.floor(value / place) % 10;\n const animatedValue = useSpring(startNumber, transition);\n\n React.useEffect(() => {\n animatedValue.set(targetNumber);\n }, [targetNumber, animatedValue]);\n\n const [measureRef, { height }] = useMeasure();\n\n return (\n <span\n ref={measureRef}\n data-slot=\"sliding-number-roller\"\n className=\"relative inline-block w-[1ch] overflow-x-visible overflow-y-clip leading-none tabular-nums\"\n >\n <span className=\"invisible\">0</span>\n {Array.from({ length: 10 }, (_, i) => (\n <SlidingNumberDisplay\n key={i}\n motionValue={animatedValue}\n number={i}\n height={height}\n transition={transition}\n />\n ))}\n </span>\n );\n}\n\ntype SlidingNumberDisplayProps = {\n motionValue: MotionValue<number>;\n number: number;\n height: number;\n transition: SpringOptions;\n};\n\nfunction SlidingNumberDisplay({\n motionValue,\n number,\n height,\n transition,\n}: SlidingNumberDisplayProps) {\n const y = useTransform(motionValue, (latest) => {\n if (!height) return 0;\n const currentNumber = latest % 10;\n const offset = (10 + number - currentNumber) % 10;\n let translateY = offset * height;\n if (offset > 5) translateY -= 10 * height;\n return translateY;\n });\n\n if (!height) {\n return <span className=\"invisible absolute\">{number}</span>;\n }\n\n return (\n <motion.span\n data-slot=\"sliding-number-display\"\n style={{ y }}\n className=\"absolute inset-0 flex items-center justify-center\"\n transition={{ ...transition, type: 'spring' }}\n >\n {number}\n </motion.span>\n );\n}\n\ntype SlidingNumberProps = React.ComponentProps<'span'> & {\n number: number | string;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n padStart?: boolean;\n decimalSeparator?: string;\n decimalPlaces?: number;\n transition?: SpringOptions;\n};\n\nfunction SlidingNumber({\n ref,\n number,\n className,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n padStart = false,\n decimalSeparator = '.',\n decimalPlaces = 0,\n transition = {\n stiffness: 200,\n damping: 20,\n mass: 0.4,\n },\n ...props\n}: SlidingNumberProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current!);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const prevNumberRef = React.useRef<number>(0);\n\n const effectiveNumber = React.useMemo(\n () => (!isInView ? 0 : Math.abs(Number(number))),\n [number, isInView],\n );\n\n const formatNumber = React.useCallback(\n (num: number) =>\n decimalPlaces != null ? num.toFixed(decimalPlaces) : num.toString(),\n [decimalPlaces],\n );\n\n const numberStr = formatNumber(effectiveNumber);\n const [newIntStrRaw, newDecStrRaw = ''] = numberStr.split('.');\n const newIntStr =\n padStart && newIntStrRaw?.length === 1 ? '0' + newIntStrRaw : newIntStrRaw;\n\n const prevFormatted = formatNumber(prevNumberRef.current);\n const [prevIntStrRaw = '', prevDecStrRaw = ''] = prevFormatted.split('.');\n const prevIntStr =\n padStart && prevIntStrRaw.length === 1\n ? '0' + prevIntStrRaw\n : prevIntStrRaw;\n\n const adjustedPrevInt = React.useMemo(() => {\n return prevIntStr.length > (newIntStr?.length ?? 0)\n ? prevIntStr.slice(-(newIntStr?.length ?? 0))\n : prevIntStr.padStart(newIntStr?.length ?? 0, '0');\n }, [prevIntStr, newIntStr]);\n\n const adjustedPrevDec = React.useMemo(() => {\n if (!newDecStrRaw) return '';\n return prevDecStrRaw.length > newDecStrRaw.length\n ? prevDecStrRaw.slice(0, newDecStrRaw.length)\n : prevDecStrRaw.padEnd(newDecStrRaw.length, '0');\n }, [prevDecStrRaw, newDecStrRaw]);\n\n React.useEffect(() => {\n if (isInView) prevNumberRef.current = effectiveNumber;\n }, [effectiveNumber, isInView]);\n\n const intDigitCount = newIntStr?.length ?? 0;\n const intPlaces = React.useMemo(\n () =>\n Array.from({ length: intDigitCount }, (_, i) =>\n Math.pow(10, intDigitCount - i - 1),\n ),\n [intDigitCount],\n );\n const decPlaces = React.useMemo(\n () =>\n newDecStrRaw\n ? Array.from({ length: newDecStrRaw.length }, (_, i) =>\n Math.pow(10, newDecStrRaw.length - i - 1),\n )\n : [],\n [newDecStrRaw],\n );\n\n const newDecValue = newDecStrRaw ? parseInt(newDecStrRaw, 10) : 0;\n const prevDecValue = adjustedPrevDec ? parseInt(adjustedPrevDec, 10) : 0;\n\n return (\n <span\n ref={localRef}\n data-slot=\"sliding-number\"\n className={cn('flex items-center', className)}\n {...props}\n >\n {isInView && Number(number) < 0 && <span className=\"mr-1\">-</span>}\n\n {intPlaces.map((place) => (\n <SlidingNumberRoller\n key={`int-${place}`}\n prevValue={parseInt(adjustedPrevInt, 10)}\n value={parseInt(newIntStr ?? '0', 10)}\n place={place}\n transition={transition}\n />\n ))}\n\n {newDecStrRaw && (\n <>\n <span>{decimalSeparator}</span>\n {decPlaces.map((place) => (\n <SlidingNumberRoller\n key={`dec-${place}`}\n prevValue={prevDecValue}\n value={newDecValue}\n place={place}\n transition={transition}\n />\n ))}\n </>\n )}\n </span>\n );\n}\n\nexport { SlidingNumber, type SlidingNumberProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/sliding-number/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'sliding-number';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/sliding-number',
},
'splitting-text': {
name: 'splitting-text',
description:
'A text component that dynamically simulates a splitting animation, progressively revealing characters as if typed in real-time.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/splitting/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/splitting.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n type Variants,\n type TargetAndTransition,\n type HTMLMotionProps,\n useInView,\n type UseInViewOptions,\n} from 'motion/react';\n\ntype DefaultSplittingTextProps = {\n motionVariants?: {\n initial?: Record<string, any>;\n animate?: Record<string, any>;\n transition?: Record<string, any>;\n stagger?: number;\n };\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n delay?: number;\n} & HTMLMotionProps<'div'>;\n\ntype CharsOrWordsSplittingTextProps = DefaultSplittingTextProps & {\n type?: 'chars' | 'words';\n text: string;\n};\n\ntype LinesSplittingTextProps = DefaultSplittingTextProps & {\n type: 'lines';\n text: string[];\n};\n\ntype SplittingTextProps =\n | CharsOrWordsSplittingTextProps\n | LinesSplittingTextProps;\n\nconst defaultItemVariant: Variants = {\n hidden: { x: 150, opacity: 0 },\n visible: {\n x: 0,\n opacity: 1,\n transition: { duration: 0.7, ease: 'easeOut' },\n },\n};\n\nexport const SplittingText: React.FC<SplittingTextProps> = ({\n ref,\n text,\n type = 'chars',\n motionVariants = {},\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n delay = 0,\n ...props\n}) => {\n const items = React.useMemo<React.ReactNode[]>(() => {\n if (Array.isArray(text)) {\n return text.flatMap((line, i) => [\n <React.Fragment key={`line-${i}`}>{line}</React.Fragment>,\n i < text.length - 1 ? <br key={`br-${i}`} /> : null,\n ]);\n }\n\n if (type === 'words') {\n const tokens = text.match(/\\S+\\s*/g) || [];\n return tokens.map((token, i) => (\n <React.Fragment key={i}>{token}</React.Fragment>\n ));\n }\n\n return text\n .split('')\n .map((char, i) => <React.Fragment key={i}>{char}</React.Fragment>);\n }, [text, type]);\n\n const containerVariants: Variants = {\n hidden: {},\n visible: {\n transition: {\n delayChildren: delay / 1000,\n staggerChildren:\n motionVariants.stagger ??\n (type === 'chars' ? 0.05 : type === 'words' ? 0.2 : 0.3),\n },\n },\n };\n\n const itemVariants: Variants = {\n hidden: {\n ...defaultItemVariant.hidden,\n ...(motionVariants.initial || {}),\n },\n visible: {\n ...defaultItemVariant.visible,\n ...(motionVariants.animate || {}),\n transition: {\n ...((defaultItemVariant.visible as TargetAndTransition).transition ||\n {}),\n ...(motionVariants.transition || {}),\n },\n },\n };\n\n const localRef = React.useRef<HTMLDivElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n return (\n <motion.span\n ref={localRef}\n initial=\"hidden\"\n animate={isInView ? 'visible' : 'hidden'}\n variants={containerVariants}\n {...props}\n >\n {items.map(\n (item, index) =>\n item && (\n <React.Fragment key={index}>\n <motion.span\n key={index}\n variants={itemVariants}\n style={{\n display: 'inline-block',\n whiteSpace:\n type === 'chars'\n ? 'pre'\n : Array.isArray(text)\n ? 'normal'\n : 'normal',\n }}\n >\n {item}\n </motion.span>\n {type === 'words' && ' '}\n </React.Fragment>\n ),\n )}\n </motion.span>\n );\n};",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/splitting/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'splitting-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/splitting-text',
},
'typing-text': {
name: 'typing-text',
description:
'A text component that dynamically simulates a typing animation, progressively revealing characters as if typed in real-time.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/typing/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/typing.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, useInView, type UseInViewOptions } from 'motion/react';\n\nimport { cn } from '@/lib/utils';\n\nfunction CursorBlinker({ className }: { className?: string }) {\n return (\n <motion.span\n data-slot=\"cursor-blinker\"\n variants={{\n blinking: {\n opacity: [0, 0, 1, 1],\n transition: {\n duration: 1,\n repeat: Infinity,\n repeatDelay: 0,\n ease: 'linear',\n times: [0, 0.5, 0.5, 1],\n },\n },\n }}\n animate=\"blinking\"\n className={cn(\n 'inline-block h-5 w-[1px] translate-y-1 bg-black dark:bg-white',\n className,\n )}\n />\n );\n}\n\ntype TypingTextProps = Omit<React.ComponentProps<'span'>, 'children'> & {\n duration?: number;\n delay?: number;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n cursor?: boolean;\n loop?: boolean;\n holdDelay?: number;\n text: string | string[];\n cursorClassName?: string;\n animateOnChange?: boolean;\n};\n\nfunction TypingText({\n ref,\n duration = 100,\n delay = 0,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n cursor = false,\n loop = false,\n holdDelay = 1000,\n text,\n cursorClassName,\n animateOnChange = true,\n ...props\n}: TypingTextProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLSpanElement);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const [started, setStarted] = React.useState(false);\n const [displayedText, setDisplayedText] = React.useState<string>('');\n\n React.useEffect(() => {\n // Reset animation when text changes (if animateOnChange is true)\n if (animateOnChange) {\n setStarted(false);\n setDisplayedText('');\n }\n\n if (isInView) {\n const timeoutId = setTimeout(() => {\n setStarted(true);\n }, delay);\n return () => clearTimeout(timeoutId);\n } else {\n const timeoutId = setTimeout(() => {\n setStarted(true);\n }, delay);\n return () => clearTimeout(timeoutId);\n }\n }, [isInView, delay, ...(animateOnChange ? [text] : [])]);\n\n React.useEffect(() => {\n if (!started) return;\n const timeoutIds: Array<ReturnType<typeof setTimeout>> = [];\n const texts: string[] = typeof text === 'string' ? [text] : text;\n\n const typeText = (str: string, onComplete: () => void) => {\n let currentIndex = 0;\n const type = () => {\n if (currentIndex <= str.length) {\n setDisplayedText(str.substring(0, currentIndex));\n currentIndex++;\n const id = setTimeout(type, duration);\n timeoutIds.push(id);\n } else {\n onComplete();\n }\n };\n type();\n };\n\n const eraseText = (str: string, onComplete: () => void) => {\n let currentIndex = str.length;\n const erase = () => {\n if (currentIndex >= 0) {\n setDisplayedText(str.substring(0, currentIndex));\n currentIndex--;\n const id = setTimeout(erase, duration);\n timeoutIds.push(id);\n } else {\n onComplete();\n }\n };\n erase();\n };\n\n const animateTexts = (index: number) => {\n typeText(texts[index] ?? '', () => {\n const isLast = index === texts.length - 1;\n if (isLast && !loop) {\n return;\n }\n const id = setTimeout(() => {\n eraseText(texts[index] ?? '', () => {\n const nextIndex = isLast ? 0 : index + 1;\n animateTexts(nextIndex);\n });\n }, holdDelay);\n timeoutIds.push(id);\n });\n };\n\n animateTexts(0);\n\n return () => {\n timeoutIds.forEach(clearTimeout);\n };\n }, [text, duration, started, loop, holdDelay]);\n\n return (\n <span ref={localRef} data-slot=\"typing-text\" {...props}>\n <motion.span>{displayedText}</motion.span>\n {cursor && <CursorBlinker className={cursorClassName} />}\n </span>\n );\n}\n\nexport { TypingText, type TypingTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/typing/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'typing-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/typing-text',
},
'writing-text': {
name: 'writing-text',
description: 'A text component that smoothly reveals content word by word.',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: undefined,
files: [
{
path: 'registry/text/writing/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/text/writing.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport {\n motion,\n useInView,\n type Transition,\n type UseInViewOptions,\n} from 'motion/react';\n\ntype WritingTextProps = Omit<React.ComponentProps<'span'>, 'children'> & {\n transition?: Transition;\n inView?: boolean;\n inViewMargin?: UseInViewOptions['margin'];\n inViewOnce?: boolean;\n spacing?: number | string;\n text: string;\n};\n\nfunction WritingText({\n ref,\n inView = false,\n inViewMargin = '0px',\n inViewOnce = true,\n spacing = 5,\n text,\n transition = { type: 'spring', bounce: 0, duration: 2, delay: 0.5 },\n ...props\n}: WritingTextProps) {\n const localRef = React.useRef<HTMLSpanElement>(null);\n React.useImperativeHandle(ref, () => localRef.current as HTMLSpanElement);\n\n const inViewResult = useInView(localRef, {\n once: inViewOnce,\n margin: inViewMargin,\n });\n const isInView = !inView || inViewResult;\n\n const words = React.useMemo(() => text.split(' '), [text]);\n\n return (\n <span ref={localRef} data-slot=\"writing-text\" {...props}>\n {words.map((word, index) => (\n <motion.span\n key={index}\n className=\"inline-block will-change-transform will-change-opacity\"\n style={{ marginRight: spacing }}\n initial={{ opacity: 0, y: 10 }}\n animate={isInView ? { opacity: 1, y: 0 } : undefined}\n transition={{\n ...transition,\n delay: index * (transition?.delay ?? 0),\n }}\n >\n {word}{' '}\n </motion.span>\n ))}\n </span>\n );\n}\n\nexport { WritingText, type WritingTextProps };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import('@/registry/text/writing/index.tsx');
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'writing-text';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/writing-text',
},
'management-bar': {
name: 'management-bar',
description: 'Management Bar Component',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/sliding-number'],
files: [
{
path: 'registry/ui-elements/management-bar/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/ui-elements/management-bar.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport {\n ChevronLeft,\n ChevronRight,\n Ban,\n X,\n Command,\n IdCard,\n} from \'lucide-react\';\nimport { SlidingNumber } from \'@/components/animate-ui/text/sliding-number\';\nimport { motion, type Variants, type Transition } from \'motion/react\';\n\nconst TOTAL_PAGES = 10;\n\nconst BUTTON_MOTION_CONFIG = {\n initial: \'rest\',\n whileHover: \'hover\',\n whileTap: \'tap\',\n variants: {\n rest: { maxWidth: \'40px\' },\n hover: {\n maxWidth: \'140px\',\n transition: { type: \'spring\', stiffness: 200, damping: 35, delay: 0.15 },\n },\n tap: { scale: 0.95 },\n },\n transition: { type: \'spring\', stiffness: 250, damping: 25 },\n} as const;\n\nconst LABEL_VARIANTS: Variants = {\n rest: { opacity: 0, x: 4 },\n hover: { opacity: 1, x: 0, visibility: \'visible\' },\n tap: { opacity: 1, x: 0, visibility: \'visible\' },\n};\n\nconst LABEL_TRANSITION: Transition = {\n type: \'spring\',\n stiffness: 200,\n damping: 25,\n};\n\nfunction ManagementBar() {\n const [currentPage, setCurrentPage] = React.useState(1);\n\n const handlePrevPage = React.useCallback(() => {\n if (currentPage > 1) setCurrentPage(currentPage - 1);\n }, [currentPage]);\n\n const handleNextPage = React.useCallback(() => {\n if (currentPage < TOTAL_PAGES) setCurrentPage(currentPage + 1);\n }, [currentPage]);\n\n return (\n <div className="flex w-fit flex-wrap items-center gap-y-2 rounded-2xl border border-border bg-background p-2 shadow-lg">\n <div className="mx-auto flex shrink-0 items-center">\n <button\n disabled={currentPage === 1}\n className="p-1 text-muted-foreground transition-colors hover:text-foreground disabled:text-muted-foreground/30 disabled:hover:text-muted-foreground/30"\n onClick={handlePrevPage}\n >\n <ChevronLeft size={20} />\n </button>\n <div className="mx-2 flex items-center space-x-1 text-sm tabular-nums">\n <SlidingNumber\n className="text-foreground"\n padStart\n number={currentPage}\n />\n <span className="text-muted-foreground">/ {TOTAL_PAGES}</span>\n </div>\n <button\n disabled={currentPage === TOTAL_PAGES}\n className="p-1 text-muted-foreground transition-colors hover:text-foreground disabled:text-muted-foreground/30 disabled:hover:text-muted-foreground/30"\n onClick={handleNextPage}\n >\n <ChevronRight size={20} />\n </button>\n </div>\n\n <div className="mx-3 h-6 w-px bg-border rounded-full" />\n\n <motion.div\n layout\n layoutRoot\n className="mx-auto flex flex-wrap space-x-2 sm:flex-nowrap"\n >\n <motion.button\n {...BUTTON_MOTION_CONFIG}\n className="flex h-10 items-center space-x-2 overflow-hidden whitespace-nowrap rounded-lg bg-neutral-200/60 dark:bg-neutral-600/80 px-2.5 py-2 text-neutral-600 dark:text-neutral-200"\n aria-label="Blacklist"\n >\n <Ban size={20} className="shrink-0" />\n <motion.span\n variants={LABEL_VARIANTS}\n transition={LABEL_TRANSITION}\n className="invisible text-sm"\n >\n Blacklist\n </motion.span>\n </motion.button>\n\n <motion.button\n {...BUTTON_MOTION_CONFIG}\n className="flex h-10 items-center space-x-2 overflow-hidden whitespace-nowrap rounded-lg bg-red-200/60 dark:bg-red-800/80 px-2.5 py-2 text-red-600 dark:text-red-300"\n aria-label="Reject"\n >\n <X size={20} className="shrink-0" />\n <motion.span\n variants={LABEL_VARIANTS}\n transition={LABEL_TRANSITION}\n className="invisible text-sm"\n >\n Reject\n </motion.span>\n </motion.button>\n\n <motion.button\n {...BUTTON_MOTION_CONFIG}\n className="flex h-10 items-center space-x-2 overflow-hidden whitespace-nowrap rounded-lg bg-green-200/60 dark:bg-green-800/80 px-2.5 py-2 text-green-600 dark:text-green-300"\n aria-label="Hire"\n >\n <IdCard size={20} className="shrink-0" />\n <motion.span\n variants={LABEL_VARIANTS}\n transition={LABEL_TRANSITION}\n className="invisible text-sm"\n >\n Hire\n </motion.span>\n </motion.button>\n </motion.div>\n\n <div className="mx-3 hidden h-6 w-px bg-border sm:block rounded-full" />\n\n <motion.button\n whileTap={{ scale: 0.975 }}\n className="flex w-full h-10 text-sm cursor-pointer items-center justify-center rounded-lg bg-teal-500 dark:bg-teal-600/80 px-3 py-2 text-white transition-colors duration-300 dark:hover:bg-teal-800 hover:bg-teal-600 sm:w-auto"\n >\n <span className="mr-1 text-neutral-200">Move to:</span>\n <span>Interview I</span>\n <div className="mx-3 h-5 w-px bg-white/40 rounded-full" />\n <div className="flex items-center gap-1 rounded-md bg-white/20 px-1.5 py-0.5 -mr-1">\n <Command size={14} />E\n </div>\n </motion.button>\n </div>\n );\n}\n\nexport { ManagementBar };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/ui-elements/management-bar/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'management-bar';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/management-bar',
},
'notification-list': {
name: 'notification-list',
description: 'Notification List Component',
type: 'registry:ui',
dependencies: ['motion', 'lucide-react'],
devDependencies: undefined,
registryDependencies: [],
files: [
{
path: 'registry/ui-elements/notification-list/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/ui-elements/notification-list.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { RotateCcw, ArrowUpRight } from 'lucide-react';\nimport { motion, type Transition } from 'motion/react';\n\nconst notifications = [\n {\n id: 1,\n title: 'NPM Install Complete',\n subtitle: '1,227 packages added!',\n time: 'just now',\n count: 2,\n },\n {\n id: 2,\n title: 'Build Succeeded',\n subtitle: 'Build finished in 12.34s',\n time: '1m 11s',\n },\n {\n id: 3,\n title: 'Lint Passed',\n subtitle: 'No problems found',\n time: '5m',\n },\n];\n\nconst transition: Transition = {\n type: 'spring',\n stiffness: 300,\n damping: 26,\n};\n\nconst getCardVariants = (i: number) => ({\n collapsed: {\n marginTop: i === 0 ? 0 : -44,\n scaleX: 1 - i * 0.05,\n },\n expanded: {\n marginTop: i === 0 ? 0 : 4,\n scaleX: 1,\n },\n});\n\nconst textSwitchTransition: Transition = {\n duration: 0.22,\n ease: 'easeInOut',\n};\n\nconst notificationTextVariants = {\n collapsed: { opacity: 1, y: 0, pointerEvents: 'auto' },\n expanded: { opacity: 0, y: -16, pointerEvents: 'none' },\n};\n\nconst viewAllTextVariants = {\n collapsed: { opacity: 0, y: 16, pointerEvents: 'none' },\n expanded: { opacity: 1, y: 0, pointerEvents: 'auto' },\n};\n\nfunction NotificationList() {\n return (\n <motion.div\n className=\"bg-neutral-200 dark:bg-neutral-900 p-3 rounded-3xl w-xs space-y-3 shadow-md\"\n initial=\"collapsed\"\n whileHover=\"expanded\"\n >\n <div>\n {notifications.map((notification, i) => (\n <motion.div\n key={notification.id}\n className=\"bg-neutral-100 dark:bg-neutral-800 rounded-xl px-4 py-2 shadow-sm hover:shadow-lg transition-shadow duration-200 relative\"\n variants={getCardVariants(i)}\n transition={transition}\n style={{\n zIndex: notifications.length - i,\n }}\n >\n <div className=\"flex justify-between items-center\">\n <h1 className=\"text-sm font-medium\">{notification.title}</h1>\n {notification.count && (\n <div className=\"flex items-center text-xs gap-0.5 font-medium text-neutral-500 dark:text-neutral-300\">\n <RotateCcw className=\"size-3\" />\n <span>{notification.count}</span>\n </div>\n )}\n </div>\n <div className=\"text-xs text-neutral-500 font-medium\">\n <span>{notification.time}</span>\n &nbsp;•&nbsp;\n <span>{notification.subtitle}</span>\n </div>\n </motion.div>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <div className=\"size-5 rounded-full bg-neutral-400 text-white text-xs flex items-center justify-center font-medium\">\n {notifications.length}\n </div>\n <span className=\"grid\">\n <motion.span\n className=\"text-sm font-medium text-neutral-600 dark:text-neutral-300 row-start-1 col-start-1\"\n variants={notificationTextVariants}\n transition={textSwitchTransition}\n >\n Notifications\n </motion.span>\n <motion.span\n className=\"text-sm font-medium text-neutral-600 dark:text-neutral-300 flex items-center gap-1 cursor-pointer select-none row-start-1 col-start-1\"\n variants={viewAllTextVariants}\n transition={textSwitchTransition}\n >\n View all <ArrowUpRight className=\"size-4\" />\n </motion.span>\n </span>\n </div>\n </motion.div>\n );\n}\n\nexport { NotificationList };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/ui-elements/notification-list/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'notification-list';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/notification-list',
},
'playful-todolist': {
name: 'playful-todolist',
description: 'Playful Todolist Component',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/radix-checkbox'],
files: [
{
path: 'registry/ui-elements/playful-todolist/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/ui-elements/playful-todolist.tsx',
content:
'\'use client\';\n\nimport * as React from \'react\';\nimport { motion, type Transition } from \'motion/react\';\nimport { Label } from \'@/components/ui/label\';\nimport { Checkbox } from \'@/components/animate-ui/radix/checkbox\';\n\nconst checkboxItems = [\n {\n id: 1,\n label: \'Code in Assembly 💾\',\n defaultChecked: false,\n },\n {\n id: 2,\n label: \'Present a bug as a feature 🪲\',\n defaultChecked: false,\n },\n {\n id: 3,\n label: \'Push to prod on a Friday 🚀\',\n defaultChecked: false,\n },\n];\n\nconst getPathAnimate = (isChecked: boolean) => ({\n pathLength: isChecked ? 1 : 0,\n opacity: isChecked ? 1 : 0,\n});\n\nconst getPathTransition = (isChecked: boolean): Transition => ({\n pathLength: { duration: 1, ease: \'easeInOut\' },\n opacity: {\n duration: 0.01,\n delay: isChecked ? 0 : 1,\n },\n});\n\nfunction PlayfulTodolist() {\n const [checked, setChecked] = React.useState(\n checkboxItems.map((i) => !!i.defaultChecked),\n );\n\n return (\n <div className="bg-neutral-100 dark:bg-neutral-900 rounded-2xl p-6 space-y-6">\n {checkboxItems.map((item, idx) => (\n <div key={item.id} className="space-y-6">\n <div className="flex items-center space-x-2">\n <Checkbox\n checked={checked[idx]}\n onCheckedChange={(val) => {\n const updated = [...checked];\n updated[idx] = val === true;\n setChecked(updated);\n }}\n id={`checkbox-${item.id}`}\n />\n <div className="relative inline-block">\n <Label htmlFor={`checkbox-${item.id}`}>{item.label}</Label>\n <motion.svg\n width="340"\n height="32"\n viewBox="0 0 340 32"\n className="absolute left-0 top-1/2 -translate-y-1/2 pointer-events-none z-20 w-full h-10"\n >\n <motion.path\n d="M 10 16.91 s 79.8 -11.36 98.1 -11.34 c 22.2 0.02 -47.82 14.25 -33.39 22.02 c 12.61 6.77 124.18 -27.98 133.31 -17.28 c 7.52 8.38 -26.8 20.02 4.61 22.05 c 24.55 1.93 113.37 -20.36 113.37 -20.36"\n vectorEffect="non-scaling-stroke"\n strokeWidth={2}\n strokeLinecap="round"\n strokeMiterlimit={10}\n fill="none"\n initial={false}\n animate={getPathAnimate(!!checked[idx])}\n transition={getPathTransition(!!checked[idx])}\n className="stroke-neutral-900 dark:stroke-neutral-100"\n />\n </motion.svg>\n </div>\n </div>\n {idx !== checkboxItems.length - 1 && (\n <div className="border-t border-neutral-300 dark:border-neutral-700" />\n )}\n </div>\n ))}\n </div>\n );\n}\n\nexport { PlayfulTodolist };',
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/ui-elements/playful-todolist/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'playful-todolist';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/playful-todolist',
},
'user-presence-avatar': {
name: 'user-presence-avatar',
description: 'User Presence Avatar Component',
type: 'registry:ui',
dependencies: ['motion'],
devDependencies: undefined,
registryDependencies: ['https://animate-ui.com/r/avatar-group'],
files: [
{
path: 'registry/ui-elements/user-presence-avatar/index.tsx',
type: 'registry:ui',
target: 'components/animate-ui/ui-elements/user-presence-avatar.tsx',
content:
"'use client';\n\nimport * as React from 'react';\nimport { motion, LayoutGroup } from 'motion/react';\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from '@/components/ui/avatar';\nimport {\n AvatarGroup,\n AvatarGroupTooltip,\n} from '@/components/animate-ui/components/avatar-group';\nimport { cn } from '@/lib/utils';\n\nconst USERS = [\n {\n id: 1,\n src: 'https://pbs.twimg.com/profile_images/1897311929028255744/otxpL-ke_400x400.jpg',\n fallback: 'AK',\n tooltip: 'Arhamkhnz',\n online: true,\n },\n {\n id: 2,\n src: 'https://pbs.twimg.com/profile_images/1909615404789506048/MTqvRsjo_400x400.jpg',\n fallback: 'SK',\n tooltip: 'Skyleen',\n online: true,\n },\n {\n id: 3,\n src: 'https://pbs.twimg.com/profile_images/1593304942210478080/TUYae5z7_400x400.jpg',\n fallback: 'CN',\n tooltip: 'Shadcn',\n online: true,\n },\n {\n id: 4,\n src: 'https://pbs.twimg.com/profile_images/1677042510839857154/Kq4tpySA_400x400.jpg',\n fallback: 'AW',\n tooltip: 'Adam Wathan',\n online: false,\n },\n {\n id: 5,\n src: 'https://pbs.twimg.com/profile_images/1783856060249595904/8TfcCN0r_400x400.jpg',\n fallback: 'GR',\n tooltip: 'Guillermo Rauch',\n online: false,\n },\n {\n id: 6,\n src: 'https://pbs.twimg.com/profile_images/1534700564810018816/anAuSfkp_400x400.jpg',\n fallback: 'JH',\n tooltip: 'Jhey',\n online: false,\n },\n];\n\nconst AVATAR_MOTION_TRANSITION = {\n type: 'spring',\n stiffness: 200,\n damping: 25,\n} as const;\n\nconst GROUP_CONTAINER_TRANSITION = {\n type: 'spring',\n stiffness: 150,\n damping: 20,\n} as const;\n\nfunction UserPresenceAvatar() {\n const [users, setUsers] = React.useState(USERS);\n const [togglingGroup, setTogglingGroup] = React.useState<\n 'online' | 'offline' | null\n >(null);\n\n const online = users.filter((u) => u.online);\n const offline = users.filter((u) => !u.online);\n\n const toggleStatus = (id: number) => {\n const user = users.find((u) => u.id === id);\n if (!user) return;\n\n setTogglingGroup(user.online ? 'online' : 'offline');\n setUsers((prev) => {\n const idx = prev.findIndex((u) => u.id === id);\n if (idx === -1) return prev;\n const updated = [...prev];\n const target = updated[idx];\n if (!target) return prev;\n updated.splice(idx, 1);\n updated.push({ ...target, online: !target.online });\n return updated;\n });\n // Reset group z-index after the animation duration (keep in sync with animation timing)\n setTimeout(() => setTogglingGroup(null), 500);\n };\n\n return (\n <div className=\"flex items-center gap-5\">\n <LayoutGroup>\n {online.length > 0 && (\n <motion.div\n layout\n className={cn(\n 'bg-neutral-300 dark:bg-neutral-700 p-0.5 rounded-full',\n togglingGroup === 'online' ? 'z-5' : 'z-10',\n )}\n transition={GROUP_CONTAINER_TRANSITION}\n >\n <AvatarGroup\n key={online.map((u) => u.id).join('_') + '-online'}\n translate=\"0\"\n className=\"h-12 -space-x-3\"\n tooltipProps={{ side: 'top', sideOffset: 14 }}\n >\n {online.map((user) => (\n <motion.div\n key={user.id}\n layoutId={`avatar-${user.id}`}\n className=\"cursor-pointer\"\n onClick={() => toggleStatus(user.id)}\n animate={{\n filter: 'grayscale(0)',\n scale: 1,\n }}\n transition={AVATAR_MOTION_TRANSITION}\n title=\"Click to go offline\"\n initial={false}\n >\n <Avatar className=\"size-12 border-3 border-neutral-300 dark:border-neutral-700\">\n <AvatarImage src={user.src} />\n <AvatarFallback>{user.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{user.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n </motion.div>\n ))}\n </AvatarGroup>\n </motion.div>\n )}\n\n {offline.length > 0 && (\n <motion.div\n layout\n className={cn(\n 'bg-neutral-300 dark:bg-neutral-700 p-0.5 rounded-full',\n togglingGroup === 'offline' ? 'z-5' : 'z-10',\n )}\n transition={GROUP_CONTAINER_TRANSITION}\n >\n <AvatarGroup\n key={offline.map((u) => u.id).join('_') + '-offline'}\n translate=\"0\"\n className=\"h-12 -space-x-3\"\n tooltipProps={{ side: 'top', sideOffset: 14 }}\n >\n {offline.map((user) => (\n <motion.div\n key={user.id}\n layoutId={`avatar-${user.id}`}\n className=\"cursor-pointer\"\n onClick={() => toggleStatus(user.id)}\n animate={{\n filter: 'grayscale(1)',\n scale: 1,\n }}\n transition={AVATAR_MOTION_TRANSITION}\n title=\"Click to go online\"\n initial={false}\n >\n <Avatar className=\"size-12 border-3 border-neutral-300 dark:border-neutral-700\">\n <AvatarImage src={user.src} />\n <AvatarFallback>{user.fallback}</AvatarFallback>\n <AvatarGroupTooltip>\n <p>{user.tooltip}</p>\n </AvatarGroupTooltip>\n </Avatar>\n </motion.div>\n ))}\n </AvatarGroup>\n </motion.div>\n )}\n </LayoutGroup>\n </div>\n );\n}\n\nexport { UserPresenceAvatar };",
},
],
keywords: [],
component: (function () {
const LazyComp = React.lazy(async () => {
const mod = await import(
'@/registry/ui-elements/user-presence-avatar/index.tsx'
);
const exportName =
Object.keys(mod).find(
(key) =>
typeof mod[key] === 'function' || typeof mod[key] === 'object',
) || 'user-presence-avatar';
const Comp = mod.default || mod[exportName];
if (mod.animations) {
(LazyComp as any).animations = mod.animations;
}
return { default: Comp };
});
LazyComp.demoProps = {};
return LazyComp;
})(),
command: 'https://animate-ui.com/r/user-presence-avatar',
},
};