@mitcsutt/kiln-ui 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,7 +50,7 @@ export function App() {
50
50
 
51
51
  - **Your own theme** is one CSS file against the token contract, selected the same way (`theme="harbour"`).
52
52
 
53
- Each theme has light and dark modes (`data-mode`, or `mode`/`defaultMode` on `ThemeProvider`), and `data-density` makes any subtree denser or roomier. For SSR without a flash of the wrong mode, render `themeScript(theme, defaultMode)` in your document `<head>`.
53
+ Each theme has light and dark modes (`data-mode`, or `mode`/`defaultMode` on `ThemeProvider`), and `data-density` makes any subtree denser or roomier. For SSR (or a static `index.html`) without a flash of the wrong mode, render `themeScript(theme, defaultMode)` in your document `<head>`. Node-side tooling, like a Vite config that writes it into `index.html`, imports it from `@mitcsutt/kiln-ui/theme-script`, which loads without React. The mode is stored under `kiln-color-mode`; pass `storageKey` to `ThemeProvider` and `themeScript` to give each app on one origin its own key.
54
54
 
55
55
  ## Fonts
56
56
 
@@ -64,6 +64,8 @@ The package ships agent skills in `skills/`, built from the docs pages: setting
64
64
  npx @tanstack/intent@latest install
65
65
  ```
66
66
 
67
+ If your `package.json` already has an `intent.skills` list, Intent loads only the packages it names: add `@mitcsutt/kiln-ui` to it, then check with `npx @tanstack/intent@latest list`.
68
+
67
69
  ## Docs
68
70
 
69
71
  Full documentation, including the token contract and how to write a theme, lives on the [Kiln docs site](https://kiln.mitchellsutton.com). Until it's live, see [`DESIGN.md`](https://github.com/mitcsutt/kiln/blob/main/DESIGN.md) in the repository.
@@ -1 +1 @@
1
- {"version":3,"file":"List.module.js","names":["list","item","row","leading","content","description","trailing","List_module_default"],"sources":["../../../../src/components/display/List/List.module.css"],"sourcesContent":["/*\n * Component tokens (themes may set any of these on [data-theme]):\n * --list-inset default var(--space-2) — row padding-inline (room for fills)\n * --list-row-radius default var(--radius-field) — hover/selected/highlighted fill\n * --list-trailing-size default: the row's text size (same as the title)\n * --highlight-tone-{positive,caution,critical,info}-text, --highlight-accent-text\n * tone text inside a highlighted row (shared with Table)\n *\n * Structure: li.item > .row (a div, or the asChild link/button) > slots. The row carries\n * padding, hover and focus so a linked row is one target edge to edge. Slots are spans,\n * valid inside <a> and <button>.\n */\n.list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--font-text);\n color: var(--color-ink);\n}\n\n.item {\n --_py: var(--space-3);\n --_fill: transparent;\n --_fill-ink: inherit;\n\n position: relative;\n min-inline-size: 0;\n}\n.list[data-density='compact'] > .item {\n --_py: var(--space-2);\n}\n\n.list[data-divided] > .item + .item {\n border-block-start: var(--border-width) solid var(--color-line);\n}\n/* A filled row doesn't need rules either side — the fill is its edge. */\n.list[data-divided] > .item:is([data-highlighted], [data-selected]),\n.list[data-divided] > .item:is([data-highlighted], [data-selected]) + .item {\n border-block-start-color: transparent;\n}\n\n.row {\n display: flex;\n align-items: center;\n gap: var(--space-3);\n inline-size: 100%;\n min-inline-size: 0;\n margin: 0;\n padding-block: var(--_py);\n padding-inline: var(--list-inset, var(--space-2));\n border: 0;\n border-radius: var(--list-row-radius, var(--radius-field));\n background: var(--_fill);\n color: var(--_fill-ink);\n font: inherit;\n text-align: start;\n text-decoration: none;\n transition: background-color var(--dur-1) var(--ease-out);\n}\n\n.item[data-selected] {\n --_fill: var(--color-accent-soft);\n --_fill-ink: var(--color-ink);\n}\n.item[data-highlighted] {\n --_fill: var(--color-highlight);\n --_fill-ink: var(--color-highlight-ink);\n --_band-positive: var(\n --highlight-tone-positive-text,\n color-mix(in oklab, var(--tone-positive-text) 75%, var(--color-highlight-ink))\n );\n --_band-caution: var(\n --highlight-tone-caution-text,\n color-mix(in oklab, var(--tone-caution-text) 75%, var(--color-highlight-ink))\n );\n --_band-critical: var(\n --highlight-tone-critical-text,\n color-mix(in oklab, var(--tone-critical-text) 75%, var(--color-highlight-ink))\n );\n --_band-info: var(\n --highlight-tone-info-text,\n color-mix(in oklab, var(--tone-info-text) 75%, var(--color-highlight-ink))\n );\n --_band-accent: var(\n --highlight-accent-text,\n color-mix(in oklab, var(--color-accent-text) 75%, var(--color-highlight-ink))\n );\n}\n\n/*\n * A filled row re-points the colour roles for its content, so a muted description, a\n * tone-coloured Numeral or a LiveIndicator stays legible on the fill (gold in Fiesta\n * night). The item publishes fill/ink under private names and the row swaps the roles —\n * redefining a role from itself on one element would be a var() cycle (see Section).\n */\n.item:is([data-highlighted], [data-selected]) > .row {\n --color-ink: var(--_fill-ink);\n --color-ink-muted: color-mix(in oklab, var(--_fill-ink), var(--_fill) 25%);\n --color-ink-subtle: color-mix(in oklab, var(--_fill-ink), var(--_fill) 35%);\n}\n.item[data-highlighted] > .row {\n --tone-positive-text: var(--_band-positive);\n --tone-caution-text: var(--_band-caution);\n --tone-critical-text: var(--_band-critical);\n --tone-info-text: var(--_band-info);\n --color-accent-text: var(--_band-accent);\n}\n\n.item[data-interactive] > .row {\n cursor: pointer;\n}\n@media (hover: hover) {\n .item[data-interactive]:not([data-highlighted], [data-selected]) > .row:hover {\n background: var(--color-surface-sunken);\n }\n .item[data-interactive]:is([data-highlighted], [data-selected]) > .row:hover {\n background: color-mix(in oklch, var(--_fill) 88%, var(--color-ink));\n }\n}\n.row:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: -2px;\n}\n\n/* ── Slots ───────────────────────────────────────────────────────────────── */\n\n.leading {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n min-inline-size: 2ch;\n color: var(--color-ink-muted);\n font-family: var(--font-numeric);\n font-stretch: var(--numeric-stretch);\n font-weight: var(--label-weight);\n font-variant-numeric: tabular-nums lining-nums;\n font-size: var(--text-md);\n}\n.item[data-highlighted] .leading {\n color: inherit;\n}\n\n.content {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: calc(var(--space-1) / 2);\n min-inline-size: 0;\n font-size: var(--text-md);\n font-weight: var(--label-weight);\n line-height: var(--leading-snug);\n overflow-wrap: anywhere;\n}\n\n.description {\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n font-weight: 400;\n}\n\n.trailing {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-inline-start: auto;\n text-align: end;\n /*\n * The row's text face and size, with tabular figures: a bare \"7 tasks\" sits level with the\n * title instead of looming in the numeric face. Put a <Numeral>/<Amount> here for figures\n * that should carry the numeric face (receipt mono in Ledger).\n */\n font-variant-numeric: tabular-nums lining-nums;\n font-size: var(--list-trailing-size, var(--text-md));\n font-weight: var(--label-weight);\n line-height: var(--leading-snug);\n white-space: nowrap;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"List.module.js","names":["list","item","row","leading","content","description","trailing","List_module_default"],"sources":["../../../../src/components/display/List/List.module.css"],"sourcesContent":["/*\n * Component tokens (themes may set any of these on [data-theme]):\n * --list-inset default var(--space-2) — row padding-inline (room for fills)\n * --list-row-radius default var(--radius-field) — hover/selected/highlighted fill\n * --list-trailing-size default: the row's text size (same as the title)\n * --highlight-tone-{positive,caution,critical,info}-text, --highlight-accent-text\n * tone text inside a highlighted row (shared with Table)\n *\n * Structure: li.item > .row (a div, or the asChild link/button) > slots. The row carries\n * padding, hover and focus so a linked row is one target edge to edge. Slots are spans,\n * valid inside <a> and <button>.\n */\n.list {\n display: flex;\n flex-direction: column;\n margin: 0;\n padding: 0;\n list-style: none;\n font-family: var(--font-text);\n color: var(--color-ink);\n}\n\n.item {\n --_py: var(--space-3);\n --_fill: transparent;\n --_fill-ink: inherit;\n\n position: relative;\n min-inline-size: 0;\n}\n.list[data-density='compact'] > .item {\n --_py: var(--space-2);\n}\n\n.list[data-divided] > .item + .item {\n border-block-start: var(--border-width) solid var(--color-line);\n}\n/* A filled row doesn't need rules either side — the fill is its edge. */\n.list[data-divided] > .item:is([data-highlighted], [data-selected]),\n.list[data-divided] > .item:is([data-highlighted], [data-selected]) + .item {\n border-block-start-color: transparent;\n}\n\n.row {\n display: flex;\n align-items: center;\n gap: var(--space-3);\n inline-size: 100%;\n min-inline-size: 0;\n margin: 0;\n padding-block: var(--_py);\n padding-inline: var(--list-inset, var(--space-2));\n border: 0;\n border-radius: var(--list-row-radius, var(--radius-field));\n background: var(--_fill);\n color: var(--_fill-ink);\n font: inherit;\n text-align: start;\n text-decoration: none;\n transition: background-color var(--dur-1) var(--ease-out);\n}\n\n.item[data-selected] {\n --_fill: var(--color-accent-soft);\n --_fill-ink: var(--color-ink);\n}\n.item[data-highlighted] {\n --_fill: var(--color-highlight);\n --_fill-ink: var(--color-highlight-ink);\n --_band-positive: var(\n --highlight-tone-positive-text,\n color-mix(in oklab, var(--tone-positive-text) 75%, var(--color-highlight-ink))\n );\n --_band-caution: var(\n --highlight-tone-caution-text,\n color-mix(in oklab, var(--tone-caution-text) 75%, var(--color-highlight-ink))\n );\n --_band-critical: var(\n --highlight-tone-critical-text,\n color-mix(in oklab, var(--tone-critical-text) 75%, var(--color-highlight-ink))\n );\n --_band-info: var(\n --highlight-tone-info-text,\n color-mix(in oklab, var(--tone-info-text) 75%, var(--color-highlight-ink))\n );\n --_band-accent: var(\n --highlight-accent-text,\n color-mix(in oklab, var(--color-accent-text) 75%, var(--color-highlight-ink))\n );\n}\n\n/*\n * A filled row re-points the colour roles for its content, so a muted description, a\n * tone-coloured Numeral or a LiveIndicator stays legible on the fill (gold in Fiesta\n * night). The item publishes fill/ink under private names and the row swaps the roles —\n * redefining a role from itself on one element would be a var() cycle (see Section).\n */\n.item:is([data-highlighted], [data-selected]) > .row {\n --color-ink: var(--_fill-ink);\n --color-ink-muted: color-mix(in oklab, var(--_fill-ink), var(--_fill) 25%);\n --color-ink-subtle: color-mix(in oklab, var(--_fill-ink), var(--_fill) 35%);\n}\n.item[data-highlighted] > .row {\n --tone-positive-text: var(--_band-positive);\n --tone-caution-text: var(--_band-caution);\n --tone-critical-text: var(--_band-critical);\n --tone-info-text: var(--_band-info);\n --color-accent-text: var(--_band-accent);\n /* Soft fills (a soft Badge or Tag) tint the band, like Section's accent band, so the\n re-pointed tone texts above stay legible on them in every mode. */\n --tone-positive-soft: color-mix(in oklab, var(--_band-positive) 8%, var(--_fill));\n --tone-caution-soft: color-mix(in oklab, var(--_band-caution) 8%, var(--_fill));\n --tone-critical-soft: color-mix(in oklab, var(--_band-critical) 8%, var(--_fill));\n --tone-info-soft: color-mix(in oklab, var(--_band-info) 8%, var(--_fill));\n --color-accent-soft: color-mix(in oklab, var(--_band-accent) 8%, var(--_fill));\n}\n\n.item[data-interactive] > .row {\n cursor: pointer;\n}\n@media (hover: hover) {\n .item[data-interactive]:not([data-highlighted], [data-selected]) > .row:hover {\n background: var(--color-surface-sunken);\n }\n .item[data-interactive]:is([data-highlighted], [data-selected]) > .row:hover {\n background: color-mix(in oklch, var(--_fill) 88%, var(--color-ink));\n }\n}\n.row:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: -2px;\n}\n\n/* ── Slots ───────────────────────────────────────────────────────────────── */\n\n.leading {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n min-inline-size: 2ch;\n color: var(--color-ink-muted);\n font-family: var(--font-numeric);\n font-stretch: var(--numeric-stretch);\n font-weight: var(--label-weight);\n font-variant-numeric: tabular-nums lining-nums;\n font-size: var(--text-md);\n}\n.item[data-highlighted] .leading {\n color: inherit;\n}\n\n.content {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: calc(var(--space-1) / 2);\n min-inline-size: 0;\n font-size: var(--text-md);\n font-weight: var(--label-weight);\n line-height: var(--leading-snug);\n overflow-wrap: anywhere;\n}\n\n.description {\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n font-weight: 400;\n}\n\n.trailing {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-inline-start: auto;\n text-align: end;\n /*\n * The row's text face and size, with tabular figures: a bare \"7 tasks\" sits level with the\n * title instead of looming in the numeric face. Put a <Numeral>/<Amount> here for figures\n * that should carry the numeric face (receipt mono in Ledger).\n */\n font-variant-numeric: tabular-nums lining-nums;\n font-size: var(--list-trailing-size, var(--text-md));\n font-weight: var(--label-weight);\n line-height: var(--leading-snug);\n white-space: nowrap;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"Table.module.js","names":["scroll","table","caption","headerCell","cell","body","row","foot","head","sortButton","sortGlyph","Table_module_default"],"sources":["../../../../src/components/display/Table/Table.module.css"],"sourcesContent":["/*\n * Component tokens (themes may set any of these on [data-theme]):\n * --table-head-font default var(--font-text) — Fiesta sets its display caps\n * --table-head-numeric-font numeric header cells, default var(--table-head-font, var(--font-text))\n * --table-head-size default var(--text-sm)\n * --table-head-weight default var(--label-weight)\n * --table-head-transform default var(--heading-transform)\n * --table-head-bg default var(--color-canvas) — only painted when stickyHeader\n * --table-max-height default 70vh — scroll height when stickyHeader\n * --table-foot-rule the rule over totals, default var(--border-width-strong) solid\n * var(--color-line-strong) — Ledger draws the accountant's double rule\n * --highlight-tone-{positive,caution,critical,info}-text, --highlight-accent-text\n * tone text inside a highlighted row (shared with List). Default:\n * the tone text mixed 25% toward --color-highlight-ink.\n *\n * Headers are labels, so they're set in the text face (monospace as decoration for small\n * labels is banned in DESIGN §2); figures below them carry the numeric face.\n */\n.scroll {\n inline-size: 100%;\n min-inline-size: 0;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n.scroll[data-sticky-header] {\n overflow: auto;\n max-block-size: var(--table-max-height, 70vh);\n}\n.scroll:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 2px;\n}\n\n.table {\n --_py: var(--space-2);\n --_px: var(--space-3);\n\n inline-size: 100%;\n border-collapse: separate;\n border-spacing: 0;\n font-family: var(--font-text);\n font-size: var(--text-sm);\n line-height: var(--leading-snug);\n color: var(--color-ink);\n}\n.table[data-density='compact'] {\n --_py: var(--space-1);\n --_px: var(--space-2);\n}\n\n.caption {\n caption-side: top;\n padding-block-end: var(--space-3);\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n text-align: start;\n}\n\n/* ── Cells ─────────────────────────────────────────────────────────────── */\n\n.headerCell,\n.cell {\n padding: var(--_py) var(--_px);\n text-align: start;\n vertical-align: baseline;\n}\n.headerCell:first-child,\n.cell:first-child {\n padding-inline-start: var(--space-2);\n}\n.headerCell:last-child,\n.cell:last-child {\n padding-inline-end: var(--space-2);\n}\n/* Figure columns are narrow; tighter gutters keep a 10-column figures table on a phone. */\n:is(.headerCell, .cell)[data-numeric] {\n padding-inline: var(--space-2);\n}\n.headerCell abbr {\n text-decoration: none;\n cursor: help;\n}\n:is(.headerCell, .cell)[data-align='center'] {\n text-align: center;\n}\n:is(.headerCell, .cell)[data-align='end'] {\n text-align: end;\n}\n\n.headerCell {\n padding-block: var(--_py);\n color: var(--color-ink-muted);\n font-family: var(--table-head-font, var(--font-text));\n font-size: var(--table-head-size, var(--text-sm));\n font-weight: var(--table-head-weight, var(--label-weight));\n letter-spacing: var(--label-tracking);\n text-transform: var(--table-head-transform, var(--heading-transform));\n white-space: nowrap;\n vertical-align: bottom;\n border-block-end: var(--border-width-strong) solid var(--color-line-strong);\n}\n\n.headerCell[data-numeric] {\n font-family: var(--table-head-numeric-font, var(--table-head-font, var(--font-text)));\n font-variant-numeric: tabular-nums lining-nums;\n}\n.headerCell[data-width='fill'] {\n inline-size: 100%;\n}\n.headerCell[data-width='min'] {\n inline-size: 1%;\n}\n\n.cell[data-numeric] {\n font-family: var(--font-numeric);\n font-stretch: var(--numeric-stretch);\n font-variant-numeric: tabular-nums lining-nums;\n white-space: nowrap;\n}\n.cell[data-row-header] {\n font-weight: var(--label-weight);\n}\n\n/* ── Rows ──────────────────────────────────────────────────────────────── */\n\n.table[data-variant='rules'] .body .cell {\n border-block-end: var(--border-width) solid var(--color-line);\n}\n.table[data-variant='rules'] .body > .row:last-child > .cell {\n border-block-end-color: var(--color-line-strong);\n}\n\n.table[data-striped] .body > .row:nth-child(even) > .cell {\n background: var(--color-surface-sunken);\n}\n\n/*\n * A highlighted row re-points the colour roles for its cells' content, so a muted date,\n * a tone-coloured Numeral or a LiveIndicator stays legible on the highlight fill (gold in\n * Fiesta night, where the ordinary tone texts are pale). Same approach as Section's\n * inverse band: the row publishes its fill/ink and tone texts under private names, and\n * the cells swap the roles — setting e.g. --tone-positive-text from itself on one element\n * would be a var() cycle.\n */\n.row[data-highlighted] {\n --_band-fill: var(--color-highlight);\n --_band-ink: var(--color-highlight-ink);\n --_band-positive: var(\n --highlight-tone-positive-text,\n color-mix(in oklab, var(--tone-positive-text) 75%, var(--color-highlight-ink))\n );\n --_band-caution: var(\n --highlight-tone-caution-text,\n color-mix(in oklab, var(--tone-caution-text) 75%, var(--color-highlight-ink))\n );\n --_band-critical: var(\n --highlight-tone-critical-text,\n color-mix(in oklab, var(--tone-critical-text) 75%, var(--color-highlight-ink))\n );\n --_band-info: var(\n --highlight-tone-info-text,\n color-mix(in oklab, var(--tone-info-text) 75%, var(--color-highlight-ink))\n );\n --_band-accent: var(\n --highlight-accent-text,\n color-mix(in oklab, var(--color-accent-text) 75%, var(--color-highlight-ink))\n );\n}\n.row[data-highlighted] > .cell {\n --color-ink: var(--_band-ink);\n --color-ink-muted: color-mix(in oklab, var(--_band-ink), var(--_band-fill) 25%);\n --color-ink-subtle: color-mix(in oklab, var(--_band-ink), var(--_band-fill) 35%);\n --tone-positive-text: var(--_band-positive);\n --tone-caution-text: var(--_band-caution);\n --tone-critical-text: var(--_band-critical);\n --tone-info-text: var(--_band-info);\n --color-accent-text: var(--_band-accent);\n\n background: var(--_band-fill);\n color: var(--_band-ink);\n}\n/* Round the ends of a highlighted row so the fill reads as a marker, not a stripe. */\n.row[data-highlighted] > .cell:first-child {\n border-start-start-radius: var(--radius-field);\n border-end-start-radius: var(--radius-field);\n}\n.row[data-highlighted] > .cell:last-child {\n border-start-end-radius: var(--radius-field);\n border-end-end-radius: var(--radius-field);\n}\n\n.row[data-interactive] {\n cursor: pointer;\n}\n.row > .cell {\n transition: background-color var(--dur-1) var(--ease-out);\n}\n@media (hover: hover) {\n .row[data-interactive]:not([data-highlighted]):hover > .cell {\n background: var(--color-surface-sunken);\n }\n}\n\n.foot > :first-child > .cell {\n border-block-start: var(\n --table-foot-rule,\n var(--border-width-strong) solid var(--color-line-strong)\n );\n}\n.foot .cell {\n font-weight: var(--label-weight);\n}\n/* The totals rule replaces the last row's hairline rather than stacking under it. */\n.table[data-variant='rules'] .body:has(+ .foot) > .row:last-child > .cell {\n border-block-end-width: 0;\n}\n\n/* ── Sticky header ─────────────────────────────────────────────────────── */\n\n.table[data-sticky-header] .head .headerCell {\n position: sticky;\n inset-block-start: 0;\n z-index: 1;\n background: var(--table-head-bg, var(--color-canvas));\n}\n\n/* ── Sort button ───────────────────────────────────────────────────────── */\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25em;\n margin: calc(var(--space-1) * -1);\n padding: var(--space-1);\n border: 0;\n border-radius: var(--radius-field);\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n transition: color var(--dur-1) var(--ease-out);\n}\n.headerCell[data-align='end'] .sortButton {\n flex-direction: row-reverse;\n}\n@media (hover: hover) {\n .sortButton:hover {\n color: var(--color-ink);\n }\n}\n.sortButton:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 0;\n}\n.sortGlyph {\n display: inline-flex;\n font-size: 1.1em;\n opacity: 0;\n transition: opacity var(--dur-1) var(--ease-out);\n}\n.headerCell:is([data-sort='asc'], [data-sort='desc']) {\n color: var(--color-ink);\n}\n.headerCell:is([data-sort='asc'], [data-sort='desc']) .sortGlyph,\n.sortButton:hover .sortGlyph,\n.sortButton:focus-visible .sortGlyph {\n opacity: 1;\n}\n.headerCell[data-sort='none'] .sortButton:is(:hover, :focus-visible) .sortGlyph {\n opacity: 0.45;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Table.module.js","names":["scroll","table","caption","headerCell","cell","body","row","foot","head","sortButton","sortGlyph","Table_module_default"],"sources":["../../../../src/components/display/Table/Table.module.css"],"sourcesContent":["/*\n * Component tokens (themes may set any of these on [data-theme]):\n * --table-head-font default var(--font-text) — Fiesta sets its display caps\n * --table-head-numeric-font numeric header cells, default var(--table-head-font, var(--font-text))\n * --table-head-size default var(--text-sm)\n * --table-head-weight default var(--label-weight)\n * --table-head-transform default var(--heading-transform)\n * --table-head-bg default var(--color-canvas) — only painted when stickyHeader\n * --table-max-height default 70vh — scroll height when stickyHeader\n * --table-foot-rule the rule over totals, default var(--border-width-strong) solid\n * var(--color-line-strong) — Ledger draws the accountant's double rule\n * --highlight-tone-{positive,caution,critical,info}-text, --highlight-accent-text\n * tone text inside a highlighted row (shared with List). Default:\n * the tone text mixed 25% toward --color-highlight-ink.\n *\n * Headers are labels, so they're set in the text face (monospace as decoration for small\n * labels is banned in DESIGN §2); figures below them carry the numeric face.\n */\n.scroll {\n inline-size: 100%;\n min-inline-size: 0;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n}\n.scroll[data-sticky-header] {\n overflow: auto;\n max-block-size: var(--table-max-height, 70vh);\n}\n.scroll:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 2px;\n}\n\n.table {\n --_py: var(--space-2);\n --_px: var(--space-3);\n\n inline-size: 100%;\n border-collapse: separate;\n border-spacing: 0;\n font-family: var(--font-text);\n font-size: var(--text-sm);\n line-height: var(--leading-snug);\n color: var(--color-ink);\n}\n.table[data-density='compact'] {\n --_py: var(--space-1);\n --_px: var(--space-2);\n}\n\n.caption {\n caption-side: top;\n padding-block-end: var(--space-3);\n color: var(--color-ink-muted);\n font-size: var(--text-sm);\n text-align: start;\n}\n\n/* ── Cells ─────────────────────────────────────────────────────────────── */\n\n.headerCell,\n.cell {\n padding: var(--_py) var(--_px);\n text-align: start;\n vertical-align: baseline;\n}\n.headerCell:first-child,\n.cell:first-child {\n padding-inline-start: var(--space-2);\n}\n.headerCell:last-child,\n.cell:last-child {\n padding-inline-end: var(--space-2);\n}\n/* Figure columns are narrow; tighter gutters keep a 10-column figures table on a phone. */\n:is(.headerCell, .cell)[data-numeric] {\n padding-inline: var(--space-2);\n}\n.headerCell abbr {\n text-decoration: none;\n cursor: help;\n}\n:is(.headerCell, .cell)[data-align='center'] {\n text-align: center;\n}\n:is(.headerCell, .cell)[data-align='end'] {\n text-align: end;\n}\n\n.headerCell {\n padding-block: var(--_py);\n color: var(--color-ink-muted);\n font-family: var(--table-head-font, var(--font-text));\n font-size: var(--table-head-size, var(--text-sm));\n font-weight: var(--table-head-weight, var(--label-weight));\n letter-spacing: var(--label-tracking);\n text-transform: var(--table-head-transform, var(--heading-transform));\n white-space: nowrap;\n vertical-align: bottom;\n border-block-end: var(--border-width-strong) solid var(--color-line-strong);\n}\n\n.headerCell[data-numeric] {\n font-family: var(--table-head-numeric-font, var(--table-head-font, var(--font-text)));\n font-variant-numeric: tabular-nums lining-nums;\n}\n.headerCell[data-width='fill'] {\n inline-size: 100%;\n}\n.headerCell[data-width='min'] {\n inline-size: 1%;\n}\n\n.cell[data-numeric] {\n font-family: var(--font-numeric);\n font-stretch: var(--numeric-stretch);\n font-variant-numeric: tabular-nums lining-nums;\n white-space: nowrap;\n}\n.cell[data-row-header] {\n font-weight: var(--label-weight);\n}\n\n/* ── Rows ──────────────────────────────────────────────────────────────── */\n\n.table[data-variant='rules'] .body .cell {\n border-block-end: var(--border-width) solid var(--color-line);\n}\n.table[data-variant='rules'] .body > .row:last-child > .cell {\n border-block-end-color: var(--color-line-strong);\n}\n\n.table[data-striped] .body > .row:nth-child(even) > .cell {\n background: var(--color-surface-sunken);\n}\n\n/*\n * A highlighted row re-points the colour roles for its cells' content, so a muted date,\n * a tone-coloured Numeral or a LiveIndicator stays legible on the highlight fill (gold in\n * Fiesta night, where the ordinary tone texts are pale). Same approach as Section's\n * inverse band: the row publishes its fill/ink and tone texts under private names, and\n * the cells swap the roles — setting e.g. --tone-positive-text from itself on one element\n * would be a var() cycle.\n */\n.row[data-highlighted] {\n --_band-fill: var(--color-highlight);\n --_band-ink: var(--color-highlight-ink);\n --_band-positive: var(\n --highlight-tone-positive-text,\n color-mix(in oklab, var(--tone-positive-text) 75%, var(--color-highlight-ink))\n );\n --_band-caution: var(\n --highlight-tone-caution-text,\n color-mix(in oklab, var(--tone-caution-text) 75%, var(--color-highlight-ink))\n );\n --_band-critical: var(\n --highlight-tone-critical-text,\n color-mix(in oklab, var(--tone-critical-text) 75%, var(--color-highlight-ink))\n );\n --_band-info: var(\n --highlight-tone-info-text,\n color-mix(in oklab, var(--tone-info-text) 75%, var(--color-highlight-ink))\n );\n --_band-accent: var(\n --highlight-accent-text,\n color-mix(in oklab, var(--color-accent-text) 75%, var(--color-highlight-ink))\n );\n}\n.row[data-highlighted] > .cell {\n --color-ink: var(--_band-ink);\n --color-ink-muted: color-mix(in oklab, var(--_band-ink), var(--_band-fill) 25%);\n --color-ink-subtle: color-mix(in oklab, var(--_band-ink), var(--_band-fill) 35%);\n --tone-positive-text: var(--_band-positive);\n --tone-caution-text: var(--_band-caution);\n --tone-critical-text: var(--_band-critical);\n --tone-info-text: var(--_band-info);\n --color-accent-text: var(--_band-accent);\n /* Soft fills (a soft Badge or Tag) tint the band, like Section's accent band, so the\n re-pointed tone texts above stay legible on them in every mode. */\n --tone-positive-soft: color-mix(in oklab, var(--_band-positive) 8%, var(--_band-fill));\n --tone-caution-soft: color-mix(in oklab, var(--_band-caution) 8%, var(--_band-fill));\n --tone-critical-soft: color-mix(in oklab, var(--_band-critical) 8%, var(--_band-fill));\n --tone-info-soft: color-mix(in oklab, var(--_band-info) 8%, var(--_band-fill));\n --color-accent-soft: color-mix(in oklab, var(--_band-accent) 8%, var(--_band-fill));\n\n background: var(--_band-fill);\n color: var(--_band-ink);\n}\n/* Round the ends of a highlighted row so the fill reads as a marker, not a stripe. */\n.row[data-highlighted] > .cell:first-child {\n border-start-start-radius: var(--radius-field);\n border-end-start-radius: var(--radius-field);\n}\n.row[data-highlighted] > .cell:last-child {\n border-start-end-radius: var(--radius-field);\n border-end-end-radius: var(--radius-field);\n}\n\n.row[data-interactive] {\n cursor: pointer;\n}\n.row > .cell {\n transition: background-color var(--dur-1) var(--ease-out);\n}\n@media (hover: hover) {\n .row[data-interactive]:not([data-highlighted]):hover > .cell {\n background: var(--color-surface-sunken);\n }\n}\n\n.foot > :first-child > .cell {\n border-block-start: var(\n --table-foot-rule,\n var(--border-width-strong) solid var(--color-line-strong)\n );\n}\n.foot .cell {\n font-weight: var(--label-weight);\n}\n/* The totals rule replaces the last row's hairline rather than stacking under it. */\n.table[data-variant='rules'] .body:has(+ .foot) > .row:last-child > .cell {\n border-block-end-width: 0;\n}\n\n/* ── Sticky header ─────────────────────────────────────────────────────── */\n\n.table[data-sticky-header] .head .headerCell {\n position: sticky;\n inset-block-start: 0;\n z-index: 1;\n background: var(--table-head-bg, var(--color-canvas));\n}\n\n/* ── Sort button ───────────────────────────────────────────────────────── */\n\n.sortButton {\n display: inline-flex;\n align-items: center;\n gap: 0.25em;\n margin: calc(var(--space-1) * -1);\n padding: var(--space-1);\n border: 0;\n border-radius: var(--radius-field);\n background: transparent;\n color: inherit;\n font: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n cursor: pointer;\n transition: color var(--dur-1) var(--ease-out);\n}\n.headerCell[data-align='end'] .sortButton {\n flex-direction: row-reverse;\n}\n@media (hover: hover) {\n .sortButton:hover {\n color: var(--color-ink);\n }\n}\n.sortButton:focus-visible {\n outline: 2px solid var(--color-focus);\n outline-offset: 0;\n}\n.sortGlyph {\n display: inline-flex;\n font-size: 1.1em;\n opacity: 0;\n transition: opacity var(--dur-1) var(--ease-out);\n}\n.headerCell:is([data-sort='asc'], [data-sort='desc']) {\n color: var(--color-ink);\n}\n.headerCell:is([data-sort='asc'], [data-sort='desc']) .sortGlyph,\n.sortButton:hover .sortGlyph,\n.sortButton:focus-visible .sortGlyph {\n opacity: 1;\n}\n.headerCell[data-sort='none'] .sortButton:is(:hover, :focus-visible) .sortGlyph {\n opacity: 0.45;\n}\n"],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference path="./stylesheets.d.ts" preserve="true" />
2
2
  export { ThemeProvider, ThemeScope, useTheme, themeScript, THEMES, THEME_META, MODES, DEFAULT_THEME, } from './theme/index.js';
3
- export type { ThemeProviderProps, ThemeScopeProps, ThemeContextValue, ThemeName, BuiltInThemeName, ThemeMeta, ColorMode, } from './theme/index.js';
3
+ export type { ThemeProviderProps, ThemeScopeProps, ThemeContextValue, ThemeScriptOptions, ThemeName, BuiltInThemeName, ThemeMeta, ColorMode, } from './theme/index.js';
4
4
  export { cx } from './utils/cx.js';
5
5
  export type { Responsive, Breakpoint } from './utils/responsive.js';
6
6
  export type { Space, Tone, Size, Width, Align, Justify } from './utils/tokens.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_THEME as e, MODES as t, THEMES as n, THEME_META as r } from "./theme/themes.js";
2
- import { themeScript as i, useTheme as a } from "./theme/context.js";
2
+ import { useTheme as i } from "./theme/context.js";
3
+ import { themeScript as a } from "./theme/script.js";
3
4
  import { ThemeProvider as o, ThemeScope as s } from "./theme/ThemeProvider.js";
4
5
  import { cx as c } from "./utils/cx.js";
5
6
  import { createIcon as l } from "./icons/Icon.js";
@@ -114,4 +115,4 @@ import { Sheet as zt } from "./components/overlays/Sheet/Sheet.js";
114
115
  import { Popover as Bt } from "./components/overlays/Popover/Popover.js";
115
116
  import { DropdownMenu as Vt } from "./components/overlays/DropdownMenu/DropdownMenu.js";
116
117
  import { Tooltip as Ht, TooltipProvider as Ut } from "./components/overlays/Tooltip/Tooltip.js";
117
- export { At as Accordion, q as ActionBar, Mt as Alert, oe as Amount, Ne as AmountField, Me as AmountInput, K as AppShell, u as ArrowLeftIcon, d as ArrowRightIcon, f as ArrowUpRightIcon, W as AspectRatio, dt as Avatar, ft as AvatarGroup, ct as Badge, kt as BottomNav, R as Box, le as Button, st as Card, p as CheckIcon, be as Checkbox, De as CheckboxField, Be as CheckboxGroup, Ve as CheckboxGroupField, m as ChevronDownIcon, h as ChevronLeftIcon, g as ChevronRightIcon, _ as ChevronUpIcon, pe as ChipGroup, We as ChipGroupField, Ge as ChoiceCards, Ke as ChoiceCardsField, v as CircleCheckIcon, y as CloseIcon, Q as Code, bt as CodeBlock, Le as ColorField, Ie as ColorInput, tt as Combobox, nt as ComboboxField, V as Container, b as CopyIcon, J as DEFAULT_HEADING_SIZE, e as DEFAULT_THEME, ht as DataList, ze as DateRangeField, pt as Delta, Rt as Dialog, U as Divider, Vt as DropdownMenu, Et as EmptyState, x as ErrorIcon, S as EyeIcon, C as EyeOffIcon, ge as Field, Ce as Fieldset, at as FileDrop, ot as FileField, z as Grid, Y as Heading, ue as IconButton, w as InfoIcon, L as Inline, _e as Input, $ as Kbd, Z as Link, gt as List, Nt as LiveIndicator, t as MODES, yt as Marquee, vt as Media, T as MenuIcon, wt as Meter, E as MinusIcon, he as ModeToggle, D as MoonIcon, O as MoreIcon, Ot as NavLinks, je as NumberField, Ae as NumberInput, ae as Numeral, Fe as OneTimeCodeField, Pe as OneTimeCodeInput, ke as PasswordField, Oe as PasswordInput, k as PlusIcon, Bt as Popover, St as Progress, ee as Prose, te as Quote, xe as RadioGroup, He as RadioGroupField, Ye as RangeSlider, Xe as RangeSliderField, Ze as Rating, Qe as RatingField, Lt as RelativeTime, A as SearchIcon, H as Section, se as SectionHeader, me as SegmentedControl, Ue as SegmentedField, ye as Select, Ee as SelectField, zt as Sheet, Tt as Skeleton, qe as Slider, Je as SliderField, ce as Spinner, B as Split, I as Stack, xt as Stamp, j as StarIcon, mt as Stat, Pt as StatusDot, jt as Stepper, M as SunIcon, Se as Switch, Re as SwitchField, N as SystemIcon, n as THEMES, r as THEME_META, _t as Table, Dt as Tabs, $e as Tag, et as TagList, it as TagsField, rt as TagsInput, X as Text, we as TextField, ve as Textarea, Te as TextareaField, o as ThemeProvider, s as ThemeScope, de as ToggleChip, Ht as Tooltip, Ut as TooltipProvider, P as UploadIcon, G as VisuallyHidden, F as WarningIcon, lt as avatarColor, l as createIcon, c as cx, Ft as formatAbsoluteTime, ne as formatNumeral, re as formatNumeralParts, It as formatRelativeTime, ut as getInitials, Ct as meterTone, ie as signOf, i as themeScript, fe as useFieldControl, a as useTheme };
118
+ export { At as Accordion, q as ActionBar, Mt as Alert, oe as Amount, Ne as AmountField, Me as AmountInput, K as AppShell, u as ArrowLeftIcon, d as ArrowRightIcon, f as ArrowUpRightIcon, W as AspectRatio, dt as Avatar, ft as AvatarGroup, ct as Badge, kt as BottomNav, R as Box, le as Button, st as Card, p as CheckIcon, be as Checkbox, De as CheckboxField, Be as CheckboxGroup, Ve as CheckboxGroupField, m as ChevronDownIcon, h as ChevronLeftIcon, g as ChevronRightIcon, _ as ChevronUpIcon, pe as ChipGroup, We as ChipGroupField, Ge as ChoiceCards, Ke as ChoiceCardsField, v as CircleCheckIcon, y as CloseIcon, Q as Code, bt as CodeBlock, Le as ColorField, Ie as ColorInput, tt as Combobox, nt as ComboboxField, V as Container, b as CopyIcon, J as DEFAULT_HEADING_SIZE, e as DEFAULT_THEME, ht as DataList, ze as DateRangeField, pt as Delta, Rt as Dialog, U as Divider, Vt as DropdownMenu, Et as EmptyState, x as ErrorIcon, S as EyeIcon, C as EyeOffIcon, ge as Field, Ce as Fieldset, at as FileDrop, ot as FileField, z as Grid, Y as Heading, ue as IconButton, w as InfoIcon, L as Inline, _e as Input, $ as Kbd, Z as Link, gt as List, Nt as LiveIndicator, t as MODES, yt as Marquee, vt as Media, T as MenuIcon, wt as Meter, E as MinusIcon, he as ModeToggle, D as MoonIcon, O as MoreIcon, Ot as NavLinks, je as NumberField, Ae as NumberInput, ae as Numeral, Fe as OneTimeCodeField, Pe as OneTimeCodeInput, ke as PasswordField, Oe as PasswordInput, k as PlusIcon, Bt as Popover, St as Progress, ee as Prose, te as Quote, xe as RadioGroup, He as RadioGroupField, Ye as RangeSlider, Xe as RangeSliderField, Ze as Rating, Qe as RatingField, Lt as RelativeTime, A as SearchIcon, H as Section, se as SectionHeader, me as SegmentedControl, Ue as SegmentedField, ye as Select, Ee as SelectField, zt as Sheet, Tt as Skeleton, qe as Slider, Je as SliderField, ce as Spinner, B as Split, I as Stack, xt as Stamp, j as StarIcon, mt as Stat, Pt as StatusDot, jt as Stepper, M as SunIcon, Se as Switch, Re as SwitchField, N as SystemIcon, n as THEMES, r as THEME_META, _t as Table, Dt as Tabs, $e as Tag, et as TagList, it as TagsField, rt as TagsInput, X as Text, we as TextField, ve as Textarea, Te as TextareaField, o as ThemeProvider, s as ThemeScope, de as ToggleChip, Ht as Tooltip, Ut as TooltipProvider, P as UploadIcon, G as VisuallyHidden, F as WarningIcon, lt as avatarColor, l as createIcon, c as cx, Ft as formatAbsoluteTime, ne as formatNumeral, re as formatNumeralParts, It as formatRelativeTime, ut as getInitials, Ct as meterTone, ie as signOf, a as themeScript, fe as useFieldControl, i as useTheme };