# Components — danchilton.com design system Every shared component, split into vendored shadcn primitives and project composites. Generated from source at build time, so it cannot drift from the code it describes. Rendered board: https://danchilton.com/styleguide/ ## Components Vendored into the repo under `src/shared/components/` and editable — they are not an installed package. The `$lib` alias maps to `src/shared`. ### Primitives — shadcn-svelte, vendored (23) `src/shared/components/ui/`. Stock shadcn-svelte. These carry the shared focus, sizing and disabled behaviour. - `alert` - `alert-dialog` - `badge` - `button` - `button-group` - `checkbox` - `dialog` - `dropdown-menu` - `input` - `label` - `native-select` - `popover` - `separator` - `sheet` - `sidebar` - `skeleton` - `sonner` - `spinner` - `switch` - `textarea` - `toggle` - `toggle-group` - `tooltip` **Button** variants: `default`, `outline`, `secondary`, `ghost`, `destructive`, `link` **Button** sizes: `default`, `xs`, `sm`, `lg`, `icon`, `icon-xs`, `icon-sm`, `icon-lg` **Badge** variants: `default`, `secondary`, `destructive`, `outline`, `ghost`, `success`, `warning`, `info`, `pending`, `link` — `success`/`warning`/`info` are project additions backed by the matching tokens. ### Composites — project-specific (19) `src/shared/components/`. Built on the primitives. These define what the apps actually look like, so they matter more than the primitives for matching the style. | Component | Props | | --- | --- | | **AppShell** | `appName`, `displayName`, `icon`, `addLabel`, `addIcon`, `onHomeClick`, `onAddClick`, `onSettingsClick`, `searchValue`, `onSearchInput`, `searchable`, `searchPlaceholder`, `searchFullWidth`, `hasAdd`, `hasSettings`, `sidebar`, `children` | | **BackLink** | `label`, `onclick` | | **ConfirmDeleteModal** | `open`, `onClose`, `onConfirm`, `title`, `message`, `confirmLabel`, `loading` | | **DeleteButton** | `variant`, `label`, `onclick`, `disabled`, `showIcon` | | **EmptyState** | `icon`, `title`, `description`, `action` | | **GroupLabel** | `use`, `sticky`, `children` | | **IconNameEditor** | `items`, `fallbackIcon`, `entityLabel`, `iconPlaceholder`, `emptyMessage`, `onSave`, `onDelete`, `deleteMessage` | | **ListRow** | `id`, `title`, `subtitle`, `leading`, `meta`, `trailing`, `layout`, `density`, `href`, `onclick`, `selectMode`, `checked`, `onCheckedChange`, `selected`, `disabled` | | **ListRowSkeleton** | `layout`, `density` | | **ListToolbar** | `filters`, `sort`, `view`, `select` | | **LucideIcon** | `name`, `strokeWidth` | | **Overlay** | `open`, `onClose`, `presentation`, `modal`, `size`, `responsive`, `title`, `subtitle`, `ariaLabel`, `dismissible`, `fill`, `header`, `headerActions`, `footer`, `children` | | **OverlayDetail** | `open`, `onClose`, `size`, `title`, `subtitle`, `ariaLabel`, `header`, `headerActions`, `footer`, `children` | | **PageHeader** | `title`, `scope`, `count`, `description`, `actions`, `toolbar` | | **SectionHeader** | `title`, `description`, `action` | | **SidebarItem** | `label`, `active`, `onclick`, `href`, `count`, `icon` | | **StatCard** | `label`, `value`, `caption`, `period`, `tone`, `secondary`, `children` | | **TagInput** | `selectedTags`, `allTags`, `onCreate`, `onchange`, `placeholder` | | **ViewBody** | `archetype`, `children` | ### Interaction states These do not appear in any screenshot, so they are easy to miss and easy to design away by accident: - **Row actions are hover-revealed on desktop, always visible on mobile.** `BookmarkRow` (archive/restore, open in new tab), `QuoteRow` (favourite) and `BookRow` (start/finish/reopen/queue) wrap their trailing actions in `md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100` on a `group` row. Focus-within is deliberate: the actions must reach the keyboard, not just the mouse. - Tag chips inside rows are buttons, and `stopPropagation` so they filter rather than opening the row. - Rows have a select mode that swaps the whole row click target for a checkbox. - Touch targets are `min-h-9` for pill nav items, `min-h-11`/`min-h-12` for primary actions. `AppShell` is the one to understand first: eight of the nine apps render inside it, so it defines the frame — collapsible sidebar, 4rem top bar with a pill search field, primary action button, and an app-switcher grid. Below the `md` breakpoint the sidebar goes off-canvas and the brand moves into the top bar.