|
| 1 | +import { Meta, Canvas, Story } from '@storybook/addon-docs/blocks' |
| 2 | +import AnimatedIcon from './index' |
| 3 | +import * as Stories from './AnimatedIcon.stories' |
| 4 | +import { Music, Heart, Play, Smartphone } from 'lucide-react' |
| 5 | + |
| 6 | +<Meta title="Stateless/AnimatedIcon" of={Stories} /> |
| 7 | + |
| 8 | +# AnimatedIcon |
| 9 | + |
| 10 | +A lightweight animated wrapper for icon components. Provides a small set of animation *variants* and *modes* and intentionally defaults to `mode="hover"` for performance. Animations respect the user's `prefers-reduced-motion` preference. |
| 11 | + |
| 12 | +import { ArgsTable } from '../../../storybook/ArgsTable' |
| 13 | + |
| 14 | +## Props |
| 15 | + |
| 16 | +<ArgsTable |
| 17 | + rows={[ |
| 18 | + { name: 'variant', type: "'spin' | 'pulse' | 'bounce' | 'draw'", default: "'spin'", description: 'Animation variant to apply to the icon.' }, |
| 19 | + { name: 'mode', type: "'hover' | 'auto' | 'idle'", default: "'hover'", description: 'How the animation is triggered: hover interactions, always running, or idle.' }, |
| 20 | + { name: 'className', type: 'string', default: "''", description: 'Additional className forwarded to the motion wrapper.' }, |
| 21 | + { name: 'children', type: 'React.ReactElement', default: '—', description: 'Icon element (SVG or icon component).' }, |
| 22 | + ]} |
| 23 | +/> |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Examples |
| 28 | + |
| 29 | +### Basic playground |
| 30 | + |
| 31 | +<Canvas> |
| 32 | + <Story name="Playground"> |
| 33 | + <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}> |
| 34 | + <AnimatedIcon variant="spin" mode="hover"><Music size={28} /></AnimatedIcon> |
| 35 | + <AnimatedIcon variant="pulse" mode="hover"><Heart size={28} /></AnimatedIcon> |
| 36 | + <AnimatedIcon variant="bounce" mode="hover"><Play size={28} /></AnimatedIcon> |
| 37 | + <AnimatedIcon variant="draw" mode="hover"><Music size={28} /></AnimatedIcon> |
| 38 | + </div> |
| 39 | + </Story> |
| 40 | +</Canvas> |
| 41 | + |
| 42 | +### Inline usage (code) |
| 43 | + |
| 44 | +```jsx |
| 45 | +<AnimatedIcon variant="spin" mode="hover"> |
| 46 | + <Music /> |
| 47 | +</AnimatedIcon> |
| 48 | +``` |
| 49 | + |
| 50 | +--- |
| 51 | + |
| 52 | +## Notes |
| 53 | + |
| 54 | +- **Accessibility:** If the icon is interactive (button/link), ensure it has an accessible name (aria-label or visible label). For purely decorative icons use `aria-hidden="true"` on the child SVG. |
| 55 | +- **Performance:** Prefer `mode="hover"` for many icons; reserve `mode="auto"` for isolated or small numbers of continuously-animated icons. |
| 56 | +- **Reduced motion:** Animations are disabled when `prefers-reduced-motion` is enabled on the user's system. |
| 57 | + |
| 58 | +> Tip: Use `variant="draw"` for decorative, one-off reveal animations and `variant="spin"` or `pulse` for status/feedback indicators. |
0 commit comments