@vegastack/design 0.7.5 → 0.7.7

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/bin/doctor.mjs CHANGED
@@ -130,8 +130,9 @@ function readJson(path) {
130
130
  // fresh consumer before anything else is installed correctly.
131
131
  const GUIDE = "https://design.vegastack.com/docs/guides/migrating-shadcn-reset";
132
132
  const HEADING_HINT = {
133
- "text-h1": "text-3xl font-semibold (page heading)",
134
- "text-h2": "text-2xl font-semibold (section heading)",
133
+ "text-h1":
134
+ "PageHeader (font-heading text-2xl font-semibold, the page heading)",
135
+ "text-h2": "font-heading text-base font-medium (section heading)",
135
136
  "text-h3": "text-lg font-semibold",
136
137
  "text-h4": "text-base font-medium (card / dialog title)",
137
138
  };
@@ -70,6 +70,12 @@ var TIMINGS = {
70
70
  feedbackRevertMs: 1500,
71
71
  /** Debounce before auto-persisting a text field (AutoSaveInput). */
72
72
  autoSaveDebounceMs: 800,
73
+ /**
74
+ * Debounce before a typed search query is sent (SearchInput's settled value, FilterBar
75
+ * search, `useAsyncSearch`). Short enough to feel like type-ahead, long enough that one
76
+ * word is one request; {@link TIMINGS.autoSaveDebounceMs} is too slow for this role.
77
+ */
78
+ searchDebounceMs: 300,
73
79
  /** Hover delay before a rich preview (HoverCard) opens — guards accidental opens. */
74
80
  hoverOpenDelayMs: 700,
75
81
  /** Hover delay before a rich preview closes — lets the pointer travel into the card. */
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  cn
4
- } from "./chunk-MSOIZXDR.js";
4
+ } from "./chunk-OHGNXG5G.js";
5
5
 
6
6
  // src/icons/create-animated-icon.tsx
7
7
  import * as React from "react";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  cn
3
- } from "../chunk-MSOIZXDR.js";
3
+ } from "../chunk-OHGNXG5G.js";
4
4
 
5
5
  // src/icons/icon.tsx
6
6
  import "react";
package/dist/index.cjs CHANGED
@@ -99,6 +99,12 @@ var TIMINGS = {
99
99
  feedbackRevertMs: 1500,
100
100
  /** Debounce before auto-persisting a text field (AutoSaveInput). */
101
101
  autoSaveDebounceMs: 800,
102
+ /**
103
+ * Debounce before a typed search query is sent (SearchInput's settled value, FilterBar
104
+ * search, `useAsyncSearch`). Short enough to feel like type-ahead, long enough that one
105
+ * word is one request; {@link TIMINGS.autoSaveDebounceMs} is too slow for this role.
106
+ */
107
+ searchDebounceMs: 300,
102
108
  /** Hover delay before a rich preview (HoverCard) opens — guards accidental opens. */
103
109
  hoverOpenDelayMs: 700,
104
110
  /** Hover delay before a rich preview closes — lets the pointer travel into the card. */
package/dist/index.d.cts CHANGED
@@ -132,6 +132,12 @@ declare const TIMINGS: {
132
132
  readonly feedbackRevertMs: 1500;
133
133
  /** Debounce before auto-persisting a text field (AutoSaveInput). */
134
134
  readonly autoSaveDebounceMs: 800;
135
+ /**
136
+ * Debounce before a typed search query is sent (SearchInput's settled value, FilterBar
137
+ * search, `useAsyncSearch`). Short enough to feel like type-ahead, long enough that one
138
+ * word is one request; {@link TIMINGS.autoSaveDebounceMs} is too slow for this role.
139
+ */
140
+ readonly searchDebounceMs: 300;
135
141
  /** Hover delay before a rich preview (HoverCard) opens — guards accidental opens. */
136
142
  readonly hoverOpenDelayMs: 700;
137
143
  /** Hover delay before a rich preview closes — lets the pointer travel into the card. */
package/dist/index.d.ts CHANGED
@@ -132,6 +132,12 @@ declare const TIMINGS: {
132
132
  readonly feedbackRevertMs: 1500;
133
133
  /** Debounce before auto-persisting a text field (AutoSaveInput). */
134
134
  readonly autoSaveDebounceMs: 800;
135
+ /**
136
+ * Debounce before a typed search query is sent (SearchInput's settled value, FilterBar
137
+ * search, `useAsyncSearch`). Short enough to feel like type-ahead, long enough that one
138
+ * word is one request; {@link TIMINGS.autoSaveDebounceMs} is too slow for this role.
139
+ */
140
+ readonly searchDebounceMs: 300;
135
141
  /** Hover delay before a rich preview (HoverCard) opens — guards accidental opens. */
136
142
  readonly hoverOpenDelayMs: 700;
137
143
  /** Hover delay before a rich preview closes — lets the pointer travel into the card. */
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  mergeRefs,
6
6
  prose,
7
7
  proseClassName
8
- } from "./chunk-MSOIZXDR.js";
8
+ } from "./chunk-OHGNXG5G.js";
9
9
  export {
10
10
  FLOATING,
11
11
  TIMINGS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vegastack/design",
3
- "version": "0.7.5",
3
+ "version": "0.7.7",
4
4
  "description": "VegaStack design system — cn utility, icon runtime, Tailwind v4 preset, and the vegastack-design CLI (tokens ship separately as @vegastack/design-tokens)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -68,8 +68,8 @@ link` (upstream's set, verbatim). `destructive` is a soft tint, not a solid red
68
68
  suggestions or multi-select chips.
69
69
  - **One view-switch rule.** A form value is a **`radio-group`**. An immediate view or scope switch
70
70
  over the same content (Mine | Team, All | Unread, Grid | List) is a single-select
71
- **`toggle-group`** that always keeps one item pressed — ignore the empty value in
72
- `onValueChange` — with `spacing={0}` for 2–5 options inline. Swapping in-page regions is
71
+ **`toggle-group`** that always keeps one item pressed — `deselectable={false}` — with
72
+ `spacing={0}` for 2–5 options inline (`wrap` when they can outgrow the row). Swapping in-page regions is
73
73
  **`tabs`**; moving between URLs is navigation — links, not `tabs` (a route-tabs recipe is
74
74
  not shipped yet).
75
75
  - **Empty is tiered** — nothing yet, no matches ("Clear filters"), couldn't load (`role="alert"`,
@@ -95,33 +95,37 @@ info`, each an ink on the `card` surface with a required icon; **`announcement-b
95
95
 
96
96
  A component's name undersells it. Before composing something by hand, check this list:
97
97
 
98
- | Component | What it already does |
99
- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
100
- | `Command` | Renders inline as well as in `CommandDialog`. An item's check mark is `data-checked` — visual only, so it is not a form value. |
101
- | `Combobox` | `multiple` with `ComboboxChips`; `filter={null}` hands filtering to your server. |
102
- | `SearchableSelect` | The Select-shaped search picker, with `clearable`. Single-select today. |
103
- | `Item` | A link tile with `render={<a />}`; `ItemGroup` gives a set of items list semantics. |
104
- | `DialogContent` | `size`: `sm · default · lg · xl`. Never a width class. |
105
- | `DataList` | Per-column `mobile` (`merge` · `visible` · `hidden`) and `minWidth`. `DataGrid` adds editing, multi-key sort and a column picker; `Table` is static markup. |
106
- | `FilterBar` / `FilterBuilder` | `FilterBar` is a flat chip row with search; `FilterBuilder` (the `filter-bar-managed` item) edits a nested and/or tree over your field vocabulary. Both are controlled. |
107
- | `Stat` | `StatDelta` for change, `StatEmpty` for nothing to report. |
108
- | `PropertyList` · `DataList` · `SettingsRow` | A record's facts · many records · one setting with its control. |
109
- | `ActionBar` | The docked bar for bulk selection ("5 selected"), unsaved changes and batch progress. |
110
- | `TruncatedText` · `IconText` · `TableCellText` | Overflow detection, hover and keyboard reveal, and tap-to-toggle on touch. |
111
- | `RelativeTime` | `mode="ago"` ("3 minutes ago") or `mode="day"` ("Yesterday"). |
112
- | `EditableCell` · `AutoSaveInput` · `useInlineEdit` | Click-to-edit in a table · a field that saves as you type, with its status · the hook `EditableCell` is built on. |
113
- | `AttachmentGroup` · `Dropzone` · `useFileDrop` | A file list with per-file state · a drop target · the drop and paste engine. |
114
- | `PageHeader` | Title, description, `breadcrumb`, a back link (`backHref`) and `actions`. |
115
- | `MultiStepForm` · `Stepper` · `Questionnaire` · `Tabs` | A form in steps · progress display (`navigable` on request) · one question at a time · peer regions. |
116
- | `NativeSelect` | The platform `<select>`, so a touch device opens its own picker. |
117
- | `Board` | A column's `lockedReason` explains why it cannot take a card. |
118
- | `AudioPlayer` | `mediaRef` to drive playback, a transcript button and a waveform. |
119
- | `Tabs` | `TabsList variant="line"` and `Tabs orientation="vertical"`. |
120
- | `MessageScroller` | `defaultScrollPosition` (`start` · `end` · `last-anchor`), `scrollToMessage` from `useMessageScroller()`, and `useMessageScrollerVisibility()`. |
98
+ | Component | What it already does |
99
+ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
100
+ | `Command` | Renders inline as well as in `CommandDialog`. An item's check mark is `data-checked` — visual only, so it is not a form value. |
101
+ | `Combobox` | `multiple` with `ComboboxChips`; `filter={null}` hands filtering to your server. |
102
+ | `SearchableSelect` | The Select-shaped search picker, with `clearable`. `multiple` for several values; `remote` plus `useAsyncSearch` hands search and paging to your server. |
103
+ | `Item` | A link tile with `render={<a />}`; `ItemGroup` gives a set of items list semantics. |
104
+ | `DialogContent` · `SheetContent` | `size`: `sm · default · lg · xl` (a side sheet). Never a width class. |
105
+ | `DataList` | Per-column `mobile` (`merge` · `visible` · `hidden`) and `minWidth`. `DataGrid` adds editing, multi-key sort and a column picker; `Table` is static markup. |
106
+ | `DataList` paging and rows | `loadMore` for keyset paging, `getRowHref` for rows that are links, `sections` + `getRowSection` for collapsible groups, and `rowActionsColumn` for a per-row menu. |
107
+ | `LoadMore` · `useAsyncSearch` | The Load more footer of a keyset list (keeps its width while loading, "Try again", an end caption) · the server-search engine: debounce, dropped stale responses, cursor paging. |
108
+ | `SortableList` | `layout="grid"` reorders tiles as well as rows. |
109
+ | `FilterBar` / `FilterBuilder` | `FilterBar` is a flat chip row with search, and `FilterBarFacet` is a "Status: Open" facet on `SearchableSelect` (single or `multiple`, local or `remote`); `FilterBuilder` (the `filter-bar-managed` item) edits a nested and/or tree over your field vocabulary. All controlled. |
110
+ | `Stat` | `StatDelta` for change, `StatEmpty` for nothing to report. |
111
+ | `PropertyList` · `DataList` · `SettingsRow` | A record's facts · many records · one setting with its control. |
112
+ | `ActionBar` | The docked bar for bulk selection ("5 selected"), unsaved changes and batch progress. |
113
+ | `TruncatedText` · `IconText` · `TableCellText` | Overflow detection, hover and keyboard reveal, and tap-to-toggle on touch. |
114
+ | `RelativeTime` | `mode="ago"` ("3 minutes ago") or `mode="day"` ("Yesterday"). |
115
+ | `EditableCell` · `AutoSaveInput` · `useInlineEdit` | Click-to-edit in a table · a field that saves as you type, with its status · the hook `EditableCell` is built on. |
116
+ | `AttachmentGroup` · `Dropzone` · `useFileDrop` | A file list with per-file state · a drop target · the drop and paste engine. |
117
+ | `PageHeader` | Title, description, `breadcrumb`, a back link (`backHref`) and `actions`. |
118
+ | `MultiStepForm` · `Stepper` · `Questionnaire` · `Tabs` | A form in steps · progress display (`navigable` on request) · one question at a time · peer regions. |
119
+ | `NativeSelect` | The platform `<select>`, so a touch device opens its own picker. |
120
+ | `Board` | A column's `lockedReason` explains why it cannot take a card. |
121
+ | `AudioPlayer` | `mediaRef` to drive playback, a transcript button and a waveform; `docked` pins it to the bottom of a scroll column, `onOpenChange` adds its close button, and `actionsRef` seeks it. |
122
+ | `Tabs` | `TabsList variant="line"` and `Tabs orientation="vertical"`. |
123
+ | `MessageScroller` | `defaultScrollPosition` (`start` · `end` · `last-anchor`), `scrollToMessage` from `useMessageScroller()`, and `useMessageScrollerVisibility()`. |
121
124
 
122
125
  ### Which component for X
123
126
 
124
- - **A page** → `AppShell` › `AppShellContent` › `PageHeader` › `FilterBar` › `DataList` (or
127
+ - **A page** → `AppShell` › `AppShellContent` › `AppShellPage` (`size`: `narrow` for forms and
128
+ settings, `default`, `full`) › `PageHeader` › `FilterBar` › `DataList` (or
125
129
  `DataGrid`) › the `Empty` tier that fits. The spacing between them is the page-rhythm recipe
126
130
  (<https://design.vegastack.com/docs/foundations/spacing#page-rhythm>).
127
131
  - **A record's details** → `PropertyList`, in `Card` sections titled with an `h2` in `CardTitle`.
@@ -132,6 +136,30 @@ A component's name undersells it. Before composing something by hand, check this
132
136
  - **A confirmation that interrupts** → `AlertDialog`; a form or detail in an overlay → `Dialog` or
133
137
  `Sheet`.
134
138
  - **Feedback after an action** → `toast.add({ title })`.
139
+ - **A recording's text beside its player** → `Transcript` (follows `currentTime`, seeks through
140
+ `onSeek`, searches) with a `docked` `AudioPlayer` at the bottom of the column.
141
+ - **A list that pages by cursor** → `DataList` `loadMore` (or `LoadMore` under your own list), with
142
+ `useAsyncSearch` when the search runs on the server.
143
+
144
+ ### Starter blocks
145
+
146
+ A block is a page you copy once and then own (`shadcn add @vegastack/<name>`). Start from the
147
+ closest one rather than composing the page from nothing:
148
+
149
+ - **`app-shell-01`** — the shell: landmarks, skip link, a rail with search, inbox count and a user
150
+ menu.
151
+ - **`list-page-01`** — one kind of record: search, a facet, Mine | Team, table or tile grid, Load
152
+ more and three empty tiers.
153
+ - **`board-01`** — lanes of cards under a `FilterBar`, with a paged backlog.
154
+ - **`settings-01`** — one settings page: grouped `SettingsRow` sections and a save bar.
155
+ - **`settings-02`** — the settings hub: grids of linked tiles, grouped by area.
156
+ - **`review-split-01`** — a record reviewed beside a sticky transcript and a docked player; tabs
157
+ when narrow.
158
+ - **`notifications-01`** — the inbox sheet: All | Unread, Today and Earlier, Load older.
159
+ - **`command-search-01`** — the ⌘K search palette: scopes, recents, grouped results and every
160
+ state.
161
+ - **`status-pages-01`** — the 404, 403 and error pages.
162
+ - **`login-01`** — a sign-in page.
135
163
 
136
164
  ## Tokens
137
165
 
@@ -212,11 +240,12 @@ contract.
212
240
 
213
241
  ## Composition patterns
214
242
 
215
- - **Forms are composed, not configured** — `Field` is layout and copy: `FieldLabel` bound with
216
- `htmlFor`, the control, then `FieldDescription` and `FieldError` as CHILDREN. There is no `label`,
217
- `description` or `error` prop, and no context that reaches into the control. State is written where
218
- it belongs: `aria-invalid` on the control (for assistive tech), `data-invalid` / `data-disabled` on
219
- the `Field` (for the block's styling). `FieldError` is `role="alert"`, carries a leading icon so an
243
+ - **Forms are composed, not configured** — `Field` is layout and copy: `FieldLabel`, the control,
244
+ then `FieldDescription` and `FieldError` as CHILDREN. There is no `label`, `description` or `error`
245
+ prop. `Field` wires the control through Base UI Field — the label's `for`, the description and
246
+ error ids in `aria-describedby`, and `aria-invalid` from the Field's `data-invalid` — so pass ids
247
+ only to override; an explicit `aria-*` prop on the control merges with the Field's, it does not
248
+ replace it. Write `data-invalid` / `data-disabled` on the `Field`, not by hand on the control. `FieldError` is `role="alert"`, carries a leading icon so an
220
249
  error is never colour alone, and takes either children or an `errors` array it de-duplicates.
221
250
  react-hook-form's `register` wires straight to the control; there is no `Controller` indirection.
222
251
  - **A set of related checkboxes is a `FieldSet` + `FieldLegend` + one `Field` per option** — that is
@@ -3,7 +3,7 @@
3
3
  <!-- GENERATED — do not hand-edit. Regenerated from the design system's component contract,
4
4
  which is the authority for membership and counts. -->
5
5
 
6
- **114 components**, plus 467 animated-icon items, 11 hooks (`use-animation-replay`, `use-announcer`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-overflow`, `use-platform`), 4 starter blocks (`app-shell-01`, `board-01`, `login-01`, `settings-01`), 68 chart blocks across 7 families, and 2 data libs (`geo-data`, `drag-item`) — 666 registry items in total.
6
+ **114 components**, plus 467 animated-icon items, 12 hooks (`use-animation-replay`, `use-announcer`, `use-async-search`, `use-drag-reorder`, `use-file-drop`, `use-inline-edit`, `use-list-nav`, `use-media-query`, `use-mobile`, `use-modal-inert`, `use-overflow`, `use-platform`), 10 starter blocks (`app-shell-01`, `board-01`, `command-search-01`, `list-page-01`, `login-01`, `notifications-01`, `review-split-01`, `settings-01`, `settings-02`, `status-pages-01`), 68 chart blocks across 7 families, and 2 data libs (`geo-data`, `drag-item`) — 673 registry items in total.
7
7
 
8
8
  Install any of them with `shadcn add @vegastack/<name>`. Animated icons install as
9
9
  `@vegastack/icon-<name>`; the bare name is reserved for components, so a component whose name