` → CSS variable handles mode
WRONG: Using Dialog for destructive confirmations
RIGHT: Use AlertDialog — it prevents accidental dismissal
WRONG: String concatenation for classNames: `className={"p-4 " + props.className}`
RIGHT: Use cn() utility: `className={cn("p-4", props.className)}`
WRONG: `
` → no associated label
RIGHT: `
`
WRONG: Animating without checking preference
RIGHT: `const { shouldAnimate } = useMotionPreference()` → conditionally animate
---
## WHICH COMPONENT SHOULD I USE?
| Need | Use | Why |
|------|-----|-----|
| Confirm destructive action | AlertDialog (not Dialog) | Prevents accidental dismiss via overlay click |
| Side panel content | Sheet (not Drawer) | Sheet is for desktop, Drawer for mobile bottom sheets |
| Searchable dropdown | Combobox (not Select) | Combobox has built-in search/filter |
| Boolean toggle | Switch (not Checkbox) | Switch for instant effect, Checkbox for form submission |
| Multi-select | Checkbox group (not Select) | Select is single-value only |
| File upload | DragDrop from `@thesage/ui/dnd` | Handles drag events, accessible |
| Date selection | DatePicker from `@thesage/ui/dates` | Wraps Calendar + Popover |
| Data grid with sort/filter | DataTable from `@thesage/ui/tables` | Built on @tanstack/react-table |
| Form validation | Form from `@thesage/ui/forms` | Wraps react-hook-form + zod |
| Short notification | Sonner / Toast | Auto-dismisses, non-blocking |
| Important message | Alert | Persistent, stays visible in flow |
| Full-page modal | Dialog | Focus-trapped, centered overlay |
| Quick info on hover | Tooltip (desktop) / Popover (mobile) | Tooltip doesn't work on touch devices |
| Command palette / search | Command | Keyboard-driven, filterable list |
| Collapsible sections | Accordion (multiple) / Collapsible (single) | Accordion manages multiple panels |
---
## COMPOSITION COMPATIBILITY
### Safe combinations:
- Dialog + Form — common: form inside dialog
- Sheet + Tabs — common: tabbed side panel
- Card + Accordion — common: expandable card sections
- Sidebar + NavigationMenu — common: app navigation
- Popover + Command — common: searchable dropdown (this is how Combobox works internally)
- Card + Badge — common: status indicators on cards
- Table + Pagination — common: paginated data display
- Form + Select + Input — common: multi-field forms
- AlertDialog + Button variant="destructive" — common: delete confirmation
### Avoid these combinations:
- Drawer + Sheet — don't nest sliding overlays
- Dialog + Dialog — don't nest modal dialogs
- Tooltip inside Dialog — tooltip may disappear when dialog opens
- DropdownMenu inside Sheet — z-index conflicts possible
- Multiple Toaster instances — only render one Toaster at app root
### Use with care:
- Toast + Dialog — toast may appear behind dialog; ensure Toaster is at root level
- HoverCard + mobile — HoverCard doesn't work on touch devices; use Popover instead
- Combobox inside Dialog — keyboard events may conflict; test thoroughly
- Drawer on desktop — Drawer is designed for mobile; use Sheet on desktop
---
## BUNDLE ARCHITECTURE
SDE uses subpath exports to keep your bundle lean. Only import what you use:
| Import | Size (min+brotli) | What's Included |
|--------|-------------------|-----------------|
| `@thesage/ui` | ~146 KB | All 100 base components |
| `@thesage/ui/hooks` | ~40 KB | useTheme, useMotionPreference, useForm |
| `@thesage/ui/providers` | ~60 KB | ThemeProvider, TooltipProvider |
| `@thesage/ui/tokens` | ~70 KB | Design tokens (re-exported from @thesage/tokens) |
| `@thesage/ui/utils` | ~25 KB | cn(), parseCode, and utilities |
| `@thesage/ui/forms` | ~9 KB | Form integration (requires react-hook-form + zod) |
| `@thesage/ui/dates` | ~29 KB | Calendar, DatePicker (requires date-fns) |
| `@thesage/ui/tables` | ~8 KB | DataTable (requires @tanstack/react-table) |
| `@thesage/ui/dnd` | ~8 KB | DragDrop (requires @dnd-kit) |
| `@thesage/ui/webgl` | ~1 KB | WebGL components |
Heavy optional dependencies are peer deps — install only what your app needs.
### CVA Variant Exports
All CVA-based components export their variant definitions for custom composition:
```tsx
import { buttonVariants, badgeVariants, cardVariants, alertVariants } from '@thesage/ui'
import { toggleVariants } from '@thesage/ui'
import { sheetVariants } from '@thesage/ui'
import { labelVariants } from '@thesage/ui'
// Use variants without rendering the component
Link styled as button
```
---
# RESOURCES
- Docs: https://thesage.dev/docs/overview
- GitHub: https://github.com/shalomormsby/sage-design-engine
- NPM: https://www.npmjs.com/package/@thesage/ui
- MCP: https://www.npmjs.com/package/@thesage/mcp
- API JSON: https://thesage.dev/docs/api.json
- AI Plugin: https://thesage.dev/.well-known/ai-plugin.json
- MCP Discovery: https://thesage.dev/.well-known/mcp-server.json