Animation
Animation
Micro-interactions that feel natural. Zero dependencies.
Built-in Transitions
typescript
1import { Modal, Select, Button } from '@flint-ui/core'23// Modal — fade + scale on enter, fade + scale on exit4function Example() {5 const [open, setOpen] = useState(false)67 return (8 <>9 <Button onClick={() => setOpen(true)}>10 Open Modal11 </Button>1213 <Modal14 open={open}15 onClose={() => setOpen(false)}16 transition="scale" // 'scale' | 'slide' | 'fade'17 duration={200}18 >19 <Modal.Title>Confirm Action</Modal.Title>20 <Modal.Body>Are you sure?</Modal.Body>21 <Modal.Footer>22 <Button onClick={() => setOpen(false)}>Cancel</Button>23 <Button variant="primary">Confirm</Button>24 </Modal.Footer>25 </Modal>26 </>27 )28}2930// Select — dropdown slides in with spring physics31<Select32 options={options}33 transition="slide"34 transitionDuration={150}35/>3637// Button — press feedback scales to 0.9738<Button pressScale={0.97}>39 Click me40</Button>
Built-in transitions for Modal, Select, and Button
Custom Animations
typescript
1import { useTransition } from '@flint-ui/core'23function FadeIn({ show, children }: { show: boolean; children: React.ReactNode }) {4 const { mounted, style } = useTransition(show, {5 from: { opacity: 0, transform: 'translateY(8px)' },6 enter: { opacity: 1, transform: 'translateY(0px)' },7 exit: { opacity: 0, transform: 'translateY(-8px)' },8 duration: 200,9 })1011 if (!mounted) return null1213 return <div style={style}>{children}</div>14}1516// Usage17function App() {18 const [visible, setVisible] = useState(false)19 return (20 <>21 <Button onClick={() => setVisible((v) => !v)}>Toggle</Button>22 <FadeIn show={visible}>23 <Card>This fades in and out smoothly.</Card>24 </FadeIn>25 </>26 )27}
useTransition manages enter/exit states for any element
Reduced Motion
Flint UI respects prefers-reduced-motion automatically. All built-in animations are disabled when the user prefers reduced motion.
Important: If you add custom animations, always wrap them in a reduced motion check. Flint UI provides useReducedMotion() for this.
typescript
1import { useReducedMotion, useTransition } from '@flint-ui/core'23function AnimatedPanel({ show, children }: { show: boolean; children: React.ReactNode }) {4 const reducedMotion = useReducedMotion()56 const { mounted, style } = useTransition(show, {7 from: reducedMotion8 ? { opacity: 0 }9 : { opacity: 0, transform: 'scale(0.95)' },10 enter: reducedMotion11 ? { opacity: 1 }12 : { opacity: 1, transform: 'scale(1)' },13 exit: reducedMotion14 ? { opacity: 0 }15 : { opacity: 0, transform: 'scale(0.95)' },16 duration: reducedMotion ? 0 : 200,17 })1819 if (!mounted) return null20 return <div style={style}>{children}</div>21}
useReducedMotion gracefully degrades animations to opacity-only