@devalok/shilp-sutra 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +107 -0
- package/dist/_chunks/badge-group.js +48 -34
- package/dist/_chunks/badge-group.js.map +1 -1
- package/dist/_chunks/chat.js +91 -75
- package/dist/_chunks/chat.js.map +1 -1
- package/dist/_chunks/document-preview.js +1 -1
- package/dist/_chunks/document-preview.js.map +1 -1
- package/dist/_chunks/emoji-suggestion.js +1 -1
- package/dist/_chunks/emoji-suggestion.js.map +1 -1
- package/dist/_chunks/mention-suggestion.js +2 -2
- package/dist/_chunks/mention-suggestion.js.map +1 -1
- package/dist/_chunks/oauth-button.js +1 -1
- package/dist/_chunks/oauth-button.js.map +1 -1
- package/dist/_chunks/success.js +2 -2
- package/dist/_chunks/success.js.map +1 -1
- package/dist/_chunks/tree-view.js +1 -1
- package/dist/_chunks/tree-view.js.map +1 -1
- package/dist/_chunks/use-calendar.js +4 -4
- package/dist/_chunks/use-calendar.js.map +1 -1
- package/dist/ai/blocks/text.js +1 -1
- package/dist/ai/blocks/text.js.map +1 -1
- package/dist/ai/command-bar.js +9 -9
- package/dist/ai/command-bar.js.map +1 -1
- package/dist/ai/conversation.js +2 -2
- package/dist/ai/conversation.js.map +1 -1
- package/dist/composed/activity-feed.js +1 -1
- package/dist/composed/activity-feed.js.map +1 -1
- package/dist/composed/avatar-group.d.ts +7 -2
- package/dist/composed/avatar-group.d.ts.map +1 -1
- package/dist/composed/avatar-group.js +3 -3
- package/dist/composed/avatar-group.js.map +1 -1
- package/dist/composed/command-palette.js +7 -7
- package/dist/composed/command-palette.js.map +1 -1
- package/dist/composed/content-card.js +2 -2
- package/dist/composed/content-card.js.map +1 -1
- package/dist/composed/date-picker/index.js +4 -4
- package/dist/composed/date-picker/index.js.map +1 -1
- package/dist/composed/diff.d.ts +23 -2
- package/dist/composed/diff.d.ts.map +1 -1
- package/dist/composed/diff.js +341 -260
- package/dist/composed/diff.js.map +1 -1
- package/dist/composed/emoji-picker.js +3 -3
- package/dist/composed/emoji-picker.js.map +1 -1
- package/dist/composed/error-boundary.js +2 -2
- package/dist/composed/error-boundary.js.map +1 -1
- package/dist/composed/file-preview.js +1 -1
- package/dist/composed/file-preview.js.map +1 -1
- package/dist/composed/filter-bar.js +1 -1
- package/dist/composed/filter-bar.js.map +1 -1
- package/dist/composed/inline-edit.js +1 -1
- package/dist/composed/inline-edit.js.map +1 -1
- package/dist/composed/loading-skeleton.js +3 -3
- package/dist/composed/loading-skeleton.js.map +1 -1
- package/dist/composed/master-detail.js +1 -1
- package/dist/composed/master-detail.js.map +1 -1
- package/dist/composed/member-picker.js +1 -1
- package/dist/composed/member-picker.js.map +1 -1
- package/dist/composed/multi-select-popover.js +1 -1
- package/dist/composed/multi-select-popover.js.map +1 -1
- package/dist/composed/page-skeletons.js +4 -4
- package/dist/composed/page-skeletons.js.map +1 -1
- package/dist/composed/responsive-modal.js +1 -1
- package/dist/composed/responsive-modal.js.map +1 -1
- package/dist/composed/rich-chat-input.js +17 -17
- package/dist/composed/rich-chat-input.js.map +1 -1
- package/dist/composed/rich-text-editor.js +5 -5
- package/dist/composed/rich-text-editor.js.map +1 -1
- package/dist/composed/schedule-view.js +5 -5
- package/dist/composed/schedule-view.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +4 -3
- package/dist/hooks/use-container-size.d.ts +18 -0
- package/dist/hooks/use-container-size.d.ts.map +1 -0
- package/dist/hooks/use-container-size.js +28 -0
- package/dist/hooks/use-container-size.js.map +1 -0
- package/dist/shell/app-shell.d.ts +101 -0
- package/dist/shell/app-shell.d.ts.map +1 -0
- package/dist/shell/app-shell.js +76 -0
- package/dist/shell/app-shell.js.map +1 -0
- package/dist/shell/bottom-navbar.js +2 -2
- package/dist/shell/bottom-navbar.js.map +1 -1
- package/dist/shell/index.d.ts +1 -0
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +6 -5
- package/dist/shell/notification-center.js +4 -4
- package/dist/shell/notification-center.js.map +1 -1
- package/dist/shell/notification-preferences.js +1 -1
- package/dist/shell/notification-preferences.js.map +1 -1
- package/dist/shell/top-bar.js +7 -7
- package/dist/shell/top-bar.js.map +1 -1
- package/dist/tokens/generate-scale.d.ts +49 -0
- package/dist/tokens/generate-scale.d.ts.map +1 -1
- package/dist/tokens/primitives.css +29 -26
- package/dist/tokens/semantic.css +98 -39
- package/dist/tokens/variants.css +1 -1
- package/dist/ui/accordion.js +1 -1
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/alert-dialog.js +1 -1
- package/dist/ui/alert-dialog.js.map +1 -1
- package/dist/ui/alert.d.ts.map +1 -1
- package/dist/ui/alert.js +7 -7
- package/dist/ui/alert.js.map +1 -1
- package/dist/ui/avatar.js +3 -3
- package/dist/ui/avatar.js.map +1 -1
- package/dist/ui/badge-indicator.js +1 -1
- package/dist/ui/badge-indicator.js.map +1 -1
- package/dist/ui/badge.d.ts +47 -33
- package/dist/ui/badge.d.ts.map +1 -1
- package/dist/ui/banner.js +1 -1
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/button.js +4 -4
- package/dist/ui/button.js.map +1 -1
- package/dist/ui/card.js +4 -4
- package/dist/ui/card.js.map +1 -1
- package/dist/ui/chat/date-separator.d.ts +8 -1
- package/dist/ui/chat/date-separator.d.ts.map +1 -1
- package/dist/ui/checkbox.js +1 -1
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code.js +2 -2
- package/dist/ui/code.js.map +1 -1
- package/dist/ui/color-input.js +3 -3
- package/dist/ui/color-input.js.map +1 -1
- package/dist/ui/combobox.js +4 -4
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/context-menu.js +4 -4
- package/dist/ui/context-menu.js.map +1 -1
- package/dist/ui/data-table-body.d.ts +3 -1
- package/dist/ui/data-table-body.d.ts.map +1 -1
- package/dist/ui/data-table-body.js +93 -92
- package/dist/ui/data-table-body.js.map +1 -1
- package/dist/ui/data-table-bulk-actions.d.ts +7 -1
- package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
- package/dist/ui/data-table-bulk-actions.js +14 -8
- package/dist/ui/data-table-bulk-actions.js.map +1 -1
- package/dist/ui/data-table-card.d.ts.map +1 -1
- package/dist/ui/data-table-card.js +66 -47
- package/dist/ui/data-table-card.js.map +1 -1
- package/dist/ui/data-table-context.d.ts +4 -0
- package/dist/ui/data-table-context.d.ts.map +1 -1
- package/dist/ui/data-table-context.js.map +1 -1
- package/dist/ui/data-table-header.d.ts.map +1 -1
- package/dist/ui/data-table-header.js +18 -15
- package/dist/ui/data-table-header.js.map +1 -1
- package/dist/ui/data-table-pagination.js +3 -3
- package/dist/ui/data-table-pagination.js.map +1 -1
- package/dist/ui/data-table-toolbar.d.ts +11 -1
- package/dist/ui/data-table-toolbar.d.ts.map +1 -1
- package/dist/ui/data-table-toolbar.js +7 -7
- package/dist/ui/data-table-toolbar.js.map +1 -1
- package/dist/ui/data-table.d.ts +52 -5
- package/dist/ui/data-table.d.ts.map +1 -1
- package/dist/ui/data-table.js +181 -169
- package/dist/ui/data-table.js.map +1 -1
- package/dist/ui/dialog.js +1 -1
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dot.js +1 -1
- package/dist/ui/dot.js.map +1 -1
- package/dist/ui/dropdown-menu.js +4 -4
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/file-upload.js +3 -3
- package/dist/ui/file-upload.js.map +1 -1
- package/dist/ui/input-otp.js +1 -1
- package/dist/ui/input-otp.js.map +1 -1
- package/dist/ui/input.js +8 -8
- package/dist/ui/input.js.map +1 -1
- package/dist/ui/menubar.js +5 -5
- package/dist/ui/menubar.js.map +1 -1
- package/dist/ui/navigation-menu.js +1 -1
- package/dist/ui/navigation-menu.js.map +1 -1
- package/dist/ui/number-input.js +3 -3
- package/dist/ui/number-input.js.map +1 -1
- package/dist/ui/pagination.js +1 -1
- package/dist/ui/pagination.js.map +1 -1
- package/dist/ui/progress-ring.js +2 -2
- package/dist/ui/progress-ring.js.map +1 -1
- package/dist/ui/progress.d.ts.map +1 -1
- package/dist/ui/progress.js +16 -12
- package/dist/ui/progress.js.map +1 -1
- package/dist/ui/radio.js +1 -1
- package/dist/ui/radio.js.map +1 -1
- package/dist/ui/select.js +5 -5
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/sheet.js +1 -1
- package/dist/ui/sheet.js.map +1 -1
- package/dist/ui/sidebar.js +12 -12
- package/dist/ui/sidebar.js.map +1 -1
- package/dist/ui/slider.js +1 -1
- package/dist/ui/slider.js.map +1 -1
- package/dist/ui/split-button.js +3 -3
- package/dist/ui/split-button.js.map +1 -1
- package/dist/ui/stat-card.js +1 -1
- package/dist/ui/stat-card.js.map +1 -1
- package/dist/ui/stepper.js +2 -2
- package/dist/ui/stepper.js.map +1 -1
- package/dist/ui/surface.d.ts.map +1 -1
- package/dist/ui/surface.js +2 -2
- package/dist/ui/surface.js.map +1 -1
- package/dist/ui/switch.js +1 -1
- package/dist/ui/switch.js.map +1 -1
- package/dist/ui/table.js +1 -1
- package/dist/ui/table.js.map +1 -1
- package/dist/ui/tabs.d.ts.map +1 -1
- package/dist/ui/tabs.js +1 -1
- package/dist/ui/tabs.js.map +1 -1
- package/dist/ui/textarea.js +5 -5
- package/dist/ui/textarea.js.map +1 -1
- package/dist/ui/toast.js +1 -1
- package/dist/ui/toast.js.map +1 -1
- package/dist/ui/toggle.js +3 -3
- package/dist/ui/toggle.js.map +1 -1
- package/docs/components/composed/avatar-group.md +4 -4
- package/docs/components/composed/diff.md +10 -2
- package/docs/components/composed/schedule-view.md +1 -1
- package/docs/components/shell/app-shell.md +132 -0
- package/docs/components/ui/avatar.md +1 -1
- package/docs/components/ui/button.md +1 -1
- package/docs/components/ui/chat.md +7 -1
- package/docs/components/ui/color-swatch.md +1 -1
- package/docs/components/ui/data-table-toolbar.md +6 -2
- package/docs/components/ui/data-table.md +41 -7
- package/docs/components/ui/dot.md +1 -1
- package/docs/components/ui/progress.md +1 -0
- package/docs/components/ui/surface.md +3 -3
- package/docs/components/ui/table.md +2 -2
- package/docs/recipes/install-astro.md +1 -0
- package/docs/recipes/install-next-app-router.md +1 -0
- package/docs/recipes/install-remix.md +1 -0
- package/docs/recipes/install-tanstack-start.md +1 -0
- package/docs/recipes/install-vite.md +1 -0
- package/llms.txt +2 -1
- package/make-kit/Guidelines.md +2 -2
- package/make-kit/components/button.md +1 -1
- package/make-kit/components/card.md +6 -6
- package/make-kit/components/surface.md +4 -4
- package/make-kit/foundations/color.md +4 -4
- package/make-kit/foundations/dark-mode.md +1 -1
- package/make-kit/foundations/radius.md +1 -1
- package/make-kit/foundations/surfaces.md +9 -9
- package/mcp-manifest.json +350 -32
- package/package.json +6 -3
- package/skill/SKILL.md +12 -6
- package/skill/references/components.md +2 -1
- package/skill/references/setup-astro.md +1 -0
- package/skill/references/setup-next-app-router.md +1 -0
- package/skill/references/setup-remix.md +1 -0
- package/skill/references/setup-tanstack-start.md +1 -0
- package/skill/references/setup-vite.md +1 -0
- package/dist/primitives/react-toast.d.ts +0 -120
- package/dist/ui/charts/_internal/scales.d.ts +0 -5
- package/dist/ui/charts/_internal/scales.d.ts.map +0 -1
- package/dist/ui/lib/slot.d.ts +0 -8
- package/dist/ui/lib/slot.d.ts.map +0 -1
|
@@ -5,20 +5,23 @@
|
|
|
5
5
|
- Category: ui
|
|
6
6
|
|
|
7
7
|
## Props
|
|
8
|
-
columns: ColumnDef<TData>[] (TanStack column definitions)
|
|
8
|
+
columns: ColumnDef<TData, TValue>[] (TanStack column definitions)
|
|
9
9
|
data: TData[]
|
|
10
|
+
className: string — class name for the wrapper div
|
|
10
11
|
sortable: boolean — enable column sorting
|
|
11
|
-
onSort: (key: string,
|
|
12
|
+
onSort: (key: string, direction: 'asc' | 'desc' | false) => void — server-side sort callback (enables manualSorting)
|
|
12
13
|
filterable: boolean — enable per-column filters
|
|
14
|
+
filterableColumns: string[] — restrict filter inputs to these column IDs (only with filterable; omit for all filterable columns)
|
|
13
15
|
globalFilter: boolean — enable global search
|
|
14
16
|
paginated: boolean — enable client-side pagination
|
|
15
17
|
pagination: { page: number, pageSize: number, total: number, onPageChange: (page: number) => void } — server-side pagination (1-based page)
|
|
16
18
|
pageSize: number (default 10)
|
|
19
|
+
pageSizeOptions: number[] — page-size selector options (default [10, 20, 50, 100])
|
|
17
20
|
selectable: boolean — enable row selection with checkboxes
|
|
18
21
|
selectedIds: Set<string> — controlled selection state
|
|
19
22
|
selectableFilter: (row: TData) => boolean — disable selection on certain rows
|
|
20
23
|
getRowId: (row: TData) => string — custom row ID accessor
|
|
21
|
-
onSelectionChange: (selectedRows: TData[]) => void
|
|
24
|
+
onSelectionChange: (selectedRows: TData[], selectedIds: Set<string>) => void — does NOT fire on mount
|
|
22
25
|
expandable: boolean — enable row expansion
|
|
23
26
|
renderExpanded: (row: TData) => ReactNode — expanded row content
|
|
24
27
|
singleExpand: boolean — only one row expanded at a time
|
|
@@ -27,15 +30,23 @@
|
|
|
27
30
|
noResultsText: string (default "No results.")
|
|
28
31
|
stickyHeader: boolean — sticky table header
|
|
29
32
|
onRowClick: (row: TData) => void — row click handler (excludes interactive element clicks)
|
|
30
|
-
|
|
33
|
+
rowClassName: (row: TData) => string | undefined — conditional per-row class (the <tr> in table mode, the Card in card mode)
|
|
34
|
+
bulkActions: BulkAction<TData>[] — floating action bar on selection — { label, onClick, icon?: IconInput, color?: 'accent'|'error', disabled? }
|
|
35
|
+
bulkActionsPosition: 'bottom' | 'top' | 'inline' — where the bulk-actions bar renders (default 'bottom')
|
|
31
36
|
toolbar: boolean — show DataTableToolbar (column visibility, density, CSV export)
|
|
37
|
+
enableExport: boolean — show the toolbar's Export CSV button (default true)
|
|
38
|
+
onExport: (visibleRows: TData[]) => void — replace the built-in CSV export
|
|
32
39
|
editable: boolean — enable double-click cell editing
|
|
40
|
+
onCellEdit: (rowIndex: number, columnId: string, value: unknown) => void — fired on cell edit commit
|
|
33
41
|
virtualRows: boolean — virtualize rows for large datasets
|
|
42
|
+
virtualRowHeight: number — ESTIMATED row height in px (default 48); real heights are measured after mount
|
|
43
|
+
maxHeight: number — max height of the virtual scroll container in px (default 600)
|
|
44
|
+
mobileView: 'card' | 'table' — stacked cards below the sm breakpoint (default 'table')
|
|
34
45
|
columnPinning: { left?: string[], right?: string[] }
|
|
35
46
|
density: 'compact' | 'standard' | 'comfortable'
|
|
36
47
|
|
|
37
48
|
## Defaults
|
|
38
|
-
pageSize=10, noResultsText="No results."
|
|
49
|
+
pageSize=10, noResultsText="No results.", enableExport=true, mobileView='table', virtualRowHeight=48, maxHeight=600, density='standard'
|
|
39
50
|
|
|
40
51
|
## Example
|
|
41
52
|
```jsx
|
|
@@ -75,7 +86,11 @@ import { DataTable } from '@devalok/shilp-sutra/ui/data-table'
|
|
|
75
86
|
**Row click model:**
|
|
76
87
|
- `onRowClick` fires on row-level click BUT excludes clicks on checkboxes, buttons, links, and inputs automatically. No manual `stopPropagation` needed for standard interactive elements.
|
|
77
88
|
|
|
78
|
-
**Virtualization:** `virtualRows={true}` enables row virtualization via `@tanstack/react-virtual`. Turn it on for 1000+ row datasets; the scroll container must have a bounded height.
|
|
89
|
+
**Virtualization:** `virtualRows={true}` enables row virtualization via `@tanstack/react-virtual`. Turn it on for 1000+ row datasets; the scroll container must have a bounded height. Rows stay in normal table flow (each windowed row is its own `<tbody>` measured by the virtualizer, with spacer row groups reserving the un-rendered remainder), so column widths keep tracking `<thead>` and `virtualRowHeight` is only the pre-measurement estimate.
|
|
90
|
+
|
|
91
|
+
**Virtualization + expansion:** `virtualRows` and `expandable` compose. Because each row group is measured, an expanded detail panel of any height contributes to the total scroll size and pushes the rows below it down. The reveal is instant in virtual mode (no height animation) — an animating height would fire a resize on every frame.
|
|
92
|
+
|
|
93
|
+
**Toolbar export:** the Export button renders whenever `toolbar` is on. The built-in CSV export walks `getFilteredRowModel()`, which under server-side `pagination` is only the current page — pass `onExport` to fetch the full set yourself, or `enableExport={false}` to drop the button.
|
|
79
94
|
|
|
80
95
|
**Density integration:** density is forwarded to `Table`'s `density` prop, which sets `--table-py` (compact 4 / standard 8 / comfortable 12px → rows ≈ 29 / 37 / 45px; header tracks it). DataTableToolbar's density switcher updates this at runtime; the prop sets the initial state only.
|
|
81
96
|
|
|
@@ -88,13 +103,32 @@ import { DataTable } from '@devalok/shilp-sutra/ui/data-table'
|
|
|
88
103
|
- onRowClick does NOT fire when clicking checkboxes, buttons, links, or inputs
|
|
89
104
|
- Use density="compact" for Karm-style h-9 rows
|
|
90
105
|
- `virtualRows={true}` requires a bounded scroll container — unbounded height silently disables virtualization
|
|
106
|
+
- `onSelectionChange` does NOT fire on mount, and does NOT fire when selection is synced from the `selectedIds` prop — only on genuine selection changes
|
|
107
|
+
- `filterableColumns` is ignored unless `filterable` is also set
|
|
108
|
+
- `rowClassName` returns are passed through `cn()` verbatim — a class that does not exist in the token set silently does nothing (use the real scale steps, e.g. `bg-error-3`, not invented names like `bg-error-subtle`)
|
|
91
109
|
|
|
92
110
|
## Changes
|
|
111
|
+
### Unreleased
|
|
112
|
+
- **Added** `bulkActions[].icon?: IconInput` — icon rendered before the label in a bulk-action button.
|
|
113
|
+
- **Added** `bulkActionsPosition?: 'bottom' | 'top' | 'inline'` — where the bulk-actions bar renders (default `'bottom'`, matching prior behavior).
|
|
114
|
+
|
|
115
|
+
### v0.57.0
|
|
116
|
+
- **Fixed** `onSelectionChange` no longer fires on mount with `[]` — first-render guard added. Root cause of the cascade reported in #213.
|
|
117
|
+
- **Fixed** `virtualRows + expandable` was a silent no-op — the expanded row was only rendered on the non-virtual path. Virtual rows now render one measured `<tbody>` per windowed row (with spacer row groups for the remainder) so the expanded panel renders, contributes its real height to `getTotalSize()`, and cannot overlap the row below.
|
|
118
|
+
- **Changed** Virtual rows are no longer absolutely positioned with a forced `virtualRowHeight`; they sit in normal table flow at their measured height, so column widths track `<thead>`. `virtualRowHeight` is now the pre-measurement ESTIMATE.
|
|
119
|
+
- **Fixed** `enableExport` was stranded on `DataTableToolbar` and never wired through `DataTableProps`. Now exposed with an `onExport` override. Default is unchanged (`true`) — the Export button still renders whenever `toolbar` is on.
|
|
120
|
+
- **Fixed** `filterable + mobileView="card"` rendered no filter inputs — they now render above the card list in `DataTableCards` (card mode renders no `<thead>` for them to live in).
|
|
121
|
+
- **Added** `onSelectionChange` receives `selectedIds: Set<string>` as second argument — complement of the `selectedIds` prop.
|
|
122
|
+
- **Added** `filterableColumns?: string[]` — restrict filter inputs to specific column IDs.
|
|
123
|
+
- **Added** `rowClassName?: (row: TData) => string | undefined` — conditional row classes in table and card layouts.
|
|
124
|
+
- **Added** `enableExport?: boolean` — hide the toolbar's Export CSV button from `DataTableProps`.
|
|
125
|
+
- **Added** `onExport?: (visibleRows: TData[]) => void` — override built-in CSV with a custom export handler.
|
|
126
|
+
|
|
93
127
|
### v0.45.0
|
|
94
128
|
- **Fixed** Expander a11y per the expando-row spec: `aria-expanded` on the toggle button, visually-hidden "Expand rows" column header; chevron rotation uses `duration-fast-02 ease-productive-standard`.
|
|
95
129
|
- **Added** Expanded-row content animates open/closed (height + opacity via framer, `springs.smooth`), self-guarded with `useReducedMotion` — instant swap for reduced-motion users. Virtualized tables keep the instant reveal (a height animation would fight the virtualizer's measurements).
|
|
96
130
|
- **Changed** Density now drives Table's `--table-py` variable (rows ≈ 29 / 37 / 45px; was 29 / 53 / 85). Per-cell `cellPadding` threading removed from context.
|
|
97
|
-
- **Fixed** Hover/selected states visible on cards: row/sort-button/expander hover use `surface-
|
|
131
|
+
- **Fixed** Hover/selected states visible on cards: row/sort-button/expander hover use `surface-panel-hover` (was the invisible `surface-panel`); expanded row is a `surface-base` recess; sticky header bg is `surface-panel`; empty state uses `py-ds-07` (was raw `h-24`).
|
|
98
132
|
- **Changed** Mobile card view composes `<Card size="sm" variant="outline">` (was a hand-rolled 12px bordered box).
|
|
99
133
|
|
|
100
134
|
### v0.29.0
|
|
@@ -49,7 +49,7 @@ sized, optionally pulsing, filled or ring.
|
|
|
49
49
|
- **`pulse` = "live".** Off by default (static status). Turn it on for active/attention states (recording, live, connecting) — a pulsing dot reads as "happening now", so leave it off for settled statuses.
|
|
50
50
|
- **Powers the higher-level pieces.** `StatusBadge` composes `<Badge>` + `<Dot>`; use `Dot` directly anywhere you need a coloured indicator without a pill.
|
|
51
51
|
- **Three treatments:** `filled` (active), `ring` (hollow outline), `off` (faint same-tone fill + light border — present but inactive/disabled).
|
|
52
|
-
- **`withBorder`** adds a contrast ring (`ring-2 ring-surface-
|
|
52
|
+
- **`withBorder`** adds a contrast ring (`ring-2 ring-surface-panel`) so the dot reads on avatars, images, or coloured fills — the pattern Avatar's status dot uses.
|
|
53
53
|
- **`pulseSpeed`** (slow/normal/fast) tunes the pulse tempo — fast for urgent (recording), slow for ambient (syncing).
|
|
54
54
|
|
|
55
55
|
## Gotchas
|
|
@@ -66,6 +66,7 @@ common cases, or the compound parts (`Progress.Root` / `Track` / `Indicator` /
|
|
|
66
66
|
- Omit `value` (or pass `null`) for indeterminate.
|
|
67
67
|
- Pass an explicit `color` to override `autoColor`.
|
|
68
68
|
- Compound `Progress.Track` needs a name — an `aria-label`, or a `Progress.Label` whose `id` the Track's `aria-labelledby` points to. A Track with neither is an unnamed progressbar (axe will flag it).
|
|
69
|
+
- **`<Progress value={72} />` with no name warns in DEV.** `aria-valuenow` already carries the number, so an unnamed bar announces as "progressbar, 72%" — the reader learns the value but not *what* is progressing. Pass `label` (renders visible text and wires `aria-labelledby`) or `aria-label` when the bar must stay visually unlabelled. The component deliberately does **not** invent a default like "Progress: 72%": that would silence the audit while leaving the announcement equally uninformative, and only you know what the bar measures. Warns once per session, not per render.
|
|
69
70
|
- `Progress.Indicator` / `Segment` / `Value` throw if rendered outside `Progress.Root`.
|
|
70
71
|
|
|
71
72
|
## Changes
|
|
@@ -18,8 +18,8 @@ The low-level elevated container primitive. Owns background + shadow + radius +
|
|
|
18
18
|
Surface: elevation="raised", padding="none", radius="surface", bordered=false
|
|
19
19
|
|
|
20
20
|
## Elevation
|
|
21
|
-
flat — bg-surface-
|
|
22
|
-
raised — bg-surface-
|
|
21
|
+
flat — bg-surface-panel, no shadow (pair with `bordered` for an on-page tile)
|
|
22
|
+
raised — bg-surface-panel + shadow-raised (card level)
|
|
23
23
|
floating — bg-surface-overlay + shadow-floating (toasts, floating toolbars)
|
|
24
24
|
overlay — bg-surface-overlay + shadow-overlay (popovers, menus, dialogs)
|
|
25
25
|
|
|
@@ -48,7 +48,7 @@ The low-level elevated container primitive. Owns background + shadow + radius +
|
|
|
48
48
|
|
|
49
49
|
## Gotchas
|
|
50
50
|
- **Edge OR elevation, never both.** Combining `bordered` with a shadowed elevation (raised/floating/overlay) is the double-edge anti-pattern and dev-warns. Use `elevation="flat"` with `bordered`, or drop `bordered` and let the shadow be the edge.
|
|
51
|
-
- `flat` still uses `bg-surface-
|
|
51
|
+
- `flat` still uses `bg-surface-panel` (a card without a shadow), not the page background — it is a surface, not a hole.
|
|
52
52
|
|
|
53
53
|
## Changes
|
|
54
54
|
### Unreleased
|
|
@@ -106,12 +106,12 @@ See the `RichCells` story for all of these live.
|
|
|
106
106
|
- **Added** `TableRowLink` (ui/table-row-link) — real-anchor whole-row navigation with pseudo-element stretch (Safari-safe: anchored to the cell, clipped by the table's `overflow-x-clip`), row-level focus ring, `stretch={false}` title-only mode.
|
|
107
107
|
- **Added** `TableRowActions` — hover/focus-revealed action cluster (opacity reveal, permanently tabbable, `:focus-within` + touch fallbacks, `persist` mode).
|
|
108
108
|
- **Added** `numeric` prop on TableCell/TableHead — right-align + tabular figures.
|
|
109
|
-
- **Fixed** TableFooter background was `color-mix(surface-
|
|
109
|
+
- **Fixed** TableFooter background was `color-mix(surface-panel 50%)` — invisible on cards (same mis-mapped shadcn `muted/50` family as the row hover). Now a `surface-base` band with a top hairline.
|
|
110
110
|
- **Fixed** Selected+hover tie: selected rows get an explicit `hover:bg-accent-4` step (hover and selected previously tied on specificity).
|
|
111
111
|
- **Added** Cell recipes section (user cell, tag overflow, money, empty-dash) + density→avatar mapping; `RichCells` / `SelectedRows` stories.
|
|
112
112
|
- **Added** `density` prop (`compact | standard | comfortable`) via `--table-py`; header height tracks density instead of a fixed 40px
|
|
113
113
|
- **Added** `striped` prop — opt-in zebra
|
|
114
|
-
- **Changed** Rows regain their hairline separator (`border-b border-surface-border-subtle` — lost in the original port) and hover becomes visible on cards (`hover:bg-surface-
|
|
114
|
+
- **Changed** Rows regain their hairline separator (`border-b border-surface-border-subtle` — lost in the original port) and hover becomes visible on cards (`hover:bg-surface-panel-hover`, was the invisible `surface-panel`)
|
|
115
115
|
- **Changed** Cells: `px-ds-04` interior, first/last cells read `--table-edge` (= `--card-spacing` inside a Card); header drops to `text-ds-sm` muted
|
|
116
116
|
- **Changed** Default vertical rhythm tightens: standard rows ~53px → ~37px
|
|
117
117
|
|
|
@@ -39,6 +39,7 @@ Some components ship hard peers as optional. **Install BEFORE first import.**
|
|
|
39
39
|
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
40
40
|
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
41
41
|
| `@devalok/shilp-sutra/composed/rich-chat-input` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion date-fns` |
|
|
42
|
+
| `@devalok/shilp-sutra/composed/diff` | `pnpm add react-syntax-highlighter` |
|
|
42
43
|
| `@devalok/shilp-sutra/composed/rich-text-editor` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion` |
|
|
43
44
|
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
44
45
|
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
@@ -52,6 +52,7 @@ Some components depend on third-party libraries that ship as optional peers. **I
|
|
|
52
52
|
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
53
53
|
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
54
54
|
| `@devalok/shilp-sutra/composed/rich-chat-input` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion date-fns` |
|
|
55
|
+
| `@devalok/shilp-sutra/composed/diff` | `pnpm add react-syntax-highlighter` |
|
|
55
56
|
| `@devalok/shilp-sutra/composed/rich-text-editor` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion` |
|
|
56
57
|
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
57
58
|
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
@@ -35,6 +35,7 @@ Some components ship hard peers as optional. **Install BEFORE first import.**
|
|
|
35
35
|
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
36
36
|
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
37
37
|
| `@devalok/shilp-sutra/composed/rich-chat-input` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion date-fns` |
|
|
38
|
+
| `@devalok/shilp-sutra/composed/diff` | `pnpm add react-syntax-highlighter` |
|
|
38
39
|
| `@devalok/shilp-sutra/composed/rich-text-editor` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion` |
|
|
39
40
|
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
40
41
|
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
@@ -44,6 +44,7 @@ Some components ship hard peers as optional. **Install BEFORE first import.**
|
|
|
44
44
|
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
45
45
|
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
46
46
|
| `@devalok/shilp-sutra/composed/rich-chat-input` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion date-fns` |
|
|
47
|
+
| `@devalok/shilp-sutra/composed/diff` | `pnpm add react-syntax-highlighter` |
|
|
47
48
|
| `@devalok/shilp-sutra/composed/rich-text-editor` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion` |
|
|
48
49
|
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
49
50
|
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
|
@@ -50,6 +50,7 @@ Some components ship hard peers as optional. **Install BEFORE first import.**
|
|
|
50
50
|
| `@devalok/shilp-sutra/composed/file-preview` | `pnpm add react-pdf react-zoom-pan-pinch` |
|
|
51
51
|
| `@devalok/shilp-sutra/composed/markdown-viewer` | `pnpm add react-markdown react-syntax-highlighter remark-gfm` |
|
|
52
52
|
| `@devalok/shilp-sutra/composed/rich-chat-input` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion date-fns` |
|
|
53
|
+
| `@devalok/shilp-sutra/composed/diff` | `pnpm add react-syntax-highlighter` |
|
|
53
54
|
| `@devalok/shilp-sutra/composed/rich-text-editor` | `pnpm add @tiptap/core @tiptap/extension-highlight @tiptap/extension-image @tiptap/extension-list @tiptap/extension-mention @tiptap/extension-text-align @tiptap/extensions @tiptap/markdown @tiptap/pm @tiptap/react @tiptap/starter-kit @tiptap/suggestion` |
|
|
54
55
|
| `@devalok/shilp-sutra/composed/schedule-view` | `pnpm add date-fns` |
|
|
55
56
|
| `@devalok/shilp-sutra/ui/charts` | `pnpm add d3-axis d3-scale d3-selection d3-shape` |
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @devalok/shilp-sutra
|
|
2
2
|
|
|
3
|
-
> Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.
|
|
3
|
+
> Radix UI + Tailwind 4 (CSS-first) + CVA design system for Devalok apps, v0.57.0.
|
|
4
4
|
> Built on the same primitives as shadcn/ui but with DIFFERENT prop APIs — never guess from shadcn knowledge; verify every prop.
|
|
5
5
|
> This file is a ROUTER: it tells you what exists and where to get details. Do not look for prop tables here — fetch them per component (MCP tool or per-component doc file below).
|
|
6
6
|
|
|
@@ -152,6 +152,7 @@ Format: `[name](doc path): summary`. Import paths follow `@devalok/shilp-sutra/<
|
|
|
152
152
|
|
|
153
153
|
### shell
|
|
154
154
|
- [app-command-palette](docs/components/shell/app-command-palette.md)
|
|
155
|
+
- [app-shell](docs/components/shell/app-shell.md)
|
|
155
156
|
- [bottom-navbar](docs/components/shell/bottom-navbar.md)
|
|
156
157
|
- [command-registry](docs/components/shell/command-registry.md): Exports: CommandRegistryProvider, useCommandRegistry
|
|
157
158
|
- [link-context](docs/components/shell/link-context.md): Exports: LinkProvider, useLink
|
package/make-kit/Guidelines.md
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
These are not preferences. Generated code that violates them is wrong.
|
|
23
23
|
|
|
24
24
|
1. **Use design system components, not raw HTML.** `<Button>` not `<button>`. `<Input>` not `<input>`. `<Text>` not `<span>`/`<p>` (when typographic semantics matter). `<Stack>` not bare flex divs.
|
|
25
|
-
2. **Use semantic tokens, never hex / rgb / hsl.** `bg-surface-
|
|
25
|
+
2. **Use semantic tokens, never hex / rgb / hsl.** `bg-surface-panel` not `bg-white`. `text-fg` not `text-zinc-900`. `bg-accent-9` not `bg-pink-500`.
|
|
26
26
|
3. **Spacing uses `ds-*` cadence.** `p-ds-05`, `gap-ds-03`. Never `p-4` / `p-6`. Default cadence is `ds-03 / ds-05 / ds-07` (related items / grouped sections / page sections). Do not reach for every adjacent token (`ds-04`, `ds-06`) — three tiers, not five.
|
|
27
27
|
4. **Prefer `variant="soft"` over `variant="outline"` for non-primary actions.** Soft (tinted bg, no visible border) reads better in data-dense UIs. Outline only when on a colored bg or paired with a primary for explicit hierarchy.
|
|
28
|
-
5. **Surface layering is strict.** Page = `surface-base`. Cards/panels/widgets = `surface-
|
|
28
|
+
5. **Surface layering is strict.** Page = `surface-base`. Cards/panels/widgets = `surface-panel`. Dialogs/popovers/dropdowns/inputs = `surface-overlay`. Shell chrome (sidebar, topbar) = `surface-sunken`. Tooltips = `surface-inverted`. If you're unsure, read `foundations/surfaces.md`.
|
|
29
29
|
6. **Never combine `border-*` + `shadow-*` tokens.** Shadow tokens already include a 1px ring layer. Adding an explicit border creates a 2-px edge.
|
|
30
30
|
7. **Icons use `<Icon icon={...} />` from `@tabler/icons-react`.** Do not import lucide, heroicons, mui-icons. The icon system auto-sizes via `IconProvider` context.
|
|
31
31
|
8. **Toasts mount once at app root.** `<Toaster />` (singleton). All triggering is imperative: `toast.success("...")`, `toast.error("...")`.
|
|
@@ -19,7 +19,7 @@ import { Button } from '@devalok/shilp-sutra/ui/button'
|
|
|
19
19
|
|---|---|
|
|
20
20
|
| `solid` (default) | Primary CTA. One per region. Heavy visual weight. |
|
|
21
21
|
| `soft` | Secondary action. **Preferred default for any non-primary action.** Tinted bg, colored text, no visible border — warmer than outline, brand-consistent. |
|
|
22
|
-
| `outline` | Secondary action on a colored / `surface-
|
|
22
|
+
| `outline` | Secondary action on a colored / `surface-panel` bg where soft's tint disappears. In toolbars / icon-dense rows. Paired adjacent to a primary that needs explicit hierarchy. |
|
|
23
23
|
| `ghost` | Tertiary / dismissive — close, cancel, skip. Minimal weight. |
|
|
24
24
|
| `link` | Inline action that should read as a link but behave as a button. Use sparingly. |
|
|
25
25
|
|
|
@@ -20,18 +20,18 @@ import {
|
|
|
20
20
|
|
|
21
21
|
- Any rectangular region that reads as a discrete unit on the page: dashboards widgets, list items, marketing feature blocks.
|
|
22
22
|
- Header / actions / footer are built in as slots (`CardHeader`, `CardAction`, `CardFooter`) — don't reach for a wrapper. (`<ContentCard>` is deprecated; use Card slots.)
|
|
23
|
-
- Need just a tinted region with no card affordance? Use a `<div className="bg-surface-
|
|
23
|
+
- Need just a tinted region with no card affordance? Use a `<div className="bg-surface-panel">` (rare; usually Card is right).
|
|
24
24
|
|
|
25
|
-
Card renders on `surface-
|
|
25
|
+
Card renders on `surface-panel`. The `default` variant is tonal — a surface-tone shift plus a whisper hairline (`border-card`), no shadow. **Never** override its background or border.
|
|
26
26
|
|
|
27
27
|
## Variants
|
|
28
28
|
|
|
29
29
|
| Variant | Use |
|
|
30
30
|
|---|---|
|
|
31
|
-
| `default` (default) | `surface-
|
|
31
|
+
| `default` (default) | `surface-panel` + tonal `border-card` hairline, no shadow. Standard card — depth from tone, not a drop shadow. |
|
|
32
32
|
| `elevated` | `shadow-raised-hover`, no border. Use when a card must visibly pop (hero, dragged tile, spotlight panel). |
|
|
33
|
-
| `outline` | `surface-
|
|
34
|
-
| `flat` | `surface-
|
|
33
|
+
| `outline` | `surface-panel` + strong border-only (no shadow). Dense lists where stacked shadowed cards would feel too lifted. |
|
|
34
|
+
| `flat` | `surface-panel` + no shadow, no border. For cards inside an already-elevated container. |
|
|
35
35
|
|
|
36
36
|
## Colors
|
|
37
37
|
|
|
@@ -186,7 +186,7 @@ wrap the text column in `<CardSection>`, which re-establishes py + gap from the
|
|
|
186
186
|
|
|
187
187
|
## Rules
|
|
188
188
|
|
|
189
|
-
- **Never** `bg-surface-base` on a Card — cards sit on `surface-
|
|
189
|
+
- **Never** `bg-surface-base` on a Card — cards sit on `surface-panel`. The pre-publish audit rejects this.
|
|
190
190
|
- **Never** combine `border-*` + `shadow-*` on a Card. Pick one (Card already does — don't override).
|
|
191
191
|
- **Use `interactive` + `onClick` + `aria-label`** for clickable cards. Don't wrap a Card in a `<button>` — broken nesting.
|
|
192
192
|
- **`size` on Card** drives all spacing via `--card-spacing`. Never set `p-*` on Card or a slot — override the variable if a one-off is truly needed.
|
|
@@ -9,7 +9,7 @@ The low-level elevated container. It paints a tokened surface — background + s
|
|
|
9
9
|
## When to use
|
|
10
10
|
|
|
11
11
|
- You need a plain elevated box (a promo, a callout, a small panel) and don't need Card's header/content/footer slots.
|
|
12
|
-
- You're building a new component that sits on a surface — compose `Surface`, never hand-roll `bg-surface-
|
|
12
|
+
- You're building a new component that sits on a surface — compose `Surface`, never hand-roll `bg-surface-panel … shadow-raised`.
|
|
13
13
|
|
|
14
14
|
Use `<Card>` instead when you want the gap-model padding rhythm and the `CardHeader`/`CardContent`/`CardFooter` slots. Use raw utilities for nothing — if it's a surface, it's a `Surface`.
|
|
15
15
|
|
|
@@ -17,8 +17,8 @@ Use `<Card>` instead when you want the gap-model padding rhythm and the `CardHea
|
|
|
17
17
|
|
|
18
18
|
| `elevation` | Surface | Use for |
|
|
19
19
|
|---|---|---|
|
|
20
|
-
| `flat` | `bg-surface-
|
|
21
|
-
| `raised` *(default)* | `bg-surface-
|
|
20
|
+
| `flat` | `bg-surface-panel`, no shadow | On-page tiles. Pair with `bordered` for an edge. |
|
|
21
|
+
| `raised` *(default)* | `bg-surface-panel` + `shadow-raised` | Cards, panels — anything sitting on the page. |
|
|
22
22
|
| `floating` | `bg-surface-overlay` + `shadow-floating` | Toasts, floating toolbars. |
|
|
23
23
|
| `overlay` | `bg-surface-overlay` + `shadow-overlay` | Popovers, menus, dialogs. |
|
|
24
24
|
|
|
@@ -55,6 +55,6 @@ Plus all native `div` props. Server-safe; forwards ref.
|
|
|
55
55
|
## Rules
|
|
56
56
|
|
|
57
57
|
- **Edge OR elevation, never both.** `bordered` + a shadowed `elevation` is the double-edge anti-pattern (dev-warns). Use `elevation="flat" bordered`, or drop `bordered`.
|
|
58
|
-
- `flat` is still a surface (`bg-surface-
|
|
58
|
+
- `flat` is still a surface (`bg-surface-panel`), not the page — a card without a shadow, not a hole in the page.
|
|
59
59
|
- Don't reach for `Surface` when you mean `Card` — if you're rebuilding header/content/footer spacing by hand, use `Card`.
|
|
60
60
|
- Padding is symmetric. For anything asymmetric, use `className` or `Card`.
|
|
@@ -13,7 +13,7 @@ The kit ships an OKLCH 12-step ramp per color family (`1`=app-bg, `9`=solid/acce
|
|
|
13
13
|
```
|
|
14
14
|
Surface (background of a region)?
|
|
15
15
|
→ page bg → bg-surface-base
|
|
16
|
-
→ card / widget / panel → bg-surface-
|
|
16
|
+
→ card / widget / panel → bg-surface-panel
|
|
17
17
|
→ sidebar / topbar → bg-surface-sunken
|
|
18
18
|
→ dialog / popover / dropdown / input → bg-surface-overlay
|
|
19
19
|
→ tooltip → bg-surface-inverted
|
|
@@ -50,9 +50,9 @@ Brand emphasis?
|
|
|
50
50
|
| Token | Use |
|
|
51
51
|
|---|---|
|
|
52
52
|
| `surface-base` | Page background. The "back wall" of the app. |
|
|
53
|
-
| `surface-
|
|
54
|
-
| `surface-
|
|
55
|
-
| `surface-
|
|
53
|
+
| `surface-panel` | Cards, widgets, panels, anything that sits **on** the page. |
|
|
54
|
+
| `surface-panel-hover` | Hover state on a `surface-panel` element. |
|
|
55
|
+
| `surface-panel-active` | Pressed / active state. |
|
|
56
56
|
| `surface-sunken` | Shell chrome (sidebar, topbar), board columns, segmented-control tracks. |
|
|
57
57
|
| `surface-overlay` | Floating layers — dialogs, popovers, dropdowns, inputs, toasts. |
|
|
58
58
|
| `surface-inverted` | Tooltips, inverted badges. Pair with `surface-inverted-fg`. |
|
|
@@ -39,7 +39,7 @@ function ThemeToggle() {
|
|
|
39
39
|
|
|
40
40
|
## What you have to do per-component
|
|
41
41
|
|
|
42
|
-
Nothing. Semantic tokens flip automatically. As long as you use `bg-surface-
|
|
42
|
+
Nothing. Semantic tokens flip automatically. As long as you use `bg-surface-panel` not `bg-white`, dark mode works.
|
|
43
43
|
|
|
44
44
|
The only exception: **images, illustrations, decorative SVGs**. These don't flip. Author them as theme-aware:
|
|
45
45
|
|
|
@@ -36,7 +36,7 @@ In components: never — they apply the right role automatically.
|
|
|
36
36
|
In your own elements (rare):
|
|
37
37
|
|
|
38
38
|
```tsx
|
|
39
|
-
<div className="bg-surface-
|
|
39
|
+
<div className="bg-surface-panel rounded-(--radius-surface) p-ds-05">…</div>
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
TW4 shorthand `rounded-(--radius-surface)` is the right way. **Do not** use `rounded-ds-lg` directly — it's not a semantic role, and the pre-publish audit rejects it in `src/ui/`.
|
|
@@ -7,15 +7,15 @@ The kit ships five semantic surface tiers and a paired shadow system. **Picking
|
|
|
7
7
|
| Tier | Token | What sits here |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| **Base** | `surface-base` | Page background. The "back wall." |
|
|
10
|
-
| **Raised** | `surface-
|
|
10
|
+
| **Raised** | `surface-panel` | Cards, widgets, panels — anything that floats **on** the page. |
|
|
11
11
|
| **Sunken** | `surface-sunken` | Shell chrome (Sidebar, TopBar), board columns, segmented-control tracks. |
|
|
12
12
|
| **Overlay** | `surface-overlay` | Floating layers — Dialog, Sheet, Popover, Dropdown, Toast, Tooltip-when-light, Input field. |
|
|
13
13
|
| **Inverted** | `surface-inverted` | Tooltips, inverted badges. Pair with `text-surface-inverted-fg`. |
|
|
14
14
|
|
|
15
15
|
Each tier has hover / active variants:
|
|
16
16
|
|
|
17
|
-
- `surface-
|
|
18
|
-
- `surface-
|
|
17
|
+
- `surface-panel-hover` — hover on a raised element.
|
|
18
|
+
- `surface-panel-active` — pressed / selected raised element.
|
|
19
19
|
|
|
20
20
|
And a disabled state:
|
|
21
21
|
|
|
@@ -27,8 +27,8 @@ And a disabled state:
|
|
|
27
27
|
|---|---|---|
|
|
28
28
|
| Page / layout shell | `surface-base` | none |
|
|
29
29
|
| Sidebar / TopBar (shell) | `surface-sunken` | `shadow-raised` |
|
|
30
|
-
| Card / widget / panel | `surface-
|
|
31
|
-
| Card on hover | `surface-
|
|
30
|
+
| Card / widget / panel | `surface-panel` | `shadow-raised` |
|
|
31
|
+
| Card on hover | `surface-panel` | `shadow-raised-hover` |
|
|
32
32
|
| Board column / well / track | `surface-sunken` | none |
|
|
33
33
|
| Popover / dropdown / menu | `surface-overlay` | `shadow-floating` |
|
|
34
34
|
| Dialog / modal / sheet | `surface-overlay` | `shadow-overlay` |
|
|
@@ -64,17 +64,17 @@ Shadow tokens include a 1-px ring layer (inset hairline + drop shadow). Adding a
|
|
|
64
64
|
|
|
65
65
|
❌ **Wrong:**
|
|
66
66
|
```tsx
|
|
67
|
-
<div className="bg-surface-
|
|
67
|
+
<div className="bg-surface-panel border border-surface-border shadow-raised rounded-(--radius-surface)">
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
✅ **Right (shadow only):**
|
|
71
71
|
```tsx
|
|
72
|
-
<div className="bg-surface-
|
|
72
|
+
<div className="bg-surface-panel shadow-raised rounded-(--radius-surface)">
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
✅ **Right (border only — when shadow is unwanted, e.g. dense lists):**
|
|
76
76
|
```tsx
|
|
77
|
-
<div className="bg-surface-
|
|
77
|
+
<div className="bg-surface-panel border border-surface-border rounded-(--radius-surface)">
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
`<Card>` already follows this rule. Don't override with extra border classes.
|
|
@@ -113,7 +113,7 @@ In dark mode the kit lightens surfaces with elevation (so `surface-overlay` is *
|
|
|
113
113
|
|
|
114
114
|
## Rules
|
|
115
115
|
|
|
116
|
-
- **Card-like elements** (anything that reads as a panel on the page) → `surface-
|
|
116
|
+
- **Card-like elements** (anything that reads as a panel on the page) → `surface-panel`, never `surface-base`.
|
|
117
117
|
- **Overlay-like elements** → `surface-overlay`, always.
|
|
118
118
|
- **Never** combine an explicit border with a shadow token.
|
|
119
119
|
- **Never** invent a sixth tier. Five is the system.
|