@assure-one/design-system 1.37.0 → 1.38.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/README.md +45 -16
- package/codemods/README.md +40 -0
- package/codemods/lib/registry.mjs +1 -0
- package/codemods/transforms/cm-18-data-table-parts.mjs +234 -0
- package/dist/css/components.css +1 -1
- package/dist/css/legacy-aliases.css +8 -0
- package/dist/css/tokens.css +8 -0
- package/dist/{design-system-provider-C8UlFe52.d.ts → design-system-provider-B5MbvbRc.d.ts} +61 -1
- package/dist/index.d.ts +1358 -206
- package/dist/index.js +2201 -607
- package/dist/index.js.map +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/styles.css +1 -1
- package/docs/components.md +36 -8
- package/docs/components.registry.json +2399 -463
- package/docs/for-ai-agents.md +2 -0
- package/eslint-config/index.mjs +210 -0
- package/eslint-config/stylelint-rules.mjs +54 -0
- package/eslint-config/stylelint.mjs +73 -0
- package/package.json +8 -1
package/docs/components.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- Generated by `pnpm docs:catalogue` from api/*.api.md and docs/components.registry.json. Do not edit by hand; edit the registry and regenerate. -->
|
|
4
4
|
|
|
5
|
-
Every public component of `@assure-one/design-system`, in one place: **
|
|
5
|
+
Every public component of `@assure-one/design-system`, in one place: **561 component exports** — 180 component families with 228 compound parts, and 153 icons — plus the hooks, utilities, tokens and testing helpers the package exports. The list is derived from the API reports, so a public component cannot be missing from this page (`pnpm docs:catalogue --check` runs in `pnpm test:contracts`).
|
|
6
6
|
|
|
7
7
|
**How to use this page.** Start from the ["Pick a component"](#pick-a-component) table with the UI need you have, or from ["Never hand-roll"](#never-hand-roll) with the raw element you were about to write; links land on the category section that holds the row. Every row links to the story that shows the states. The short rulebook for agents and new contributors is [`docs/for-ai-agents.md`](./for-ai-agents.md).
|
|
8
8
|
|
|
@@ -76,7 +76,7 @@ The UI need on the left, the design-system answer on the right. When two compone
|
|
|
76
76
|
| A global command / search box | [CommandPalette](#overlays), [KeyboardShortcutsDialog](#overlays) | |
|
|
77
77
|
| Switch between views | [Tabs](#navigation), [ChannelTabs](#navigation), [BottomNav](#navigation) | `BottomNav` is the mobile tab bar. |
|
|
78
78
|
| Where am I | [Breadcrumb](#navigation), [PageHeader](#layout), [AppHeader](#shell-screens) | |
|
|
79
|
-
| Page through results | [Pagination](#navigation) | `DataTablePagination`
|
|
79
|
+
| Page through results | [Pagination](#navigation) | `DataTablePagination` is the same pager with the table's 25-row default; `pageSizeOptions` adds a rows-per-page picker. |
|
|
80
80
|
| A tree or a rail of items | [FolderTree](#navigation), [ClientRailItem](#navigation) | |
|
|
81
81
|
| Space things out | [Stack](#layout), [Inline](#layout) | Tokenised gap and alignment; never ad-hoc `flex gap-*` in product code. |
|
|
82
82
|
| A bordered box or card | [Surface](#layout), [Card](#layout) | `Card` adds header/title/description/footer parts and an interactive variant. |
|
|
@@ -165,6 +165,8 @@ Pick one or many from a set: dropdowns, comboboxes, toggle groups, chips and fil
|
|
|
165
165
|
|
|
166
166
|
| Component | Use when | Don't use when | Replaces raw HTML | Related | Links |
|
|
167
167
|
| --- | --- | --- | --- | --- | --- |
|
|
168
|
+
| **PeoplePicker** (experimental)<br>since unreleased | Pick a person or people from the firm's roster (W7-10): `people`, single or `multiple`, avatars with an optional second line, an "assign to me" shortcut from `currentUserId`, and an `unassignedLabel` row that reports `null`. Search, keyboard, `Field` binding and form submission come from `Combobox`. | The options are not people (`Combobox`, `MultiSelect`), or a plain roster select with no roster affordances is enough (`Select`). `TeamMemberSelect` is the predecessor it replaces. | `hand-rolled assignee popover with checkboxes` | [Combobox](#selection), [MultiSelect](#selection), [Avatar](#data-display), [TeamMemberSelect](#selection) | [story](https://github.com/Assure-One/design-system/blob/main/src/patterns/pickers/people-picker.stories.tsx) |
|
|
169
|
+
| **SegmentedControl** (experimental)<br>since unreleased | One of a few mutually exclusive views or scopes, shown side by side (W7-17): `options` with an optional `count` per segment, `size` on the control scale, radio semantics and arrow-key movement from `ToggleGroup`. The active segment cannot be cleared by clicking it again. | The set is long or open-ended (`Select`, `Combobox`), more than one may be active (`ToggleGroup type="multiple"`), or the segments switch page regions rather than a value (`Tabs`). | `pill Tabs used as a filter`, `<div> of <button> with a manual active class` | [ToggleGroup](#selection), [Tabs](#navigation), [Select](#selection), [MultiFilterPill](#selection) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/segmented-control.stories.tsx) |
|
|
168
170
|
| **Select**<br>parts: `SelectRoot`, `SelectTrigger`, `SelectValue`, `SelectContent`, `SelectItem`, `SelectGroup`, `SelectLabel`, `SelectSeparator`, `SelectScrollUpButton`, `SelectScrollDownButton`<br>since 0.0.0 | One of a short static list in a dropdown: the sealed `Select` takes `options`; the `Select*` parts compose custom items. Empty value is a real empty (no sentinel option), `size`, `classNames`, Field binding. | The user should type to filter, the list is long or async (`Combobox`), several values (`MultiSelect`), or a few options that can all be visible (`RadioGroup`, `ToggleGroup`). | `<select>`, `<option>` | [Combobox](#selection), [MultiSelect](#selection), [ClientSelect](#selection), [TeamMemberSelect](#selection) | — |
|
|
169
171
|
| **Combobox** (experimental)<br>also: `DEFAULT_COMBOBOX_MESSAGES`<br>since unreleased | A searchable pick: one input, a portalled listbox, the `Option<T>` model (`{ value, label }`), async loading and empty messages, single or `multiple`. | A short static list (`Select`) or free text with suggestions that need not match (`Input` + `Popover`). | `<input list> + <datalist>`, `<select> with a search box` | [Select](#selection), [MultiSelect](#selection), [SearchSelect](#selection) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/combobox.stories.tsx) |
|
|
170
172
|
| **MultiSelect** (experimental)<br>since unreleased | Several of many options with search: `Combobox` in `multiple` mode with selected chips. | A handful of options that should all be visible (`MultiSelectField`) or one value (`Combobox`, `Select`). | `<select multiple>` | [Combobox](#selection), [MultiSelectField](#forms), [Chip](#selection) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/multi-select.stories.tsx) |
|
|
@@ -192,7 +194,8 @@ Tell the user what is happening: status messages, progress, loading and empty st
|
|
|
192
194
|
| **ProgressRing**<br>also: `progressRingVariants`<br>since 0.0.0 | A circular meter for a card or tile, with the same `intent` and value-driven colour rule as `ProgressBar`. | A wide layout (`ProgressBar`) or a donut of several series (`DonutChart`). | — | [ProgressBar](#feedback), [DonutChart](#media) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/progress-ring.stories.tsx) |
|
|
193
195
|
| **SegmentedProgress**<br>since 1.2.0 | Progress through a known number of steps as filled segments (onboarding, checklists). | The steps have names (`Stepper`) or the value is continuous (`ProgressBar`). | — | [Stepper](#navigation), [ProgressBar](#feedback), [SuiteProgress](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/segmented-progress.stories.tsx) |
|
|
194
196
|
| **SuiteProgress**<br>also: `suiteProgressFillVariants`<br>since 1.34.0 | The suite's discrete segmented meter with a percent readout, tinted per product or `intent`. | A generic segmented meter (`SegmentedProgress`) or a continuous one (`ProgressBar`). | — | [SegmentedProgress](#feedback), [ProgressBar](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/suite-progress.stories.tsx) |
|
|
195
|
-
| **EmptyState**<br>since 0.0.0 | A list or panel has nothing to show: icon, title, description and one action. | The feature does not exist yet (`ComingSoon`) or content is loading (`Skeleton`). | `centred div with an icon and grey text` | [ComingSoon](#feedback), [LoadingRows](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/empty-state.stories.tsx) |
|
|
197
|
+
| **EmptyState**<br>since 0.0.0 | A list or panel has nothing to show: icon, title, description and one action. | The feature does not exist yet (`ComingSoon`) or content is loading (`Skeleton`). | `centred div with an icon and grey text` | [ComingSoon](#feedback), [LoadingRows](#feedback), [ErrorState](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/empty-state.stories.tsx) |
|
|
198
|
+
| **ErrorState**<br>since 1.38.0 | A list or panel failed to load: danger icon tile, title, description and a retry button (`onRetry`). `size="compact"` inside a table. | There is simply nothing to show (`EmptyState`) or the error belongs to a form field (`FieldError`). | `centred div with a warning icon and a Try again button` | [EmptyState](#feedback), [TableError](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/error-state.stories.tsx) |
|
|
196
199
|
| **ComingSoon**<br>since 0.0.0 | A placeholder for a feature that is not available yet: icon, title, description and a feature list. | The feature exists but has no data (`EmptyState`). | — | [EmptyState](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/coming-soon.stories.tsx) |
|
|
197
200
|
| **AttentionItem**<br>since 1.2.0 | One row of an attention queue: icon, title, description, service tone and trailing action. | A notification (`NotificationPanel` items) or an activity event (`ActivityList` items). | — | [NotificationPanel](#data-display), [ActivityList](#data-display), [KpiCard](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/attention-item.stories.tsx) |
|
|
198
201
|
| **MissingDocumentsPanel**<br>since 1.4.0 | The firm-side panel listing documents a client has not provided, with a Request action. | The client-side checklist (`DocumentChecklist`). | — | [DocumentChecklist](#data-display), [DocumentRequestDetail](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/missing-documents-panel.stories.tsx) |
|
|
@@ -229,7 +232,7 @@ Move between places: tabs, breadcrumbs, pagination, steppers, trees and rails.
|
|
|
229
232
|
| **Tabs**<br>parts: `TabsList`, `TabsTrigger`, `TabsContent`<br>since 0.0.0 | Switch between panels of one page; roving focus, `value`/`onValueChange`. | The switch changes a mode rather than showing another panel (`ToggleGroup`), or it is the mobile app-level bar (`BottomNav`). | `<ul role="tablist">`, `buttons toggling useState panels` | [ToggleGroup](#selection), [ChannelTabs](#navigation), [BottomNav](#navigation) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/tabs.stories.tsx) |
|
|
230
233
|
| **ChannelTabs**<br>since 1.5.0 | Pill tabs switching between communication channels on a thread, each with a toned status dot and unread count; fully controlled. | Generic panels (`Tabs`). | — | [Tabs](#navigation), [StatusDot](#data-display), [MessageBubble](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/channel-tabs.stories.tsx) |
|
|
231
234
|
| **Breadcrumb**<br>parts: `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`<br>since 0.0.0 | The path to the current page; `BreadcrumbPage` marks the current one, `BreadcrumbLink asChild` wraps your router link. | The page title itself (`PageHeader`) or the app-level bar (`AppHeaderBreadcrumb` inside `AppHeader`). | `<nav aria-label="breadcrumb"><ol>` | [PageHeader](#layout), [AppHeader](#shell-screens) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/breadcrumb.stories.tsx) |
|
|
232
|
-
| **Pagination**<br>since 0.0.0 | Page controls for a paged list: current/total pages, sibling count, optional total items. | Inside a `DataTable
|
|
235
|
+
| **Pagination**<br>since 0.0.0 | Page controls for a paged list: current/total pages, sibling count, optional total items. | Infinite scroll. Inside a `DataTable`, `DataTablePagination` is the same component with the table defaults. | `<nav> of page number buttons` | [DataTable](#data-display), [DataTableView](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/pagination.stories.tsx) |
|
|
233
236
|
| **Stepper**<br>since 0.0.0 | Named steps of a multi-step flow, horizontal or vertical, with the current step marked. | Unnamed progress (`SegmentedProgress`) or a timeline of past events (`EngagementTimeline`). | — | [SegmentedProgress](#feedback), [EngagementTimeline](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/stepper.stories.tsx) |
|
|
234
237
|
| **BottomNav**<br>since 1.2.0 | The mobile tab bar at the bottom of the app: tabs with icons and badges, controlled `value`. | Desktop navigation (`Sidebar`) or in-page panels (`Tabs`). | — | [Sidebar](#shell-screens), [Tabs](#navigation), [StickyActionBar](#actions) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/bottom-nav.stories.tsx) |
|
|
235
238
|
| **FolderTree**<br>since 1.2.0 | A collapsible tree of folders with an active node, default-open ids and selection callback. | A flat list (`ClientRailItem`) or a file list (`DocumentList`). | — | [DocumentsWorkspaceLayout](#layout), [ClientRailItem](#navigation), [Collapsible](#layout) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/folder-tree.stories.tsx) |
|
|
@@ -241,6 +244,7 @@ Arrange content: stacks, surfaces, cards, separators, section and page framing.
|
|
|
241
244
|
|
|
242
245
|
| Component | Use when | Don't use when | Replaces raw HTML | Related | Links |
|
|
243
246
|
| --- | --- | --- | --- | --- | --- |
|
|
247
|
+
| **SectionCard**<br>since 1.38.0 | A titled panel: `title`, optional `description`, trailing `actions`, body and optional `footer` — `Card`'s header/body/footer composed once. `flush` for a body that owns its row insets. | The surface has no heading (`Card`) or it is a whole page header (`PageHeader`). | `section with a border, a heading row and a padded body` | [Card](#layout), [PageHeader](#layout), [Surface](#layout) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/section-card.stories.tsx) |
|
|
244
248
|
| **Stack** (experimental)<br>since 1.33.0 | A vertical (or `direction="row"`) flex container that owns the gap between its children with tokenised `gap` and alignment. | A wrapping horizontal row (`Inline`) or a bordered box (`Surface`). | `<div class="flex flex-col gap-4">` | [Inline](#layout), [Surface](#layout) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/layout/stack.stories.tsx) |
|
|
245
249
|
| **Inline** (experimental)<br>since 1.33.0 | A horizontal wrapping row with children centred on the baseline and a tokenised gap: a row of chips, a button row, meta items. | A column (`Stack`) or a toolbar of controls that must share one control size (`Toolbar`). | `<div class="flex flex-wrap items-center gap-2">` | [Stack](#layout), [Toolbar](#actions) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/layout/inline.stories.tsx) |
|
|
246
250
|
| **Surface** (experimental)<br>since 1.33.0 | The bordered box content sits on: surface background, 1px rule, radius, `padding` role (none/sm/md/lg). | You need header/title/footer parts or an interactive variant (`Card`). | `<div class="rounded-xl border bg-white p-4">` | [Card](#layout), [Stack](#layout) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/layout/surface.stories.tsx) |
|
|
@@ -282,10 +286,15 @@ Show records and status: tables, key/value grids, badges, dots, avatars, lists a
|
|
|
282
286
|
|
|
283
287
|
| Component | Use when | Don't use when | Replaces raw HTML | Related | Links |
|
|
284
288
|
| --- | --- | --- | --- | --- | --- |
|
|
289
|
+
| **InfoHint** (experimental)<br>since unreleased | The ⓘ beside a label or a figure (W7-15): `label` names what the hint is about, `children` is the explanation, `presentation="tooltip"` (default) or `"popover"` for an explanation with a paragraph or a link. The trigger is a real `IconButton`, so the hint is reachable by keyboard and by touch. | The text belongs in the layout (`FieldDescription` under a field) or the surface is a rich hover preview (`HoverCard`). | `<svg title>`, `<span title>` | [Tooltip](#overlays), [Popover](#overlays), [IconButton](#actions), [FieldDescription](#forms) | [story](https://github.com/Assure-One/design-system/blob/main/src/patterns/display/info-hint.stories.tsx) |
|
|
290
|
+
| **AvatarGroup**<br>since 1.38.0 | An overlapping stack of `Avatar`s with a `+N` overflow bubble: `max` caps the faces, `total` carries the real count, `size` cascades from Avatar's scale. | A single person (`Avatar`) or a list that needs names (`DescriptionList`). | `flex row of avatars with negative margins and a +N circle` | [Avatar](#data-display), [TeamMemberSelect](#selection) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/avatar-group.stories.tsx) |
|
|
285
291
|
| **StarRating**<br>also: `starRatingVariants`<br>since 0.0.0 | A display-only rating: fractional stars, `max`, sized variants. | Capturing a rating (compose `RadioGroup` or `ToggleGroup` with star icons). | — | [Badge](#data-display), [KpiCard](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/star-rating.stories.tsx) |
|
|
286
292
|
| **Table**<br>parts: `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell`, `TableCaption`<br>since 0.0.0 | A bare semantic table with the design system's row, header and caption styling. | A records table with toolbar, sorting and pagination (`DataTable`, `DataTableView`) or an editable matrix (`Grid`). | `<table>`, `<tr>`, `<td>`, `<th>` | [DataTable](#data-display), [DataTableView](#data-display), [MetadataGrid](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/table.stories.tsx) |
|
|
287
|
-
| **DataTable**<br>parts: `DataTableToolbar`, `DataTableSearch`, `DataTableSpacer`, `DataTableResultsCount`, `DataTableHead`, `DataTableHeader`, `DataTableBody`, `DataTableRow`, `DataTableCell`, `DataTableCellName`, `DataTableCellMono`, `DataTableCellId`, `DataTableCellDue`, `DataTableCheckbox`, `DataTablePagination`<br>since 0.3.0 | The composable records table: card frame, toolbar with search and count, sortable headers, typed cells (name, mono, id, due), row checkbox, pagination. | A config-driven table is enough (`DataTableView`) or the table is a plain semantic one (`Table`). | `<table> + hand-rolled toolbar and pager` | [DataTableView](#data-display), [Table](#data-display), [BulkActionBar](#actions), [LoadingRows](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table.stories.tsx) |
|
|
288
|
-
| **
|
|
293
|
+
| **DataTable**<br>parts: `DataTableToolbar`, `DataTableSearch`, `DataTableSpacer`, `DataTableResultsCount`, `DataTableHead`, `DataTableHeader`, `DataTableBody`, `DataTableRow`, `DataTableCell`, `DataTableCellName`, `DataTableCellMono`, `DataTableCellId`, `DataTableCellDue`, `DataTableCheckbox`, `DataTablePagination`<br>since 0.3.0 | The composable records table: card frame, toolbar with search and count, sortable headers, typed cells (name, mono, id, due), row checkbox, pagination. | A config-driven table is enough (`DataTableView`) or the table is a plain semantic one (`Table`). | `<table> + hand-rolled toolbar and pager` | [DataTableView](#data-display), [Table](#data-display), [BulkActionBar](#actions), [LoadingRows](#feedback), [TableLoading](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table.stories.tsx) |
|
|
294
|
+
| **TableLoading** (experimental)<br>since 1.38.0 | The `<tbody aria-busy>` of a data table while its rows load: skeleton rows sized to the columns. Slots in place of `DataTableBody`. | A list outside a table (`LoadingRows`) or a single shape (`Skeleton`). | `<tbody> of hand-rolled skeleton <td>s` | [TableEmpty](#data-display), [TableError](#data-display), [DataTable](#data-display), [LoadingRows](#feedback) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table-states.stories.tsx) |
|
|
295
|
+
| **TableEmpty** (experimental)<br>since 1.38.0 | The `<tbody>` of a data table with no rows: one full-width row holding a compact `EmptyState`. | An empty panel outside a table (`EmptyState`). | `<tr><td colSpan> with centred grey text` | [TableLoading](#data-display), [TableError](#data-display), [EmptyState](#feedback), [DataTable](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table-states.stories.tsx) |
|
|
296
|
+
| **TableError** (experimental)<br>since 1.38.0 | The `<tbody>` of a data table whose rows failed to load: one full-width row holding a compact `ErrorState` with retry. | An error panel outside a table (`ErrorState`). | `<tr><td colSpan> with an error message and a retry button` | [TableLoading](#data-display), [TableEmpty](#data-display), [ErrorState](#feedback), [DataTable](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table-states.stories.tsx) |
|
|
297
|
+
| **DataTableView**<br>parts: `StagePill` (deprecated), `Assignee` (deprecated), `MoneyCell` (deprecated), `TagsCell`, `Dash` (deprecated)<br>since 1.6.0 | A list screen as configuration: `columns` + `data` (+ filters, search keys, sort); owns search/filter/sort/pagination state. Cell renderers `StagePill`, `Assignee`, `MoneyCell`, `TagsCell`, `Dash` for `column.render`. | You need custom table composition (`DataTable`). | — | [DataTable](#data-display), [DisplayMenu](#actions), [Toolbar](#actions) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table-view.stories.tsx) |
|
|
289
298
|
| **MetadataGrid**<br>parts: `DataItem`<br>since 0.4.1 | Label / value pairs on a detail surface as a semantic `<dl>`; `DataItem span={2}` for full-row values. | Tabular records (`Table`) or a stat tile (`KpiCard`). | `<dl>`, `two-column label/value divs` | [DetailGrid](#layout), [Table](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/metadata-grid.stories.tsx) |
|
|
290
299
|
| **KpiCard**<br>parts: `SelectableKpiCard`<br>since 0.4.1 | A single-stat dashboard tile: label, value, optional tone, icon and hint; `SelectableKpiCard` when tiles act as filters. | A number inside running content (`Stat`) or a chart (`DonutChart`). | — | [Stat](#typography), [DashGrid](#layout), [Card](#layout) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/kpi-card.stories.tsx) |
|
|
291
300
|
| **Badge**<br>also: `badgeVariants`, `resolveBadgeAppearance`<br>since 0.0.0 | A short static label or count: `variant` (solid, soft, outline) × `intent`. | A status with a shared vocabulary (`StatusBadge`), a removable token (`Chip`) or a machine-suggested intent (`IntentBadge`). | `<span class="rounded-full px-2 text-xs">` | [StatusBadge](#data-display), [Chip](#selection), [IntentBadge](#data-display), [StatusDot](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/badge.stories.tsx) |
|
|
@@ -313,6 +322,8 @@ Show records and status: tables, key/value grids, badges, dots, avatars, lists a
|
|
|
313
322
|
| **TimeLogger**<br>parts: `TimeLoggerHeader`, `TimeLoggerTimer`, `TimeLoggerContextRow`, `TimeLoggerField`, `TimeLoggerBillable`, `TimeLoggerNotes`, `TimeLoggerEntryList`, `TimeLoggerEntry`, `TimeLoggerActions`, `TimeLoggerFooter`<br>also: `formatClock`, `formatDuration`, `parseDuration`, `formatCurrency`, `useStopwatch`<br>since 0.15.0 | The compact time-entry panel: compose only the rows a surface needs (timer, context, billable, notes, entries); `useStopwatch` and the duration formatters drive it. | A single duration field (`Input` + `parseDuration`). | — | [Popover](#overlays), [NumberInput](#forms) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/time-logger.stories.tsx) |
|
|
314
323
|
| **Proposal pricing**<br>parts: `ProposalServiceRow`, `ProposalAddOn`, `ProposalBillingTerms`, `ProposalPricingSummary`<br>since 1.12.0 | The Services & Pricing blocks of a proposal preview: package card, service rows, add-ons, billing terms, summary; inherit the firm accent inside `AgreementViewer`. | Anything outside a proposal (`Card`, `MetadataGrid`). | — | [AgreementViewer](#shell-screens), [ProposalSignatureBlock](#forms), [ProposalSignerList](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/proposal-pricing.stories.tsx) |
|
|
315
324
|
| **Proposal content**<br>parts: `ProposalNote`, `ProposalCustomPage`<br>since 1.12.0 | The content blocks of a proposal: signer list, notes, custom pages. | Anything outside a proposal. | — | [AgreementViewer](#shell-screens), [ProposalPackageCard](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/proposal-content.stories.tsx) |
|
|
325
|
+
| **DataTable (compound)** (experimental)<br>since unreleased | A records table driven by `useDataTable`: the toolbar with a labelled search, filters and a column-visibility menu, the table on the `Table*` parts with sort and selection wired to the controller, bulk actions, the merged pager and the built-in loading / empty / error bodies. `classNames.search` and `--ds-data-table-search-width` size the search field. | A table with no state (the `Table` parts alone), the hand-written `DataTable*` parts a product already composes, or the config-driven convenience (`DataTableView`). | `hand-rolled toolbar + <table> + pager around per-table useState` | [useDataTable](#hooks-utilities), [Table](#data-display), [DataTable](#data-display), [DataTableView](#data-display), [Pagination](#navigation), [BulkActionBar](#actions), [TableLoading](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/patterns/data/data-table.stories.tsx) · [docs](https://github.com/Assure-One/design-system/blob/main/docs/data-tables.md) |
|
|
326
|
+
| **EmptyValue** (experimental)<br>since unreleased | A table or detail cell has no value: renders the em dash placeholder consistently. | The value is genuinely empty text a user typed — render it as-is. | `<span>—</span>` | — | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/data-table-view.stories.tsx) |
|
|
316
327
|
|
|
317
328
|
## Media
|
|
318
329
|
|
|
@@ -370,13 +381,14 @@ The application frame and full-screen composites: shell, sidebar, header, brand
|
|
|
370
381
|
| Component | Use when | Don't use when | Replaces raw HTML | Related | Links |
|
|
371
382
|
| --- | --- | --- | --- | --- | --- |
|
|
372
383
|
| **Shell**<br>parts: `Main`, `Content`<br>since 0.3.0 | The application frame: `Shell` holds the `Sidebar` and `Main`; `Main` holds `AppHeader` and `Content`. | A public or marketing page (`Section`). | `<div class="flex h-screen">` | [Sidebar](#shell-screens), [AppHeader](#shell-screens), [BrandScope](#shell-screens) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/shell.stories.tsx) |
|
|
373
|
-
| **Sidebar**<br>parts: `SidebarProvider`, `SidebarTrigger`, `SidebarBrand`, `SidebarBrandText`, `SidebarSection`, `SidebarLinkGroup`, `SidebarLink`, `SidebarLinkLabel`, `SidebarLinkBadge`, `SidebarLinkAction`, `SidebarPinButton`, `SidebarUser`, `SidebarFooter`<br>also: `sidebarLinkBadgeVariants`, `useSidebarState`, `useSidebarPeekLock`<br>since 0.3.0 | The app navigation rail: expanded/collapsed/peek states from `SidebarProvider`, brand, sections, link groups with badges and actions, user and footer. | Mobile (`BottomNav`) or a rail of records (`ClientRailItem`). | `<aside> + <nav> hand-rolled` | [Shell](#shell-screens), [SidebarBrandSwitcher](#shell-screens), [BottomNav](#navigation) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/sidebar.stories.tsx) |
|
|
384
|
+
| **Sidebar**<br>parts: `SidebarProvider`, `SidebarTrigger`, `SidebarBrand`, `SidebarBrandText`, `SidebarSection`, `SidebarLinkGroup`, `SidebarLink`, `SidebarLinkLabel`, `SidebarLinkBadge`, `SidebarLinkAction`, `SidebarPinButton`, `SidebarUser`, `SidebarFooter`<br>also: `sidebarLinkBadgeVariants`, `useSidebarState`, `useSidebarPeekLock`<br>since 0.3.0 | The app navigation rail: expanded/collapsed/peek states from `SidebarProvider`, brand, sections, link groups with badges and actions, user and footer. | Mobile (`BottomNav`) or a rail of records (`ClientRailItem`). | `<aside> + <nav> hand-rolled` | [Shell](#shell-screens), [SidebarBrandSwitcher](#shell-screens), [BottomNav](#navigation), [SidebarDrawer](#shell-screens) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/sidebar.stories.tsx) |
|
|
374
385
|
| **SidebarBrandSwitcher**<br>parts: `SidebarBrandSwitcherTile`<br>since 0.11.2 | Switch between Assure products from the sidebar brand slot: tiles for available, current and coming-soon products. | A single-product app (`SidebarBrand`). | — | [Sidebar](#shell-screens), [BrandScope](#shell-screens), [Logo](#media) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/sidebar-brand-switcher.stories.tsx) |
|
|
375
386
|
| **AppHeader**<br>parts: `AppHeaderBreadcrumb`, `AppHeaderTitle`, `AppHeaderSearch`, `AppHeaderActions`<br>since 0.3.0 | The sticky 56px top bar inside `Main`: breadcrumb, title, search and actions slots in any order. | The page's own title block (`PageHeader`). | — | [Shell](#shell-screens), [PageHeader](#layout), [NewMenu](#actions), [NotificationPanel](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/app-header.stories.tsx) |
|
|
376
387
|
| **DesignSystemProvider** (experimental)<br>also: `useDsMessages`<br>since unreleased | Mount once in the root layout to configure the whole design system: `messages` overrides for the generic strings components render, `locale` (default `en-US`, pass the one your app knows server-side), `dir`, the portal container, the router `linkComponent` and `imageComponent` for `LinkButton` and `Logo`, the tooltip provider, and opt-in `toasts` / `confirm` regions. `useDsMessages(namespace, override?)` reads the resolved strings inside your own components. | You are on Next.js — `NextDesignSystemProvider` from `/next` fills in the adapters. Theming a subtree is `ThemeScope` / `BrandScope`, not a nested provider. | `hand-rolled i18n or router context for design-system strings and links` | [ThemeScope](#shell-screens), [BrandScope](#shell-screens), [Tooltip](#overlays), [LinkButton](#actions), [Logo](#media) | [story](https://github.com/Assure-One/design-system/blob/main/src/foundation/provider/design-system-provider.stories.tsx) |
|
|
377
388
|
| **ThemeScope** (experimental)<br>since unreleased | A subtree that renders with its own colour `scheme`, `brand`, `density`, `dir` or runtime brand theme: stamps the `data-ds-*` attributes on its element and registers them so portalled overlays opened from inside (Dialog, Popover, menus) come up in the same theme; nested scopes merge. | The whole app shares one theme (set the attributes on the document root) or only the product brand changes (`BrandScope`). | `<div data-ds-scheme="dark"> whose dialogs come up in the root theme` | [BrandScope](#shell-screens), [DesignSystemProvider](#shell-screens), [Dialog](#overlays), [Popover](#overlays) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/behavior/portal.stories.tsx) · [docs](https://github.com/Assure-One/design-system/blob/main/docs/integration/css.md) |
|
|
378
389
|
| **BrandScope**<br>parts: `BrandScopeProvider`<br>also: `BRAND_PRODUCTS`, `brandLabel`, `brandScope`, `useBrandScope`<br>since 1.18.0 | Theme a subtree as a product: stamps `data-brand` and provides it so portalled surfaces re-stamp themselves; `brandScope(product)` for the attribute alone. | Colouring by service line (`serviceToneStyle`) or by status (`intent`). | — | [Shell](#shell-screens), [SidebarBrandSwitcher](#shell-screens) | [docs](https://github.com/Assure-One/design-system/blob/main/docs/integration/css.md) |
|
|
379
390
|
| **AgreementViewer**<br>parts: `AgreementPaneHeading`<br>since 1.12.0 | The client-facing agreement / proposal viewer: cover, steps, firm accent scope for the proposal blocks. | Previewing a PDF (`PdfPreview`). | — | [ProposalPackageCard](#data-display), [ProposalSignatureBlock](#forms), [ProposalSignerList](#data-display) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/agreement-viewer.stories.tsx) |
|
|
391
|
+
| **SidebarDrawer** (experimental)<br>since 1.38.0 | The sidebar nav off-canvas on small viewports: the same tree in a left-hand Sheet, with the focus trap, scroll lock and dismissal the overlay parts already provide. | Desktop widths (`Sidebar`) or a bottom tab bar (`BottomNav`). | — | [Sidebar](#shell-screens), [Sheet](#overlays), [Shell](#shell-screens) | [story](https://github.com/Assure-One/design-system/blob/main/src/composites/sidebar.stories.tsx) |
|
|
380
392
|
|
|
381
393
|
## Hooks/utilities
|
|
382
394
|
|
|
@@ -385,6 +397,7 @@ Non-rendering exports: hooks, class-name helpers, formatters and token objects.
|
|
|
385
397
|
| Component | Use when | Don't use when | Replaces raw HTML | Related | Links |
|
|
386
398
|
| --- | --- | --- | --- | --- | --- |
|
|
387
399
|
| **cn**<br>since 0.0.0 | Merge class names (clsx + tailwind-merge) when composing `className`; consumer classes still win by cascade, `cn` only dedupes. | Overriding a component part — pass `className`/`classNames` instead of rebuilding its classes. | — | [Button](#actions) | [docs](https://github.com/Assure-One/design-system/blob/main/docs/integration/css.md) |
|
|
400
|
+
| **Data-table controller** (experimental)<br>also: `compareSortValues`, `nextSortDirection`<br>since unreleased | Building a data table: owns sorting, pagination, search, selection, column visibility and filters (each controllable or uncontrolled), derives the rows to render, and in `manual` mode only emits state for a server-driven table. | A static table with no state (the `Table` parts alone), or the data-driven convenience (`DataTableView`) once it is rebuilt on the hook. | — | [Table](#data-display), [DataTable](#data-display), [DataTableView](#data-display), [Pagination](#navigation) | [story](https://github.com/Assure-One/design-system/blob/main/src/primitives/behavior/data-table/use-data-table.stories.tsx) · [docs](https://github.com/Assure-One/design-system/blob/main/docs/data-tables.md) |
|
|
388
401
|
| **useFieldControl** (experimental)<br>since 1.32.0 | Building your own form control that should bind to `Field` like the design-system ones: returns ids, `aria-*`, invalid/disabled/required wiring; explicit props win. | Wrapping an existing element once (`FieldControl`). | — | [Field](#forms), [FieldControl](#forms) | [docs](https://github.com/Assure-One/design-system/blob/main/docs/adr/006-field-native-form-participation.md) |
|
|
389
402
|
| **Date utilities**<br>also: `displayToIso`, `applyMask`, `applyYearMask`, `isoToDate`, `dateToIso`, `isoToYear`, `yearToIso`, `DATE_DISPLAY_PLACEHOLDER`, `YEAR_DISPLAY_PLACEHOLDER`<br>since 0.11.0 | Convert between ISO `YYYY-MM-DD`, the `MM/DD/YYYY` display format and JS `Date` the way `DatePicker` does, and apply its typing masks. | Locale-aware formatting for display text (`Intl.DateTimeFormat`). | — | [DatePicker](#forms), [DateRangePicker](#forms) | — |
|
|
390
403
|
| **Country codes**<br>also: `getFlagEmoji`, `parsePhoneForEditing`<br>since 1.1.0 | The ISO country / dial-code table behind `PhoneCountryInput`, a flag emoji fallback, and splitting a stored phone string for editing. | Full phone validation (bring libphonenumber). | — | [PhoneField](#forms), [PhoneCountryInput](#forms) | — |
|
|
@@ -425,6 +438,7 @@ The raw element or pattern on the left already has a design-system component. Wr
|
|
|
425
438
|
| `<div onClick>` | [Button](#actions), [Pressable](#actions) |
|
|
426
439
|
| `<div role="alert">` | [Alert](#feedback) |
|
|
427
440
|
| `<div role="group">` | [Fieldset](#forms) |
|
|
441
|
+
| `<div> of <button> with a manual active class` | [SegmentedControl](#selection) |
|
|
428
442
|
| `<dl>` | [MetadataGrid](#data-display) |
|
|
429
443
|
| `<fieldset>` | [Fieldset](#forms) |
|
|
430
444
|
| `<h1>` | [Heading](#typography) |
|
|
@@ -476,14 +490,20 @@ The raw element or pattern on the left already has a design-system component. Wr
|
|
|
476
490
|
| `<span class="rounded-full px-2 text-xs">` | [Badge](#data-display) |
|
|
477
491
|
| `<span class="text-sm text-gray-500">` | [Text](#typography) |
|
|
478
492
|
| `<span role="button">` | [Pressable](#actions) |
|
|
493
|
+
| `<span title>` | [InfoHint](#data-display) |
|
|
494
|
+
| `<span>—</span>` | [EmptyValue](#data-display) |
|
|
495
|
+
| `<svg title>` | [InfoHint](#data-display) |
|
|
479
496
|
| `<svg>` | [Icons](#icons) |
|
|
480
497
|
| `<table>` | [Table](#data-display) |
|
|
481
498
|
| `<table> + hand-rolled toolbar and pager` | [DataTable](#data-display) |
|
|
482
499
|
| `<table> of <input>s` | [Grid](#forms) |
|
|
500
|
+
| `<tbody> of hand-rolled skeleton <td>s` | [TableLoading](#data-display) |
|
|
483
501
|
| `<td>` | [Table](#data-display) |
|
|
484
502
|
| `<textarea>` | [Textarea](#forms) |
|
|
485
503
|
| `<th>` | [Table](#data-display) |
|
|
486
504
|
| `<tr>` | [Table](#data-display) |
|
|
505
|
+
| `<tr><td colSpan> with an error message and a retry button` | [TableError](#data-display) |
|
|
506
|
+
| `<tr><td colSpan> with centred grey text` | [TableEmpty](#data-display) |
|
|
487
507
|
| `<ul role="tablist">` | [Tabs](#navigation) |
|
|
488
508
|
| `<ul> of hand-styled feed rows` | [ActivityList](#data-display) |
|
|
489
509
|
| `<ul> shown on click` | [DropdownMenu](#overlays) |
|
|
@@ -493,22 +513,28 @@ The raw element or pattern on the left already has a design-system component. Wr
|
|
|
493
513
|
| `animate-spin svg` | [Spinner](#feedback) |
|
|
494
514
|
| `Array.from({ length }).map(<Skeleton/>)` | [LoadingRows](#feedback) |
|
|
495
515
|
| `buttons toggling useState panels` | [Tabs](#navigation) |
|
|
516
|
+
| `centred div with a warning icon and a Try again button` | [ErrorState](#feedback) |
|
|
496
517
|
| `centred div with an icon and grey text` | [EmptyState](#feedback) |
|
|
497
518
|
| `class="sr-only"` | [VisuallyHidden](#layout) |
|
|
498
519
|
| `coloured bordered div` | [Alert](#feedback) |
|
|
499
520
|
| `drop-zone div with onDrop` | [FileUpload](#forms) |
|
|
500
521
|
| `fixed inset-0 div` | [Dialog](#overlays) |
|
|
501
522
|
| `fixed right-0 h-full div` | [Sheet](#overlays) |
|
|
523
|
+
| `flex row of avatars with negative margins and a +N circle` | [AvatarGroup](#data-display) |
|
|
502
524
|
| `group of <button aria-pressed>` | [ToggleGroup](#selection) |
|
|
525
|
+
| `hand-rolled assignee popover with checkboxes` | [PeoplePicker](#selection) |
|
|
503
526
|
| `hand-rolled i18n or router context for design-system strings and links` | [DesignSystemProvider](#shell-screens) |
|
|
504
527
|
| `hand-rolled toast portal` | [ToastProvider](#feedback) |
|
|
528
|
+
| `hand-rolled toolbar + <table> + pager around per-table useState` | [DataTable (compound)](#data-display) |
|
|
505
529
|
| `hard-coded top-[56px] sticky offsets` | [StickyStack](#layout) |
|
|
506
530
|
| `lucide-react` | [Icons](#icons) |
|
|
507
531
|
| `navigator.clipboard.writeText + useState` | [CopyButton](#actions) |
|
|
508
532
|
| `nested div with width:%` | [ProgressBar](#feedback) |
|
|
509
533
|
| `onContextMenu + positioned div` | [ContextMenu](#overlays) |
|
|
510
534
|
| `padding-top percentage hack` | [AspectRatio](#layout) |
|
|
535
|
+
| `pill Tabs used as a filter` | [SegmentedControl](#selection) |
|
|
511
536
|
| `PromptDialog.ask() singletons` | [ConfirmHost](#overlays) |
|
|
537
|
+
| `section with a border, a heading row and a padded body` | [SectionCard](#layout) |
|
|
512
538
|
| `six <input maxlength="1">` | [OTPInput](#forms) |
|
|
513
539
|
| `stack of <details>` | [Accordion](#layout) |
|
|
514
540
|
| `title="…"` | [Tooltip](#overlays) |
|
|
@@ -522,7 +548,7 @@ The raw element or pattern on the left already has a design-system component. Wr
|
|
|
522
548
|
|
|
523
549
|
## Deprecated aliases and their replacements
|
|
524
550
|
|
|
525
|
-
Every deprecated name keeps rendering exactly what it did (zero visual diff) until 3.0. The codemod column names the transform in [`codemods/README.md`](../codemods/README.md) that rewrites call sites (`node node_modules/@assure-one/design-system/codemods/run.mjs <id> src`); a dash means the change is a hand edit. Deprecated exports in the API report: `ArrowRightSmallIcon`, `CloseIcon`, `CountryFlag`, `CountrySelect`, `FormError`, `FormSection`, `FormSuccess`, `PhoneCountryInput`, `PhoneInput`, `SearchSelect`, `SideDrawer`.
|
|
551
|
+
Every deprecated name keeps rendering exactly what it did (zero visual diff) until 3.0. The codemod column names the transform in [`codemods/README.md`](../codemods/README.md) that rewrites call sites (`node node_modules/@assure-one/design-system/codemods/run.mjs <id> src`); a dash means the change is a hand edit. Deprecated exports in the API report: `ArrowRightSmallIcon`, `Assignee`, `CloseIcon`, `CountryFlag`, `CountrySelect`, `Dash`, `FormError`, `FormSection`, `FormSuccess`, `MoneyCell`, `PhoneCountryInput`, `PhoneInput`, `SearchSelect`, `SideDrawer`, `StagePill`.
|
|
526
552
|
|
|
527
553
|
| Deprecated | Use instead | Codemod | Contract |
|
|
528
554
|
| --- | --- | --- | --- |
|
|
@@ -538,6 +564,8 @@ Every deprecated name keeps rendering exactly what it did (zero visual diff) unt
|
|
|
538
564
|
| `Input` / `Textarea` / `SearchInput` `inputSize` | `size` | CM-07 | C-INPUT-SIZE |
|
|
539
565
|
| `InputSizeAlias` `compact` / `default` / `comfortable` | `sm` / `md` / `lg` | — | C-INPUT-SIZE |
|
|
540
566
|
| `Select` `triggerClassName` / `contentClassName` | `classNames={{ trigger, content }}` | — | C-SELECT-CLASSNAMES |
|
|
567
|
+
| `Dash` (DataTableView cell) | `EmptyValue` | — | — |
|
|
568
|
+
| `StagePill` / `Assignee` / `MoneyCell` / `TableTone` (DataTableView product cells) | Product-owned renderers in `column.render` (`StatusBadge`, `Avatar`, `Intl.NumberFormat`, `EmptyValue`); hand-over to TAX in W8-13 | — | — |
|
|
541
569
|
| `Select searchable` | `Combobox` | — | — |
|
|
542
570
|
| `Select` sentinel option values standing in for "no value" | A real empty value (`value=""`, `clearable`) | CM-20 (finder) | C-SELECT-EMPTY |
|
|
543
571
|
| `SearchSelect` (`{ id, label }` options) | `Combobox` with `Option` (`{ value, label }`) | CM-08 | C-SEARCHSELECT |
|