'use client'; import { useState } from 'react'; import { AlertTriangle, CheckCircle, Clock, Crown, X, Zap } from 'lucide-react'; import { Badge } from '@kit/ui/badge'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@kit/ui/card'; import { Input } from '@kit/ui/input'; import { Label } from '@kit/ui/label'; import { Separator } from '@kit/ui/separator'; import { Switch } from '@kit/ui/switch'; import { cn } from '@kit/ui/utils'; import { generatePropsString, useStoryControls } from '../lib/story-utils'; import { ComponentStoryLayout } from './story-layout'; import { SimpleStorySelect } from './story-select'; interface BadgeControls { variant: 'default' | 'secondary' | 'destructive' | 'outline'; text: string; withIcon: boolean; iconPosition: 'left' | 'right'; size: 'default' | 'sm' | 'lg'; className: string; } const variantOptions = [ { value: 'default', label: 'Default', description: 'Primary badge style' }, { value: 'secondary', label: 'Secondary', description: 'Muted badge style' }, { value: 'destructive', label: 'Destructive', description: 'Error or warning style', }, { value: 'outline', label: 'Outline', description: 'Outlined badge style' }, ] as const; const sizeOptions = [ { value: 'sm', label: 'Small', description: 'Compact size' }, { value: 'default', label: 'Default', description: 'Standard size' }, { value: 'lg', label: 'Large', description: 'Larger size' }, ] as const; const iconOptions = [ { value: 'crown', icon: Crown, label: 'Crown' }, { value: 'zap', icon: Zap, label: 'Zap' }, { value: 'alert', icon: AlertTriangle, label: 'Alert' }, { value: 'check', icon: CheckCircle, label: 'Check' }, { value: 'clock', icon: Clock, label: 'Clock' }, { value: 'x', icon: X, label: 'X' }, ]; export function BadgeStory() { const { controls, updateControl } = useStoryControls({ variant: 'default', text: 'Badge', withIcon: false, iconPosition: 'left', size: 'default', className: '', }); const [selectedIcon, setSelectedIcon] = useState('crown'); const selectedIconData = iconOptions.find( (opt) => opt.value === selectedIcon, ); const IconComponent = selectedIconData?.icon || Crown; const generateCode = () => { const propsString = generatePropsString( { variant: controls.variant, className: cn( controls.className, controls.size === 'sm' && 'px-1.5 py-0.5 text-xs', controls.size === 'lg' && 'px-3 py-1 text-sm', ), }, { variant: 'default', className: '', }, ); let code = ``; if (controls.withIcon) { const iconName = selectedIconData?.icon.name || 'Crown'; if (controls.iconPosition === 'left') { code += `\n <${iconName} className="mr-1 h-3 w-3" />`; } } code += `\n ${controls.text}`; if (controls.withIcon && controls.iconPosition === 'right') { const iconName = selectedIconData?.icon.name || 'Crown'; code += `\n <${iconName} className="ml-1 h-3 w-3" />`; } code += `\n`; return code; }; const renderPreview = () => ( {controls.withIcon && controls.iconPosition === 'left' && ( )} {controls.text} {controls.withIcon && controls.iconPosition === 'right' && ( )} ); const renderControls = () => ( <>
updateControl('variant', value)} options={variantOptions} />
updateControl('size', value)} options={sizeOptions} />
updateControl('text', e.target.value)} placeholder="Enter badge text" />
updateControl('withIcon', checked)} />
{controls.withIcon && ( <>
({ value: opt.value, label: opt.label, description: `${opt.label} icon`, }))} />
updateControl('iconPosition', value)} options={[ { value: 'left', label: 'Left', description: 'Icon before text', }, { value: 'right', label: 'Right', description: 'Icon after text', }, ]} />
)}
updateControl('className', e.target.value)} placeholder="e.g. border-2 shadow-lg" />
); const renderExamples = () => (
Badge Variants Different badge styles
Default Secondary Destructive Outline
Badge Sizes Different badge sizes
Small Default Large
Badges with Icons Badges enhanced with icons
Premium Verified Warning New
); const renderApiReference = () => ( Badge Component Complete API reference for Badge component

Badge

A small labeled status indicator or category tag.

Prop Type Default Description
variant 'default' | 'secondary' | 'destructive' | 'outline' 'default' Visual style variant
className string - Additional CSS classes
children ReactNode - Badge content
); const renderUsageGuidelines = () => (
When to Use Badges Best practices for badge usage

✅ Use Badges For

  • • Status indicators (new, verified, premium)
  • • Category labels and tags
  • • Notification counts
  • • Feature flags and labels
  • • Version or type indicators

❌ Avoid Badges For

  • • Long text content (use cards instead)
  • • Interactive elements (use buttons instead)
  • • Main navigation items
Badge Hierarchy Using badge variants effectively
Default

Primary

Important status, featured items, primary categories

Secondary

Secondary

Supporting information, metadata, less prominent labels

Outline

Neutral

Subtle labels, optional information, inactive states

Destructive

Critical

Errors, warnings, urgent status, deprecated items

); return ( ); }