{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"loader","type":"registry:ui","title":"Loader","description":"Tailark Base UI Loader component","registryDependencies":["@tailark/core-utils"],"files":[{"path":"ui/loader.tsx","type":"registry:ui","target":"@ui/loader.tsx","content":"import { cn } from '@/lib/utils'\n\nconst CIRCULAR_SIZE_CLASSES = {\n    sm: 'size-4',\n    md: 'size-5',\n    lg: 'size-6',\n}\n\nconst CLASSIC_SIZE_CLASSES = {\n    sm: 'size-4',\n    md: 'size-5',\n    lg: 'size-6',\n}\n\nconst CLASSIC_BAR_SIZES = {\n    sm: { height: '6px', width: '1.5px' },\n    md: { height: '8px', width: '2px' },\n    lg: { height: '10px', width: '2.5px' },\n}\n\nconst PULSE_SIZE_CLASSES = {\n    sm: 'size-4',\n    md: 'size-5',\n    lg: 'size-6',\n}\n\nconst PULSE_DOT_SIZE_CLASSES = {\n    sm: 'size-1',\n    md: 'size-2',\n    lg: 'size-3',\n}\n\nconst DOTS_DOT_SIZES = {\n    sm: 'h-1.5 w-1.5',\n    md: 'h-2 w-2',\n    lg: 'h-2.5 w-2.5',\n}\n\nconst DOTS_CONTAINER_SIZES = {\n    sm: 'h-4',\n    md: 'h-5',\n    lg: 'h-6',\n}\n\nconst TYPING_DOT_SIZES = {\n    sm: 'h-1 w-1',\n    md: 'h-1.5 w-1.5',\n    lg: 'h-2 w-2',\n}\n\nconst TYPING_CONTAINER_SIZES = {\n    sm: 'h-4',\n    md: 'h-5',\n    lg: 'h-6',\n}\n\nconst WAVE_BAR_WIDTHS = {\n    sm: 'w-0.5',\n    md: 'w-0.5',\n    lg: 'w-1',\n}\n\nconst WAVE_CONTAINER_SIZES = {\n    sm: 'h-4',\n    md: 'h-5',\n    lg: 'h-6',\n}\n\nconst WAVE_HEIGHTS = {\n    sm: ['6px', '9px', '12px', '9px', '6px'],\n    md: ['8px', '12px', '16px', '12px', '8px'],\n    lg: ['10px', '15px', '20px', '15px', '10px'],\n}\n\nconst BARS_BAR_WIDTHS = {\n    sm: 'w-1',\n    md: 'w-1.5',\n    lg: 'w-2',\n}\n\nconst BARS_CONTAINER_SIZES = {\n    sm: 'h-4 gap-1',\n    md: 'h-5 gap-1.5',\n    lg: 'h-6 gap-2',\n}\n\nconst TERMINAL_CURSOR_SIZES = {\n    sm: 'h-3 w-1.5',\n    md: 'h-4 w-2',\n    lg: 'h-5 w-2.5',\n}\n\nconst TERMINAL_TEXT_SIZES = {\n    sm: 'text-xs',\n    md: 'text-sm',\n    lg: 'text-base',\n}\n\nconst TERMINAL_CONTAINER_SIZES = {\n    sm: 'h-4',\n    md: 'h-5',\n    lg: 'h-6',\n}\n\nconst TEXT_BLINK_TEXT_SIZES = {\n    sm: 'text-xs',\n    md: 'text-sm',\n    lg: 'text-base',\n}\n\nconst TEXT_SHIMMER_TEXT_SIZES = {\n    sm: 'text-xs',\n    md: 'text-sm',\n    lg: 'text-base',\n}\n\nconst TEXT_DOTS_TEXT_SIZES = {\n    sm: 'text-xs',\n    md: 'text-sm',\n    lg: 'text-base',\n}\n\nexport interface LoaderProps {\n    variant?: 'circular' | 'classic' | 'pulse' | 'pulse-dot' | 'dots' | 'typing' | 'wave' | 'bars' | 'terminal' | 'text-blink' | 'text-shimmer' | 'loading-dots'\n    size?: 'sm' | 'md' | 'lg'\n    text?: string\n    className?: string\n}\n\nexport function CircularLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('border-primary animate-spin rounded-full border-2 border-t-transparent', CIRCULAR_SIZE_CLASSES[size], className)}>\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function ClassicLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('relative', CLASSIC_SIZE_CLASSES[size], className)}>\n            <div className=\"absolute h-full w-full\">\n                {[...Array(12)].map((_, i) => (\n                    <div\n                        key={i}\n                        className=\"bg-primary absolute animate-[spinner-fade_1.2s_linear_infinite] rounded-full\"\n                        style={{\n                            top: '0',\n                            left: '50%',\n                            marginLeft: size === 'sm' ? '-0.75px' : size === 'lg' ? '-1.25px' : '-1px',\n                            transformOrigin: `${size === 'sm' ? '0.75px' : size === 'lg' ? '1.25px' : '1px'} ${size === 'sm' ? '10px' : size === 'lg' ? '14px' : '12px'}`,\n                            transform: `rotate(${i * 30}deg)`,\n                            opacity: 0,\n                            animationDelay: `${i * 0.1}s`,\n                            height: CLASSIC_BAR_SIZES[size].height,\n                            width: CLASSIC_BAR_SIZES[size].width,\n                        }}\n                    />\n                ))}\n            </div>\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function PulseLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('relative', PULSE_SIZE_CLASSES[size], className)}>\n            <div className=\"border-primary absolute inset-0 animate-[thin-pulse_1.5s_ease-in-out_infinite] rounded-full border-2\" />\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function PulseDotLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('bg-primary animate-[pulse-dot_1.2s_ease-in-out_infinite] rounded-full', PULSE_DOT_SIZE_CLASSES[size], className)}>\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function DotsLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('flex items-center space-x-1', DOTS_CONTAINER_SIZES[size], className)}>\n            {[...Array(3)].map((_, i) => (\n                <div\n                    key={i}\n                    className={cn('bg-primary animate-[bounce-dots_1.4s_ease-in-out_infinite] rounded-full', DOTS_DOT_SIZES[size])}\n                    style={{\n                        animationDelay: `${i * 160}ms`,\n                    }}\n                />\n            ))}\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function TypingLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('flex items-center space-x-1', TYPING_CONTAINER_SIZES[size], className)}>\n            {[...Array(3)].map((_, i) => (\n                <div\n                    key={i}\n                    className={cn('bg-primary animate-[typing_1s_infinite] rounded-full', TYPING_DOT_SIZES[size])}\n                    style={{\n                        animationDelay: `${i * 250}ms`,\n                    }}\n                />\n            ))}\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function WaveLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('flex items-center gap-0.5', WAVE_CONTAINER_SIZES[size], className)}>\n            {[...Array(5)].map((_, i) => (\n                <div\n                    key={i}\n                    className={cn('bg-primary animate-[wave_1s_ease-in-out_infinite] rounded-full', WAVE_BAR_WIDTHS[size])}\n                    style={{\n                        animationDelay: `${i * 100}ms`,\n                        height: WAVE_HEIGHTS[size][i],\n                    }}\n                />\n            ))}\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function BarsLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('flex', BARS_CONTAINER_SIZES[size], className)}>\n            {[...Array(3)].map((_, i) => (\n                <div\n                    key={i}\n                    className={cn('bg-primary h-full animate-[wave-bars_1.2s_ease-in-out_infinite]', BARS_BAR_WIDTHS[size])}\n                    style={{\n                        animationDelay: `${i * 0.2}s`,\n                    }}\n                />\n            ))}\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function TerminalLoader({ className, size = 'md' }: { className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('flex items-center space-x-1', TERMINAL_CONTAINER_SIZES[size], className)}>\n            <span className={cn('text-primary font-mono', TERMINAL_TEXT_SIZES[size])}>{'>'}</span>\n            <div className={cn('bg-primary animate-[blink_1s_step-end_infinite]', TERMINAL_CURSOR_SIZES[size])} />\n            <span className=\"sr-only\">Loading</span>\n        </div>\n    )\n}\n\nexport function TextBlinkLoader({ text = 'Thinking', className, size = 'md' }: { text?: string; className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return <div className={cn('animate-[text-blink_2s_ease-in-out_infinite] font-medium', TEXT_BLINK_TEXT_SIZES[size], className)}>{text}</div>\n}\n\nexport function TextShimmerLoader({ text = 'Thinking', className, size = 'md' }: { text?: string; className?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return <div className={cn('bg-[linear-gradient(to_right,var(--muted-foreground)_40%,var(--foreground)_60%,var(--muted-foreground)_80%)]', 'bg-size-[200%_auto] bg-clip-text font-medium text-transparent', 'animate-[shimmer_4s_infinite_linear]', TEXT_SHIMMER_TEXT_SIZES[size], className)}>{text}</div>\n}\n\nexport function TextDotsLoader({ className, text = 'Thinking', size = 'md' }: { className?: string; text?: string; size?: 'sm' | 'md' | 'lg' }) {\n    return (\n        <div className={cn('inline-flex items-center', className)}>\n            <span className={cn('text-primary font-medium', TEXT_DOTS_TEXT_SIZES[size])}>{text}</span>\n            <span className=\"inline-flex\">\n                <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.2s]\">.</span>\n                <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.4s]\">.</span>\n                <span className=\"text-primary animate-[loading-dots_1.4s_infinite_0.6s]\">.</span>\n            </span>\n        </div>\n    )\n}\n\nfunction Loader({ variant = 'circular', size = 'md', text, className }: LoaderProps) {\n    switch (variant) {\n        case 'circular':\n            return (\n                <CircularLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'classic':\n            return (\n                <ClassicLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'pulse':\n            return (\n                <PulseLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'pulse-dot':\n            return (\n                <PulseDotLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'dots':\n            return (\n                <DotsLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'typing':\n            return (\n                <TypingLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'wave':\n            return (\n                <WaveLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'bars':\n            return (\n                <BarsLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'terminal':\n            return (\n                <TerminalLoader\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'text-blink':\n            return (\n                <TextBlinkLoader\n                    text={text}\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'text-shimmer':\n            return (\n                <TextShimmerLoader\n                    text={text}\n                    size={size}\n                    className={className}\n                />\n            )\n        case 'loading-dots':\n            return (\n                <TextDotsLoader\n                    text={text}\n                    size={size}\n                    className={className}\n                />\n            )\n        default:\n            return (\n                <CircularLoader\n                    size={size}\n                    className={className}\n                />\n            )\n    }\n}\n\nexport { Loader }\n"}]}