@nadicodeai/ui 12.1.133 → 12.1.135

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.
Files changed (32) hide show
  1. package/dist/components/agent-orb.d.ts +8 -5
  2. package/dist/components/agent-orb.d.ts.map +1 -1
  3. package/dist/components/agent-orb.js +8 -5
  4. package/dist/components/data-table.d.ts +1 -1
  5. package/dist/components/data-table.js +2 -5
  6. package/dist/components/record-identity.d.ts +1 -1
  7. package/dist/components/record-identity.d.ts.map +1 -1
  8. package/dist/components/record-identity.js +2 -4
  9. package/dist/components/record-list.d.ts +1 -1
  10. package/dist/components/record-list.js +1 -1
  11. package/dist/components/scope-switcher.d.ts +1 -1
  12. package/dist/components/scope-switcher.d.ts.map +1 -1
  13. package/dist/components/scope-switcher.js +5 -2
  14. package/dist/components/table-layouts.d.ts +7 -7
  15. package/dist/components/table-layouts.js +7 -7
  16. package/dist/components/table.d.ts +2 -2
  17. package/dist/components/table.js +2 -2
  18. package/dist/internal/agent-orb-motion.d.ts +36 -5
  19. package/dist/internal/agent-orb-motion.d.ts.map +1 -1
  20. package/dist/internal/agent-orb-motion.js +153 -37
  21. package/dist/internal/agent-orb.d.ts.map +1 -1
  22. package/dist/internal/agent-orb.js +38 -20
  23. package/dist/internal/table-compact-line.d.ts +0 -5
  24. package/dist/internal/table-compact-line.d.ts.map +1 -1
  25. package/dist/internal/table-compact-line.js +1 -6
  26. package/dist/showcase/specimens/other.js +1 -1
  27. package/dist/showcase/specimens/status.d.ts +2 -1
  28. package/dist/showcase/specimens/status.d.ts.map +1 -1
  29. package/dist/showcase/specimens/status.js +17 -3
  30. package/dist/showcase/usage.generated.js +6 -6
  31. package/dist/standalone/index.js +1 -1
  32. package/package.json +2 -2
@@ -40,13 +40,16 @@ export type AgentOrbProps = AgentOrbBaseProps & ({
40
40
  * @instead A person is an `Avatar`. The system's own wait is the waiting line, never an orb. An orb
41
41
  * in artwork, such as a sign-in picture, takes `motion="ambient"` and claims no activity. An orb
42
42
  * that stands for an Agent shows her real state.
43
- * @behaviour The only thing that moves on its own. Idle turns at its form's own pace and breathes;
44
- * working and thinking move with their cue, the ribbon around working and three dots above
45
- * thinking; waiting holds; blocked makes one interrupted effort and stops; done celebrates once and
46
- * settles back into idle. A surface that only knows a machine checked in draws idle. No state draws
43
+ * @behaviour The only thing that moves on its own. Idle particles turn at 86.4% of the form's native pace,
44
+ * with a separate 6.4 s breath. Working sweeps a ribbon every 3.2 s; thinking passes three pulses
45
+ * over 2.4 s. Waiting leans softly as centered pause bars arrive; blocked recoils as a centered
46
+ * stop sign lands. Both entrances settle over 2 s, then waiting breathes and blocked holds still.
47
+ * Done celebrates once over 4.8 s, then rests at 72% of native particle speed with the Idle breath.
48
+ * A state change interrupts the previous gesture; `motionKey` replays it and `paused` freezes it. A surface that only knows a machine checked in draws idle. No state draws
47
49
  * a circle around the orb. Ambient motion moves the form at its own pace with no state pose or cue.
48
50
  * Reduced motion: movement stops, a thinking or working orb breathes between full ink and 0.45
49
- * opacity so busy still reads as busy, and an ambient orb holds still.
51
+ * opacity so busy still reads as busy, an ambient orb holds still, and waiting and blocked keep
52
+ * their centered signs without an entrance gesture.
50
53
  * An orb is one of seven forms, `ribbon`, `lattice`, `orbit`, `globe`, `network`, `braid` and
51
54
  * `morph`, in one colour a person chose: cobalto, verde or arancio, or none, which draws it in the
52
55
  * text colour. Giallo is not offered because it fails 3:1 on white; rosso is not offered because it
@@ -1 +1 @@
1
- {"version":3,"file":"agent-orb.d.ts","sourceRoot":"","sources":["../../src/components/agent-orb.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,OAAO,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,KAAK,iBAAiB,GAAG;IACvB,4FAA4F;IAC5F,IAAI,EAAE,cAAc,CAAC;IACrB,wFAAwF;IACxF,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,qEAAqE;IACrE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAC3C,CAAC;IAAE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GACrF,CAAC;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,IAAS,EACT,QAAkB,EAClB,MAAc,EACd,KAAc,EACd,MAAiB,EACjB,SAAa,EACb,UAAkB,EAClB,KAAK,EACL,SAAS,GACV,EAAE,aAAa,+BAyDf"}
1
+ {"version":3,"file":"agent-orb.d.ts","sourceRoot":"","sources":["../../src/components/agent-orb.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAqB,MAAM,OAAO,CAAC;AAE9D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAG/B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE,KAAK,iBAAiB,GAAG;IACvB,4FAA4F;IAC5F,IAAI,EAAE,cAAc,CAAC;IACrB,wFAAwF;IACxF,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,qEAAqE;IACrE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAC3C,CAAC;IAAE,MAAM,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,GACrF,CAAC;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,UAAU,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,IAAS,EACT,QAAkB,EAClB,MAAc,EACd,KAAc,EACd,MAAiB,EACjB,SAAa,EACb,UAAkB,EAClB,KAAK,EACL,SAAS,GACV,EAAE,aAAa,+BAyDf"}
@@ -14,13 +14,16 @@ import { cn } from "../lib/utils.js";
14
14
  * @instead A person is an `Avatar`. The system's own wait is the waiting line, never an orb. An orb
15
15
  * in artwork, such as a sign-in picture, takes `motion="ambient"` and claims no activity. An orb
16
16
  * that stands for an Agent shows her real state.
17
- * @behaviour The only thing that moves on its own. Idle turns at its form's own pace and breathes;
18
- * working and thinking move with their cue, the ribbon around working and three dots above
19
- * thinking; waiting holds; blocked makes one interrupted effort and stops; done celebrates once and
20
- * settles back into idle. A surface that only knows a machine checked in draws idle. No state draws
17
+ * @behaviour The only thing that moves on its own. Idle particles turn at 86.4% of the form's native pace,
18
+ * with a separate 6.4 s breath. Working sweeps a ribbon every 3.2 s; thinking passes three pulses
19
+ * over 2.4 s. Waiting leans softly as centered pause bars arrive; blocked recoils as a centered
20
+ * stop sign lands. Both entrances settle over 2 s, then waiting breathes and blocked holds still.
21
+ * Done celebrates once over 4.8 s, then rests at 72% of native particle speed with the Idle breath.
22
+ * A state change interrupts the previous gesture; `motionKey` replays it and `paused` freezes it. A surface that only knows a machine checked in draws idle. No state draws
21
23
  * a circle around the orb. Ambient motion moves the form at its own pace with no state pose or cue.
22
24
  * Reduced motion: movement stops, a thinking or working orb breathes between full ink and 0.45
23
- * opacity so busy still reads as busy, and an ambient orb holds still.
25
+ * opacity so busy still reads as busy, an ambient orb holds still, and waiting and blocked keep
26
+ * their centered signs without an entrance gesture.
24
27
  * An orb is one of seven forms, `ribbon`, `lattice`, `orbit`, `globe`, `network`, `braid` and
25
28
  * `morph`, in one colour a person chose: cobalto, verde or arancio, or none, which draws it in the
26
29
  * text colour. Giallo is not offered because it fails 3:1 on white; rosso is not offered because it
@@ -228,7 +228,7 @@ export declare function columnMenuLabel<TData extends RowData, TValue extends Ce
228
228
  * @instead “For a row of descriptive content paired with a single action (membership row, integration row), use `Entity` instead.” (https://vercel.com/geist/table)
229
229
  * “For a key/value metadata block on a detail page, use `Description`, not a two-column table.” (https://vercel.com/geist/table)
230
230
  * Ours: Geist's `Entity` is a `RecordList` row. A registry of entities whose columns `RecordList` cannot hold, more than three facts beside a filter bar the product owns, as Vercel's Deployments list, is this table with `rows="entities"`, which draws the same rows: headings for assistive technology only, 72 px rows, a `RecordIdentity` in the identity column. Its `Description` is `ObjectFacts`. A list on a page of its own is a `CollectionPage`. A descriptive list is `ItemGroup`.
231
- * @behaviour Every column has a `header`; a column without one does not compile. The headings are always visible, medium weight in the cells' body grey, 48 px high, with 12 px of room under the labels and then the rule, so the first row starts at the rule like every other; rows are 40 px. Each column is as wide as its definition's `size`, in pixels, and the columns without one share the rest, so a table gives a size to every column but the one that takes the spare width; a value too long for its column ends in an ellipsis, whole in its title (a record's name carries its own), unless the column `wraps`; a column marked `identifier` holds ids or paths and is cut in the middle instead. The last column trails unless it `wraps` or is `centered`; a `centered` column's heading and values sit in the middle of it. Records are divided by a 1 px rule, none after the last. The first and last columns stand in from the card's edges by the card's spacing, so the first lines up with the title. Records of several kinds stand in one table under `group` headings (Vercel's Usage page: *Delivery network*, *Functions*): a heading row that spans the columns, in ink, medium text, 36 px high with the same rule under it, one per group in the order the groups first appear, never a second table; a heading is the group's name and carries no figure of its own. A row that opens a record takes `accent` on hover, and any row on focus within and while its menu is open; a row that opens nothing never reacts to hover. A selected row takes `muted`; headers and footers never highlight and carry no fill. A row never scrolls sideways: on a card narrower than its columns (the sized ones and 160 px for each without a size) the row keeps its name and its `primaryColumns`, and every other column leaves it, its value joining the one muted line under the name, joined by a middle dot and ending in an ellipsis (a `Tag` reads as its text there, and a `wraps` column's prose wraps the line whole), or `dropped` when its `compact` says so, or beside an entity row's name, which ends in an ellipsis before it, when it says `name`, as Vercel's lists read on a phone: no labels, no second line; an `optional` column's empty value is left out of the line. A table whose every column is in `primaryColumns`, a settings matrix, lays out by its content there instead, so the name wraps beside the columns. A document's table, such as a legal page's, is read whole instead: its columns take the `wraps` option, so their words wrap and the row grows, and it keeps its header row; in the compact layout every cell but the identity wraps between words. A bounded page's paging stands in the card's footer strip at its trailing edge, opposite `footer`, which stands at the leading edge: its `status` ("Page 2 of 7") before Previous and Next, which are the product's router links (`previousLink`, `nextLink`) when each page is its own address, and buttons otherwise; the one that leads nowhere stays, disabled. A note about the whole table is `footerNote`, in a strip of its own under that one: one muted line, an optional *Learn more* after it at the left and one secondary action at the right (Vercel's deployments list ends "Deployment retention is enabled. Learn more" with *View recently deleted*); it is the one place a table says a sentence. Colour is neutral: headings and cells in the body grey, no hue, except a status badge or a tone the cell itself carries.
231
+ * @behaviour Every column has a `header`; a column without one does not compile. The headings are always visible, medium weight in the cells' body grey, 48 px high, with 12 px of room under the labels and then the rule, so the first row starts at the rule like every other; rows are 40 px. Each column is as wide as its definition's `size`, in pixels, and the columns without one share the rest, so a table gives a size to every column but the one that takes the spare width; a value too long for its column ends in an ellipsis, whole in its title (a record's name carries its own), unless the column `wraps`; a column marked `identifier` holds ids or paths and is cut in the middle instead. The last column trails unless it `wraps` or is `centered`; a `centered` column's heading and values sit in the middle of it. Records are divided by a 1 px rule, none after the last. The first and last columns stand in from the card's edges by the card's spacing, so the first lines up with the title. Records of several kinds stand in one table under `group` headings (Vercel's Usage page: *Delivery network*, *Functions*): a heading row that spans the columns, in ink, medium text, 36 px high with the same rule under it, one per group in the order the groups first appear, never a second table; a heading is the group's name and carries no figure of its own. A row that opens a record takes `accent` on hover, and any row on focus within and while its menu is open; a row that opens nothing never reacts to hover. A selected row takes `muted`; headers and footers never highlight and carry no fill. A row never scrolls sideways: on a card narrower than its columns (the sized ones and 160 px for each without a size) the row keeps its name and its `primaryColumns`, and every other column leaves it, its value joining the one muted line under the name, joined by a middle dot (a `Tag` reads as its text there); entity facts wrap below the name so every value stays readable, while other rows end in an ellipsis unless a column `wraps`, or `dropped` when its `compact` says so, or beside an entity row's name, which ends in an ellipsis before it, when it says `name`, as Vercel's lists read on a phone: no labels, no second line; an `optional` column's empty value is left out of the line. A table whose every column is in `primaryColumns`, a settings matrix, lays out by its content there instead, so the name wraps beside the columns. A document's table, such as a legal page's, is read whole instead: its columns take the `wraps` option, so their words wrap and the row grows, and it keeps its header row; in the compact layout every cell but the identity wraps between words. A bounded page's paging stands in the card's footer strip at its trailing edge, opposite `footer`, which stands at the leading edge: its `status` ("Page 2 of 7") before Previous and Next, which are the product's router links (`previousLink`, `nextLink`) when each page is its own address, and buttons otherwise; the one that leads nowhere stays, disabled. A note about the whole table is `footerNote`, in a strip of its own under that one: one muted line, an optional *Learn more* after it at the left and one secondary action at the right (Vercel's deployments list ends "Deployment retention is enabled. Learn more" with *View recently deleted*); it is the one place a table says a sentence. Colour is neutral: headings and cells in the body grey, no hue, except a status badge or a tone the cell itself carries.
232
232
  * “When the underlying list is empty (filter cleared, never created), render `Empty State` outside the table rather than an empty `<Table.Body>`.” (https://vercel.com/geist/table)
233
233
  * “After an async filter change, wrap the region in `aria-live="polite"` so screen readers announce the new state.” (https://vercel.com/geist/empty-state)
234
234
  * Ours: empty sits outside the body, in a polite live region that stays in place so a filter that empties the table is announced.
@@ -183,7 +183,7 @@ function DefaultToolbar({ actions }) {
183
183
  * @instead “For a row of descriptive content paired with a single action (membership row, integration row), use `Entity` instead.” (https://vercel.com/geist/table)
184
184
  * “For a key/value metadata block on a detail page, use `Description`, not a two-column table.” (https://vercel.com/geist/table)
185
185
  * Ours: Geist's `Entity` is a `RecordList` row. A registry of entities whose columns `RecordList` cannot hold, more than three facts beside a filter bar the product owns, as Vercel's Deployments list, is this table with `rows="entities"`, which draws the same rows: headings for assistive technology only, 72 px rows, a `RecordIdentity` in the identity column. Its `Description` is `ObjectFacts`. A list on a page of its own is a `CollectionPage`. A descriptive list is `ItemGroup`.
186
- * @behaviour Every column has a `header`; a column without one does not compile. The headings are always visible, medium weight in the cells' body grey, 48 px high, with 12 px of room under the labels and then the rule, so the first row starts at the rule like every other; rows are 40 px. Each column is as wide as its definition's `size`, in pixels, and the columns without one share the rest, so a table gives a size to every column but the one that takes the spare width; a value too long for its column ends in an ellipsis, whole in its title (a record's name carries its own), unless the column `wraps`; a column marked `identifier` holds ids or paths and is cut in the middle instead. The last column trails unless it `wraps` or is `centered`; a `centered` column's heading and values sit in the middle of it. Records are divided by a 1 px rule, none after the last. The first and last columns stand in from the card's edges by the card's spacing, so the first lines up with the title. Records of several kinds stand in one table under `group` headings (Vercel's Usage page: *Delivery network*, *Functions*): a heading row that spans the columns, in ink, medium text, 36 px high with the same rule under it, one per group in the order the groups first appear, never a second table; a heading is the group's name and carries no figure of its own. A row that opens a record takes `accent` on hover, and any row on focus within and while its menu is open; a row that opens nothing never reacts to hover. A selected row takes `muted`; headers and footers never highlight and carry no fill. A row never scrolls sideways: on a card narrower than its columns (the sized ones and 160 px for each without a size) the row keeps its name and its `primaryColumns`, and every other column leaves it, its value joining the one muted line under the name, joined by a middle dot and ending in an ellipsis (a `Tag` reads as its text there, and a `wraps` column's prose wraps the line whole), or `dropped` when its `compact` says so, or beside an entity row's name, which ends in an ellipsis before it, when it says `name`, as Vercel's lists read on a phone: no labels, no second line; an `optional` column's empty value is left out of the line. A table whose every column is in `primaryColumns`, a settings matrix, lays out by its content there instead, so the name wraps beside the columns. A document's table, such as a legal page's, is read whole instead: its columns take the `wraps` option, so their words wrap and the row grows, and it keeps its header row; in the compact layout every cell but the identity wraps between words. A bounded page's paging stands in the card's footer strip at its trailing edge, opposite `footer`, which stands at the leading edge: its `status` ("Page 2 of 7") before Previous and Next, which are the product's router links (`previousLink`, `nextLink`) when each page is its own address, and buttons otherwise; the one that leads nowhere stays, disabled. A note about the whole table is `footerNote`, in a strip of its own under that one: one muted line, an optional *Learn more* after it at the left and one secondary action at the right (Vercel's deployments list ends "Deployment retention is enabled. Learn more" with *View recently deleted*); it is the one place a table says a sentence. Colour is neutral: headings and cells in the body grey, no hue, except a status badge or a tone the cell itself carries.
186
+ * @behaviour Every column has a `header`; a column without one does not compile. The headings are always visible, medium weight in the cells' body grey, 48 px high, with 12 px of room under the labels and then the rule, so the first row starts at the rule like every other; rows are 40 px. Each column is as wide as its definition's `size`, in pixels, and the columns without one share the rest, so a table gives a size to every column but the one that takes the spare width; a value too long for its column ends in an ellipsis, whole in its title (a record's name carries its own), unless the column `wraps`; a column marked `identifier` holds ids or paths and is cut in the middle instead. The last column trails unless it `wraps` or is `centered`; a `centered` column's heading and values sit in the middle of it. Records are divided by a 1 px rule, none after the last. The first and last columns stand in from the card's edges by the card's spacing, so the first lines up with the title. Records of several kinds stand in one table under `group` headings (Vercel's Usage page: *Delivery network*, *Functions*): a heading row that spans the columns, in ink, medium text, 36 px high with the same rule under it, one per group in the order the groups first appear, never a second table; a heading is the group's name and carries no figure of its own. A row that opens a record takes `accent` on hover, and any row on focus within and while its menu is open; a row that opens nothing never reacts to hover. A selected row takes `muted`; headers and footers never highlight and carry no fill. A row never scrolls sideways: on a card narrower than its columns (the sized ones and 160 px for each without a size) the row keeps its name and its `primaryColumns`, and every other column leaves it, its value joining the one muted line under the name, joined by a middle dot (a `Tag` reads as its text there); entity facts wrap below the name so every value stays readable, while other rows end in an ellipsis unless a column `wraps`, or `dropped` when its `compact` says so, or beside an entity row's name, which ends in an ellipsis before it, when it says `name`, as Vercel's lists read on a phone: no labels, no second line; an `optional` column's empty value is left out of the line. A table whose every column is in `primaryColumns`, a settings matrix, lays out by its content there instead, so the name wraps beside the columns. A document's table, such as a legal page's, is read whole instead: its columns take the `wraps` option, so their words wrap and the row grows, and it keeps its header row; in the compact layout every cell but the identity wraps between words. A bounded page's paging stands in the card's footer strip at its trailing edge, opposite `footer`, which stands at the leading edge: its `status` ("Page 2 of 7") before Previous and Next, which are the product's router links (`previousLink`, `nextLink`) when each page is its own address, and buttons otherwise; the one that leads nowhere stays, disabled. A note about the whole table is `footerNote`, in a strip of its own under that one: one muted line, an optional *Learn more* after it at the left and one secondary action at the right (Vercel's deployments list ends "Deployment retention is enabled. Learn more" with *View recently deleted*); it is the one place a table says a sentence. Colour is neutral: headings and cells in the body grey, no hue, except a status badge or a tone the cell itself carries.
187
187
  * “When the underlying list is empty (filter cleared, never created), render `Empty State` outside the table rather than an empty `<Table.Body>`.” (https://vercel.com/geist/table)
188
188
  * “After an async filter change, wrap the region in `aria-live="polite"` so screen readers announce the new state.” (https://vercel.com/geist/empty-state)
189
189
  * Ours: empty sits outside the body, in a polite live region that stays in place so a filter that empties the table is announced.
@@ -291,8 +291,6 @@ function RecordsTable({ kind, columns, data, getRowId, filterColumnId, filterPla
291
291
  wraps: cell.column.columnDef.meta?.wraps === true,
292
292
  besideName: entities && cell.column.columnDef.meta?.compact === "name",
293
293
  }));
294
- // An entity row keeps its record on one 72 px row on a narrow card: the facts that leave the
295
- // row join the line under the name, which `RecordIdentity` draws, instead of a row of their own.
296
294
  // The line's provider stays in the tree when the card is wide enough for the columns and only
297
295
  // its facts go, so a layout read after hydration never remounts the name a click is landing on.
298
296
  const compactLine = entities && compactLayout && detailCells.length > 0
@@ -323,8 +321,7 @@ function RecordsTable({ kind, columns, data, getRowId, filterColumnId, filterPla
323
321
  return _jsx(TableCell, { className: className }, cell.id);
324
322
  }
325
323
  const content = holdsCompactLine ? (_jsx(TableCompactLine, { ...compactLine, children: renderCell(cell) })) : (renderCell(cell));
326
- const titledWhenCut = cutByEllipsis || (holdsCompactLine && compactLine.facts.length > 0);
327
- return (_jsx(TableCell, { className: className, onFocus: titledWhenCut ? titleWhenCut : undefined, onPointerEnter: titledWhenCut ? titleWhenCut : undefined, children: isPrimaryLink
324
+ return (_jsx(TableCell, { className: className, onFocus: cutByEllipsis ? titleWhenCut : undefined, onPointerEnter: cutByEllipsis ? titleWhenCut : undefined, children: isPrimaryLink
328
325
  ? renderRowLink(primaryRowLinkProps({ href, label, wraps, content }))
329
326
  : content }, cell.id));
330
327
  }) }), rowEditor?.rowId === row.id ? (_jsx(TableRow, { "data-slot": "table-row-editor", className: "h-auto! [&>td]:bg-transparent!", children: _jsx(TableCell, { colSpan: visibleCells.length, className: "p-0 whitespace-normal", children: rowEditor.render(row.original) }) })) : null, detailRowShown ? (_jsx(TableDetailRow, { layout: compactLayout, colSpan: visibleCells.filter((cell) => !collapseClass(cell.column, primaryColumns, compactLayout)).length, facts: detailFacts() })) : null] }));
@@ -8,7 +8,7 @@ import { type IdentityMarkProps } from "./identity-mark.js";
8
8
  * @family Status
9
9
  * @when The first cell of every collection row: the mark, the name, and one muted line saying what the record is or where it comes from, so the row reads without a heading.
10
10
  * @instead An Agent in a gallery is `AgentListRow`; a model is `ModelIdentity`. A descriptive item with prose and actions is `Item`.
11
- * @behaviour The mark stands 16 px before the name. The name is semibold (600) ink and the detail a muted 14 px line, two lines with no gap between them, so the row is an entity row; `mark` is required; a record with nothing to say under its name leaves `detail` out and is the name alone, never a dash, which is a table cell's missing value and not a record's. The name holds one line and ends in an ellipsis, whole in its title, with a `hint` such as an ID read after it. The detail is one line too and ends in an ellipsis, whole in its title when it is text; in a row on a card narrower than its columns, the facts that leave the row join it after a middle dot, so the record stays the name over one line, and a status that leaves the row stands beside the name, which ends in an ellipsis before it. `wraps` only when the name is the whole record, such as a memory, and then the detail wraps too. The table owns the link.
11
+ * @behaviour The mark stands 16 px before the name. The name is semibold (600) ink and the detail a muted 14 px line, two lines with no gap between them, so the row is an entity row; `mark` is required; a record with nothing to say under its name leaves `detail` out and is the name alone, never a dash, which is a table cell's missing value and not a record's. The name holds one line and ends in an ellipsis, whole in its title, with a `hint` such as an ID read after it. The detail is one line too and ends in an ellipsis, whole in its title when it is text; in a row on a card narrower than its columns, the facts that leave the row join it after a middle dot and wrap so every value stays readable, and a status that leaves the row stands beside the name, which ends in an ellipsis before it. `wraps` only when the name is the whole record, such as a memory, and then the detail wraps too. The table owns the link.
12
12
  * @words “Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).” (https://vercel.com/geist/entity)
13
13
  * Ours: the name as the record calls itself, and the detail in sentence case: kind, then relation, three to six words, "Company skill · every Agent has it".
14
14
  * @access The name is the row link's text; the mark is decorative; the title carries the full name.
@@ -1 +1 @@
1
- {"version":3,"file":"record-identity.d.ts","sourceRoot":"","sources":["../../src/components/record-identity.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIlF;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,KAAa,GACd,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,8FAA8F;IAC9F,IAAI,EAAE,iBAAiB,CAAC;IACxB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,+BAsCA;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"record-identity.d.ts","sourceRoot":"","sources":["../../src/components/record-identity.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIlF;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,EACtB,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,KAAa,GACd,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,8FAA8F;IAC9F,IAAI,EAAE,iBAAiB,CAAC;IACxB,qFAAqF;IACrF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,+BAoCA;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -10,7 +10,7 @@ import { cn } from "../lib/utils.js";
10
10
  * @family Status
11
11
  * @when The first cell of every collection row: the mark, the name, and one muted line saying what the record is or where it comes from, so the row reads without a heading.
12
12
  * @instead An Agent in a gallery is `AgentListRow`; a model is `ModelIdentity`. A descriptive item with prose and actions is `Item`.
13
- * @behaviour The mark stands 16 px before the name. The name is semibold (600) ink and the detail a muted 14 px line, two lines with no gap between them, so the row is an entity row; `mark` is required; a record with nothing to say under its name leaves `detail` out and is the name alone, never a dash, which is a table cell's missing value and not a record's. The name holds one line and ends in an ellipsis, whole in its title, with a `hint` such as an ID read after it. The detail is one line too and ends in an ellipsis, whole in its title when it is text; in a row on a card narrower than its columns, the facts that leave the row join it after a middle dot, so the record stays the name over one line, and a status that leaves the row stands beside the name, which ends in an ellipsis before it. `wraps` only when the name is the whole record, such as a memory, and then the detail wraps too. The table owns the link.
13
+ * @behaviour The mark stands 16 px before the name. The name is semibold (600) ink and the detail a muted 14 px line, two lines with no gap between them, so the row is an entity row; `mark` is required; a record with nothing to say under its name leaves `detail` out and is the name alone, never a dash, which is a table cell's missing value and not a record's. The name holds one line and ends in an ellipsis, whole in its title, with a `hint` such as an ID read after it. The detail is one line too and ends in an ellipsis, whole in its title when it is text; in a row on a card narrower than its columns, the facts that leave the row join it after a middle dot and wrap so every value stays readable, and a status that leaves the row stands beside the name, which ends in an ellipsis before it. `wraps` only when the name is the whole record, such as a memory, and then the detail wraps too. The table owns the link.
14
14
  * @words “Lead the left column with a scannable identifier: an `Avatar` or icon, a Title Case label, then sentence-case secondary metadata (`Member since Mar 14, 2026`).” (https://vercel.com/geist/entity)
15
15
  * Ours: the name as the record calls itself, and the detail in sentence case: kind, then relation, three to six words, "Company skill · every Agent has it".
16
16
  * @access The name is the row link's text; the mark is decorative; the title carries the full name.
@@ -21,9 +21,7 @@ function RecordIdentity({ name, mark, hint, detail, wraps = false, }) {
21
21
  return (_jsxs("span", { className: "flex min-w-0 items-center gap-4", "data-slot": "record-identity", children: [_jsx(IdentityMark, { ...mark, size: 32 }), _jsxs("span", { className: "grid min-w-0 in-[table]:w-0 in-[table]:flex-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { className: cn("min-w-0 font-semibold text-foreground", wraps ? "break-words whitespace-pre-wrap" : "truncate"), title: wraps ? undefined : title, children: name }), _jsx(TableCompactNameFacts, {})] }), _jsxs("span", { className: cn(
22
22
  // The line is the containing block of the facts' screen-reader labels, so what it cuts
23
23
  // stays cut instead of widening the table.
24
- "relative text-sm text-muted-foreground", wraps
25
- ? "break-words whitespace-normal"
26
- : "truncate has-[[data-wraps]]:break-words has-[[data-wraps]]:whitespace-normal"), "data-slot": "record-identity-detail",
24
+ "relative text-sm text-muted-foreground", wraps ? "break-words whitespace-normal" : "truncate"), "data-slot": "record-identity-detail",
27
25
  // oxlint-disable-next-line anti-slop/no-runtime-typeof -- detail is a ReactNode; only a string can be a title attribute.
28
26
  title: !wraps && typeof detail === "string" ? detail : undefined, children: [detail, _jsx(TableCompactFacts, {})] })] })] }));
29
27
  }
@@ -189,7 +189,7 @@ export type RecordListWithout<TRecord extends RowData, Key extends PropertyKey>
189
189
  * @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
190
190
  * “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
191
191
  * Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table, and anything more than a few facts lives on the record's page. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and nothing else draws a record row. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
192
- * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as one muted line joined by a middle dot, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that one line, ending in an ellipsis, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
192
+ * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
193
193
  * “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state)
194
194
  * Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
195
195
  * “The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.” (https://vercel.com/geist/entity)
@@ -250,7 +250,7 @@ function RecordRows(props) {
250
250
  * @instead “For tabular data with sortable columns and shared row shape, use `Table` instead.” (https://vercel.com/geist/entity)
251
251
  * “For a static key/value metadata block on a detail page, use `Description`.” (https://vercel.com/geist/entity)
252
252
  * Ours: Geist's `Table` is a `DataTable`: this list has no visible headings and at most three facts, so a fourth fact is a table, and anything more than a few facts lives on the record's page. A screen gives `RecordList` the records and what each one says, never its own toolbar, table, rows or menus, and nothing else draws a record row. Its `Description` is `ObjectFacts`. Events in time are an `ActivityFeed`. Reusable things a person adds from a catalogue are a `LibraryShelf`. A descriptive row with prose is an `Item`.
253
- * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as one muted line joined by a middle dot, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that one line, ending in an ellipsis, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
253
+ * @behaviour One bordered card, a 1 px rule between records and none after the last. A row is 72 px, with 16 px above and below, and its columns stand left to right at the widths the list declares, so a person reads every list the same way: the `select` box (40 px, only when the list is picked from, an optional column), the identity (the rest: the one column without a size), the facts (each its `size`), the status (`status.size`), the time (`time.size`, tabular), the `checklist` ring (52 px, only when the record has steps to be ready) and the commands (`commandsSize`; left out, 64 px for the three dots alone). A `checklist` puts the record's `ProgressChecklist` ring just before its commands, where Vercel ends a project's row with its Production Checklist; the ring opens its own drawer, never the row. Every row has its 32 px mark, its name (600) and, under it, one muted 14 px line; `name` and the mark are required; a record with nothing to say under its name leaves the line out and is the name alone, never a dash. Give every column a `size` in pixels; the name takes the rest. With `layout="line"`, as on Vercel's Projects page, the facts and the status share one muted line, joined by a middle dot, in a column as wide as the name's, and the row stays one line (mark, name over its line, that summary, the time, the ring, the three dots) on a card from 448 px, and on a narrower card the summary and the time move under the name as muted text joined by a middle dot that wraps, in the same row, their labels read by assistive technology only. Rows of `columns` follow the same rule once the card is narrower than their columns: the facts and the time leave the row for that muted text, wrapping so every value stays readable, never a labelled list, and the status stands beside the name, which ends in an ellipsis before it, so the exception is never the part a phone's line cuts. `facts` takes at most three. A menu of one command that is not destructive, with no row command, is that command's button, except in a `line` row, which keeps it in the three dots as Vercel's project row does; without a `commandsSize` the column is as wide as the widest such button, so its label is never cut. Status is only for the exception, empty for the usual record, and its column stands only while a record in the list shows one, so the name and its line keep the room; the commands column likewise stands only while a record has a command, a menu or a message, or the rows open, and it widens for a failed action's next steps only while a row shows one. Never the three dots before the button, a decorative icon for the record's mark, a status on every row, or a destructive button on every row: a destructive command stays in the three dots. A `line` row's summary joins only the facts the record has, so it never ends in a dot. A failed or refused action of the record shows as its catalogue message inside its own row, never a notice under the row: it replaces the detail line, with its next steps beside its commands, or under the message on a card too narrow for the row's columns. With `open` the whole row is one target and takes the `accent` hover, and a row that only opens ends in a muted chevron; a row that opens nothing never reacts to hover. With `editor` the record's row opens its form under its line. `empty` is required: `null` is the choice to draw nothing for a list with no records, and any other value is the state it draws. A note about the whole list is `footer.note`: one muted line, an optional *Learn more* after it at the left and one secondary action at the right, in a strip of its own under the count and the paging, as Vercel ends its deployments list ("Deployment retention is enabled. Learn more", *View recently deleted*). Colour is neutral, the name in ink and every other cell in the body grey, except the status badge and a failed action's message.
254
254
  * “Pick the variant by what the user needs: no-results for a filtered list that returned zero rows, blank slate or informational for a resource the user hasn’t created, cleared for completed work, permission for role or tier denials, error for a failed load.” (https://vercel.com/geist/empty-state)
255
255
  * Ours: `failed`, `noMatch` and `empty` are those variants, drawn inside the card.
256
256
  * “The right column holds at most one or two controls. If the row needs more, move secondary actions into a `Dots Menu`.” (https://vercel.com/geist/entity)
@@ -31,7 +31,7 @@ export type ScopeSwitcherProps = {
31
31
  * @family Navigation
32
32
  * @when Changing which part of the account a page reads, such as Analytics' scope, or switching between objects from the shell's top bar with `variant="navigation"`.
33
33
  * @instead A viewer with one scope and nothing to create reads its name with no control, which this draws by itself. Finding anything is `CommandDialog`; narrowing rows is `CollectionFilters`.
34
- * @behaviour A ghost trigger, at most 16rem, opens a 288 px popover with focus in its search. Navigation omits the visible prefix, carries each option's identity mark and opens a 384 px popover constrained to the viewport. Type to filter, Enter chooses and closes; choosing the current one changes nothing. The caller writes the choice to the URL in `onValueChange`, so sibling pages keep it. An optional create command sits last.
34
+ * @behaviour A ghost trigger, at most 16rem, opens a 288 px popover with focus in its search. Navigation omits the visible prefix, wraps the selected name on phones instead of cutting it, carries each option's identity mark and opens a 384 px popover constrained to the viewport. Type to filter, Enter chooses and closes; choosing the current one changes nothing. The caller writes the choice to the URL in `onValueChange`, so sibling pages keep it. An optional create command sits last.
35
35
  * @words `copy.label` names what is chosen ("Scope") beside the current scope's name. Search and empty lines name the thing: "Find a scope", "No scope matches".
36
36
  * @access The trigger reads "Scope: All customers"; the popover has a hidden title; options are a listbox with the current one checked.
37
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"scope-switcher.d.ts","sourceRoot":"","sources":["../../src/components/scope-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,8DAA8D;IAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CAClC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,aAAa,EACb,IAAI,EACJ,MAAM,EACN,OAAiB,GAClB,EAAE,kBAAkB,qBA0GpB"}
1
+ {"version":3,"file":"scope-switcher.d.ts","sourceRoot":"","sources":["../../src/components/scope-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,8DAA8D;IAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CAClC,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,aAAa,EACb,IAAI,EACJ,MAAM,EACN,OAAiB,GAClB,EAAE,kBAAkB,qBAsHpB"}
@@ -12,7 +12,7 @@ import { cn } from "../lib/utils.js";
12
12
  * @family Navigation
13
13
  * @when Changing which part of the account a page reads, such as Analytics' scope, or switching between objects from the shell's top bar with `variant="navigation"`.
14
14
  * @instead A viewer with one scope and nothing to create reads its name with no control, which this draws by itself. Finding anything is `CommandDialog`; narrowing rows is `CollectionFilters`.
15
- * @behaviour A ghost trigger, at most 16rem, opens a 288 px popover with focus in its search. Navigation omits the visible prefix, carries each option's identity mark and opens a 384 px popover constrained to the viewport. Type to filter, Enter chooses and closes; choosing the current one changes nothing. The caller writes the choice to the URL in `onValueChange`, so sibling pages keep it. An optional create command sits last.
15
+ * @behaviour A ghost trigger, at most 16rem, opens a 288 px popover with focus in its search. Navigation omits the visible prefix, wraps the selected name on phones instead of cutting it, carries each option's identity mark and opens a 384 px popover constrained to the viewport. Type to filter, Enter chooses and closes; choosing the current one changes nothing. The caller writes the choice to the URL in `onValueChange`, so sibling pages keep it. An optional create command sits last.
16
16
  * @words `copy.label` names what is chosen ("Scope") beside the current scope's name. Search and empty lines name the thing: "Find a scope", "No scope matches".
17
17
  * @access The trigger reads "Scope: All customers"; the popover has a hidden title; options are a listbox with the current one checked.
18
18
  */
@@ -36,7 +36,10 @@ export function ScopeSwitcher({ value, options, onValueChange, copy, create, var
36
36
  onValueChange(next);
37
37
  };
38
38
  const switchable = options.length > 1 || create !== undefined;
39
- return (_jsxs("span", { "data-slot": "scope-switcher", className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { "aria-hidden": switchable ? "true" : undefined, className: cn("text-xs font-medium text-muted-foreground", variant === "navigation" && "sr-only"), children: copy.label }), switchable ? (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsxs(PopoverTrigger, { render: _jsx(Button, { variant: "ghost", className: "min-w-0 max-w-64 shrink", prefix: current?.mark ? _jsx("span", { "aria-hidden": "true", children: current.mark }) : undefined, suffix: _jsx(ChevronsUpDown, { "aria-hidden": "true" }) }), children: [_jsxs("span", { className: "sr-only", children: [copy.label, ":"] }), " ", _jsx("span", { className: "truncate", children: currentLabel })] }), _jsxs(PopoverContent, { align: "start", className: cn("w-72 max-w-[calc(100vw-2rem)] p-0", variant === "navigation" && "w-96"), initialFocus: search, children: [_jsx(PopoverTitle, { className: "sr-only", children: copy.label }), _jsxs(Command, { label: copy.search, resultCount: copy.results, children: [_jsx(CommandInput, { ref: search, "aria-label": copy.search, placeholder: copy.search }), _jsxs(CommandList, { label: copy.label, children: [_jsx(CommandEmpty, { children: copy.empty }), groups.map(([group, items]) => (_jsx(CommandGroup, { heading: group, children: items.map((option) => (_jsxs(CommandItem, { value: option.value, keywords: [
39
+ return (_jsxs("span", { "data-slot": "scope-switcher", className: "flex min-w-0 items-center gap-2", children: [_jsx("span", { "aria-hidden": switchable ? "true" : undefined, className: cn("text-xs font-medium text-muted-foreground", variant === "navigation" && "sr-only"), children: copy.label }), switchable ? (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsxs(PopoverTrigger, { render: _jsx(Button, { variant: "ghost", className: cn("min-w-0 max-w-64 shrink", variant === "navigation" &&
40
+ "h-auto max-w-full py-1 md:h-control-height md:max-w-64 md:py-0"), prefix: current?.mark ? _jsx("span", { "aria-hidden": "true", children: current.mark }) : undefined, suffix: _jsx(ChevronsUpDown, { "aria-hidden": "true" }) }), children: [_jsxs("span", { className: "sr-only", children: [copy.label, ":"] }), " ", _jsx("span", { className: cn(variant === "navigation"
41
+ ? "whitespace-normal break-words text-left md:truncate"
42
+ : "truncate"), children: currentLabel })] }), _jsxs(PopoverContent, { align: "start", className: cn("w-72 max-w-[calc(100vw-2rem)] p-0", variant === "navigation" && "w-96"), initialFocus: search, children: [_jsx(PopoverTitle, { className: "sr-only", children: copy.label }), _jsxs(Command, { label: copy.search, resultCount: copy.results, children: [_jsx(CommandInput, { ref: search, "aria-label": copy.search, placeholder: copy.search }), _jsxs(CommandList, { label: copy.label, children: [_jsx(CommandEmpty, { children: copy.empty }), groups.map(([group, items]) => (_jsx(CommandGroup, { heading: group, children: items.map((option) => (_jsxs(CommandItem, { value: option.value, keywords: [
40
43
  option.label,
41
44
  ...(option.group ? [option.group] : []),
42
45
  ...(option.keywords ?? []),
@@ -6,7 +6,7 @@ export declare const tableCompactLayouts: {
6
6
  readonly track: "hidden @md/table:table-column";
7
7
  readonly row: "@max-md/table:[&>td]:border-b-0 @max-md/table:[&>td]:after:hidden @max-md/table:h-auto! @max-md/table:[&>td]:pb-1!";
8
8
  readonly details: "@md/table:hidden";
9
- readonly table: "@max-md/table:table-auto @max-md/table:[&_td]:whitespace-normal @max-md/table:[&_th:not(:first-child):not([data-identity])]:w-px @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child)]:pl-0 @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child):not(:last-child)]:pr-0";
9
+ readonly table: "@max-md/table:table-auto @max-md/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-md/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-md/table:[&_td]:whitespace-normal @max-md/table:[&_th:not(:first-child):not([data-identity])]:w-px @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child)]:pl-0 @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child):not(:last-child)]:pr-0";
10
10
  };
11
11
  readonly tight: {
12
12
  readonly width: 576;
@@ -14,7 +14,7 @@ export declare const tableCompactLayouts: {
14
14
  readonly track: "hidden @xl/table:table-column";
15
15
  readonly row: "@max-xl/table:[&>td]:border-b-0 @max-xl/table:[&>td]:after:hidden @max-xl/table:h-auto! @max-xl/table:[&>td]:pb-1!";
16
16
  readonly details: "@xl/table:hidden";
17
- readonly table: "@max-xl/table:table-auto @max-xl/table:[&_td]:whitespace-normal @max-xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
17
+ readonly table: "@max-xl/table:table-auto @max-xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-xl/table:[&_td]:whitespace-normal @max-xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
18
18
  };
19
19
  readonly standard: {
20
20
  readonly width: 768;
@@ -22,7 +22,7 @@ export declare const tableCompactLayouts: {
22
22
  readonly track: "hidden @3xl/table:table-column";
23
23
  readonly row: "@max-3xl/table:[&>td]:border-b-0 @max-3xl/table:[&>td]:after:hidden @max-3xl/table:h-auto! @max-3xl/table:[&>td]:pb-1!";
24
24
  readonly details: "@3xl/table:hidden";
25
- readonly table: "@max-3xl/table:table-auto @max-3xl/table:[&_td]:whitespace-normal @max-3xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
25
+ readonly table: "@max-3xl/table:table-auto @max-3xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-3xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-3xl/table:[&_td]:whitespace-normal @max-3xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
26
26
  };
27
27
  readonly wide: {
28
28
  readonly width: 1024;
@@ -30,7 +30,7 @@ export declare const tableCompactLayouts: {
30
30
  readonly track: "hidden @5xl/table:table-column";
31
31
  readonly row: "@max-5xl/table:[&>td]:border-b-0 @max-5xl/table:[&>td]:after:hidden @max-5xl/table:h-auto! @max-5xl/table:[&>td]:pb-1!";
32
32
  readonly details: "@5xl/table:hidden";
33
- readonly table: "@max-5xl/table:table-auto @max-5xl/table:[&_td]:whitespace-normal @max-5xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
33
+ readonly table: "@max-5xl/table:table-auto @max-5xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-5xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-5xl/table:[&_td]:whitespace-normal @max-5xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
34
34
  };
35
35
  readonly roomy: {
36
36
  readonly width: 1088;
@@ -38,7 +38,7 @@ export declare const tableCompactLayouts: {
38
38
  readonly track: "hidden @min-[68rem]/table:table-column";
39
39
  readonly row: "@max-[68rem]/table:[&>td]:border-b-0 @max-[68rem]/table:[&>td]:after:hidden @max-[68rem]/table:h-auto! @max-[68rem]/table:[&>td]:pb-1!";
40
40
  readonly details: "@min-[68rem]/table:hidden";
41
- readonly table: "@max-[68rem]/table:table-auto @max-[68rem]/table:[&_td]:whitespace-normal @max-[68rem]/table:[&_th:not(:first-child):not([data-identity])]:w-px";
41
+ readonly table: "@max-[68rem]/table:table-auto @max-[68rem]/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-[68rem]/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-[68rem]/table:[&_td]:whitespace-normal @max-[68rem]/table:[&_th:not(:first-child):not([data-identity])]:w-px";
42
42
  };
43
43
  readonly spacious: {
44
44
  readonly width: 1152;
@@ -46,14 +46,14 @@ export declare const tableCompactLayouts: {
46
46
  readonly track: "hidden @6xl/table:table-column";
47
47
  readonly row: "@max-6xl/table:[&>td]:border-b-0 @max-6xl/table:[&>td]:after:hidden @max-6xl/table:h-auto! @max-6xl/table:[&>td]:pb-1!";
48
48
  readonly details: "@6xl/table:hidden";
49
- readonly table: "@max-6xl/table:table-auto @max-6xl/table:[&_td]:whitespace-normal @max-6xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
49
+ readonly table: "@max-6xl/table:table-auto @max-6xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-6xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-6xl/table:[&_td]:whitespace-normal @max-6xl/table:[&_th:not(:first-child):not([data-identity])]:w-px";
50
50
  };
51
51
  };
52
52
  export type TableCompactLayout = keyof typeof tableCompactLayouts;
53
53
  /**
54
54
  * The compact layout for columns of these sizes: the narrowest card width at which every sized
55
55
  * column, and a floor for each column without a size, still fit. A card narrower than that
56
- * leaves its secondary columns out of the row: each joins the one muted line under the name, or is
56
+ * leaves its secondary columns out of the row: each joins the muted text under the name, or is
57
57
  * dropped.
58
58
  */
59
59
  export declare function compactLayoutFor(sizes: readonly (number | undefined)[]): TableCompactLayout;
@@ -6,7 +6,7 @@ export const tableCompactLayouts = {
6
6
  track: "hidden @md/table:table-column",
7
7
  row: "@max-md/table:[&>td]:border-b-0 @max-md/table:[&>td]:after:hidden @max-md/table:h-auto! @max-md/table:[&>td]:pb-1!",
8
8
  details: "@md/table:hidden",
9
- table: "@max-md/table:table-auto @max-md/table:[&_td]:whitespace-normal @max-md/table:[&_th:not(:first-child):not([data-identity])]:w-px @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child)]:pl-0 @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child):not(:last-child)]:pr-0",
9
+ table: "@max-md/table:table-auto @max-md/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-md/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-md/table:[&_td]:whitespace-normal @max-md/table:[&_th:not(:first-child):not([data-identity])]:w-px @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child)]:pl-0 @max-md/table:[&_tr:not([data-slot=table-detail-row])>td:not(:first-child):not(:last-child)]:pr-0",
10
10
  },
11
11
  tight: {
12
12
  width: 576,
@@ -14,7 +14,7 @@ export const tableCompactLayouts = {
14
14
  track: "hidden @xl/table:table-column",
15
15
  row: "@max-xl/table:[&>td]:border-b-0 @max-xl/table:[&>td]:after:hidden @max-xl/table:h-auto! @max-xl/table:[&>td]:pb-1!",
16
16
  details: "@xl/table:hidden",
17
- table: "@max-xl/table:table-auto @max-xl/table:[&_td]:whitespace-normal @max-xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
17
+ table: "@max-xl/table:table-auto @max-xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-xl/table:[&_td]:whitespace-normal @max-xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
18
18
  },
19
19
  standard: {
20
20
  width: 768,
@@ -22,7 +22,7 @@ export const tableCompactLayouts = {
22
22
  track: "hidden @3xl/table:table-column",
23
23
  row: "@max-3xl/table:[&>td]:border-b-0 @max-3xl/table:[&>td]:after:hidden @max-3xl/table:h-auto! @max-3xl/table:[&>td]:pb-1!",
24
24
  details: "@3xl/table:hidden",
25
- table: "@max-3xl/table:table-auto @max-3xl/table:[&_td]:whitespace-normal @max-3xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
25
+ table: "@max-3xl/table:table-auto @max-3xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-3xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-3xl/table:[&_td]:whitespace-normal @max-3xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
26
26
  },
27
27
  wide: {
28
28
  width: 1024,
@@ -30,7 +30,7 @@ export const tableCompactLayouts = {
30
30
  track: "hidden @5xl/table:table-column",
31
31
  row: "@max-5xl/table:[&>td]:border-b-0 @max-5xl/table:[&>td]:after:hidden @max-5xl/table:h-auto! @max-5xl/table:[&>td]:pb-1!",
32
32
  details: "@5xl/table:hidden",
33
- table: "@max-5xl/table:table-auto @max-5xl/table:[&_td]:whitespace-normal @max-5xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
33
+ table: "@max-5xl/table:table-auto @max-5xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-5xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-5xl/table:[&_td]:whitespace-normal @max-5xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
34
34
  },
35
35
  roomy: {
36
36
  width: 1088,
@@ -38,7 +38,7 @@ export const tableCompactLayouts = {
38
38
  track: "hidden @min-[68rem]/table:table-column",
39
39
  row: "@max-[68rem]/table:[&>td]:border-b-0 @max-[68rem]/table:[&>td]:after:hidden @max-[68rem]/table:h-auto! @max-[68rem]/table:[&>td]:pb-1!",
40
40
  details: "@min-[68rem]/table:hidden",
41
- table: "@max-[68rem]/table:table-auto @max-[68rem]/table:[&_td]:whitespace-normal @max-[68rem]/table:[&_th:not(:first-child):not([data-identity])]:w-px",
41
+ table: "@max-[68rem]/table:table-auto @max-[68rem]/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-[68rem]/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-[68rem]/table:[&_td]:whitespace-normal @max-[68rem]/table:[&_th:not(:first-child):not([data-identity])]:w-px",
42
42
  },
43
43
  spacious: {
44
44
  width: 1152,
@@ -46,7 +46,7 @@ export const tableCompactLayouts = {
46
46
  track: "hidden @6xl/table:table-column",
47
47
  row: "@max-6xl/table:[&>td]:border-b-0 @max-6xl/table:[&>td]:after:hidden @max-6xl/table:h-auto! @max-6xl/table:[&>td]:pb-1!",
48
48
  details: "@6xl/table:hidden",
49
- table: "@max-6xl/table:table-auto @max-6xl/table:[&_td]:whitespace-normal @max-6xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
49
+ table: "@max-6xl/table:table-auto @max-6xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:whitespace-normal @max-6xl/table:[&_[data-slot=record-identity-detail]:has([data-slot=table-detail-line])]:break-words @max-6xl/table:[&_td]:whitespace-normal @max-6xl/table:[&_th:not(:first-child):not([data-identity])]:w-px",
50
50
  },
51
51
  };
52
52
  /** The least a column without a size needs, in pixels: below it the card lays out compact. */
@@ -61,7 +61,7 @@ const NARROWEST_FIRST = [
61
61
  /**
62
62
  * The compact layout for columns of these sizes: the narrowest card width at which every sized
63
63
  * column, and a floor for each column without a size, still fit. A card narrower than that
64
- * leaves its secondary columns out of the row: each joins the one muted line under the name, or is
64
+ * leaves its secondary columns out of the row: each joins the muted text under the name, or is
65
65
  * dropped.
66
66
  */
67
67
  export function compactLayoutFor(sizes) {
@@ -39,8 +39,8 @@ type TableName = AccessibleName | {
39
39
  * it, one muted line joined by a middle dot that ends in an ellipsis, their labels read by assistive
40
40
  * technology only, as Vercel's lists read on a phone; a `Tag` there reads as its plain text, and a
41
41
  * fact that `wraps` lets the line wrap whole instead of ending in an ellipsis. An entity row
42
- * (`density="comfortable"`) keeps its record on one 72 px row instead: its facts join the line
43
- * under the name that `RecordIdentity` draws (`TableCompactLine`), so the row is the name over one line. Colour is neutral throughout: headings and cells share
42
+ * (`density="comfortable"`) keeps its facts in the identity cell instead: they join the text
43
+ * under the name that `RecordIdentity` draws (`TableCompactLine`), and wrap so every value stays readable. Colour is neutral throughout: headings and cells share
44
44
  * the body grey and a heading differs by weight, the footer is ink, and the hue of a state lives in
45
45
  * the `StatusBadge` of a cell, never in the row.
46
46
  * “Sortable column headers are buttons. The visible label stays Title Case; the sort-direction arrow is decorative and the button announces the next sort state to assistive tech.” (https://vercel.com/geist/table)
@@ -37,8 +37,8 @@ import { titleWhenCut } from "../internal/title-when-cut.js";
37
37
  * it, one muted line joined by a middle dot that ends in an ellipsis, their labels read by assistive
38
38
  * technology only, as Vercel's lists read on a phone; a `Tag` there reads as its plain text, and a
39
39
  * fact that `wraps` lets the line wrap whole instead of ending in an ellipsis. An entity row
40
- * (`density="comfortable"`) keeps its record on one 72 px row instead: its facts join the line
41
- * under the name that `RecordIdentity` draws (`TableCompactLine`), so the row is the name over one line. Colour is neutral throughout: headings and cells share
40
+ * (`density="comfortable"`) keeps its facts in the identity cell instead: they join the text
41
+ * under the name that `RecordIdentity` draws (`TableCompactLine`), and wrap so every value stays readable. Colour is neutral throughout: headings and cells share
42
42
  * the body grey and a heading differs by weight, the footer is ink, and the hue of a state lives in
43
43
  * the `StatusBadge` of a cell, never in the row.
44
44
  * “Sortable column headers are buttons. The visible label stays Title Case; the sort-direction arrow is decorative and the button announces the next sort state to assistive tech.” (https://vercel.com/geist/table)
@@ -1,23 +1,54 @@
1
1
  import type { AgentOrbFigure } from "./agent-orb.js";
2
2
  export type AgentOrbState = "idle" | "working" | "waiting" | "blocked" | "thinking" | "done";
3
3
  export declare function nativeSpeed(form: AgentOrbFigure): number;
4
- export declare function stateSpeed(state: AgentOrbState, form: AgentOrbFigure): number;
4
+ export declare function stateSpeed(state: AgentOrbState, form: AgentOrbFigure, age?: number, timing?: {
5
+ wait: number;
6
+ confirm: number;
7
+ transition: number;
8
+ doneDuration: number;
9
+ blockedDuration: number;
10
+ gestureAge: (age: number) => number;
11
+ settle: (age: number, delay?: number) => number;
12
+ }): number;
5
13
  /**
6
14
  * Reduced motion turns movement off and keeps opacity and colour, so a
7
15
  * thinking or working orb breathes between full ink and 0.45 over 1.6 s,
8
16
  * ease-in-out, and busy still reads as busy. Every other state holds still.
9
17
  */
10
18
  export declare function reducedBreath(state: AgentOrbState, seconds: number): number;
11
- export declare function motionPose(form: AgentOrbFigure, state: AgentOrbState, age: number): {
19
+ export declare function readOrbTiming(style?: CSSStyleDeclaration): {
20
+ wait: number;
21
+ confirm: number;
22
+ transition: number;
23
+ doneDuration: number;
24
+ blockedDuration: number;
25
+ gestureAge: (age: number) => number;
26
+ settle: (age: number, delay?: number) => number;
27
+ };
28
+ export declare function motionPose(state: AgentOrbState, age: number, timing?: {
29
+ wait: number;
30
+ confirm: number;
31
+ transition: number;
32
+ doneDuration: number;
33
+ blockedDuration: number;
34
+ gestureAge: (age: number) => number;
35
+ settle: (age: number, delay?: number) => number;
36
+ }, reduced?: boolean): {
12
37
  sx: number;
13
38
  sy: number;
14
39
  x: number;
15
40
  y: number;
16
41
  rotation: number;
17
- split: number;
18
- opacity: number;
19
42
  };
20
43
  export declare function paintOrbCue(context: CanvasRenderingContext2D, state: AgentOrbState, size: number, seconds: number, reduced: boolean, colors: readonly string[], depth: "back" | "front",
21
44
  /** The orb's whole ink, so the cue breathes with the body under reduced motion. */
22
- ink?: number): void;
45
+ ink?: number, timing?: {
46
+ wait: number;
47
+ confirm: number;
48
+ transition: number;
49
+ doneDuration: number;
50
+ blockedDuration: number;
51
+ gestureAge: (age: number) => number;
52
+ settle: (age: number, delay?: number) => number;
53
+ }, statusColor?: string): void;
23
54
  //# sourceMappingURL=agent-orb-motion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-orb-motion.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb-motion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAc7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,UAE/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,UAGpE;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAIlE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM;;;;;;;;EA0CjF;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,MAAM,GAAG,OAAO;AACvB,mFAAmF;AACnF,GAAG,SAAI,QAiER"}
1
+ {"version":3,"file":"agent-orb-motion.d.ts","sourceRoot":"","sources":["../../src/internal/agent-orb-motion.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAc7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,UAE/C;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,cAAc,EACpB,GAAG,SAAI,EACP,MAAM;;;;;;sBA2Cc,MAAM;kBACV,MAAM;CA5CA,UAWvB;AAKD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAIlE;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,mBAAmB;;;;;;sBAgBnC,MAAM;kBACV,MAAM;EAGvB;AAUD,wBAAgB,UAAU,CACxB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,MAAM,EACX,MAAM;;;;;;sBAjBc,MAAM;kBACV,MAAM;CAgBA,EACtB,OAAO,UAAQ;;;;;;EA+ChB;AA6ED,wBAAgB,WAAW,CACzB,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,KAAK,EAAE,MAAM,GAAG,OAAO;AACvB,mFAAmF;AACnF,GAAG,SAAI,EACP,MAAM;;;;;;sBAxJc,MAAM;kBACV,MAAM;CAuJA,EACtB,WAAW,SAA8B,QA4E1C"}