You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/table/table.css

348 lines
9.8 KiB

Build TextArea component + fix locale propagation bug across soma providers Major work in this session: 1. NumberField demo refactored to expose Intl.NumberFormatOptions live - 9 canonical presets (currency/unit/percent/compact/plain) - Locale/currency/unit lists derived from $libs/langs, $libs/currency, $format/units (no more hardcoded arrays) - Default locale from uix.format.numbers.getLocale() 2. Bug fix: locale prop ignored when soma.format service is active - soma/NumberField: 5 bypass points via new `hasOwnLocale` getter (decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue) - soma/Calendar: dateOrder respects locale prop (matches DateField precedence) - soma/RangeCalendar: same dateOrder fix - When the consumer passes `locale` prop, soma.nums/dates is bypassed and Intl is used directly with the prop locale 3. TextArea — new component, full 4-layer stack - morfo: 3 parts (provider/input/count), 3 events (commit-input/commit-submit/shift-count-overflow), APG textbox - soma: TextAreaProvider with autosize (scrollHeight measurement), submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp, Field integration (OR-merge), counter overflow tracking - eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize - sema: commit-submit + shift-count-overflow perceptual cues - demo: canonical 6-tab depth, all props exposed as live controls - PrimitiveTextareaAttributes added to soma/types/html.ts 4. Also includes accumulated unreleased work from prior sessions: - Eidos ports: announce, clipboard, drag-drop, feed, table, tree-grid, tree-view, virtual-grid, virtual-list, words - Their canonical demos under web/routes/uix/components/ - Semantic events defined for utility morfos (announce/clipboard/virtual-list/virtual-grid) - Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients) - Sidebar reorganized with Data + Utilities groups - Eidos words content layer and primitives Reference library survey performed before TextArea API design (Mantine, Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime). Decision documented: no separate CurrencyField/UnitField — single NumberField with formatOptions is the canon (matches all surveyed headless libs except PrimeReact's mode enum, which still uses 1 component). svelte-check: 0 errors in modified/created files. See CONTINUE.md for full session notes and next steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/*
* Table recipe.
*
* [data-table] → <table> root
* [data-table-header] → <thead>
* [data-table-body] → <tbody>
* [data-table-footer] → <tfoot>
* [data-table-column-header] → <th>
* [data-table-row] → <tr> (body row)
* [data-table-cell] → <td>
* [data-table-row-detail] → full-width disclosure <tr>
* [data-table-row-detail-trigger] → toggle button (Button consumer)
*
* Wrapper element is provided by the eidos root: `<div data-table-root>`
* absorbs `data-size` / `data-variant` / `data-color` / `data-block` /
* `data-striped` / `data-hoverable` / `data-sticky-header` so the table
* itself can stay clean `<table>` semantics.
*
* Sizes — xs..xl on the wrapper; cascades to row block-size, cell
* padding and font-size.
*
* Variant `'surface' | 'outline' | 'ghost'` (ControlVariant).
* - surface: card chrome around the whole table
* - outline: border only, transparent background
* - ghost: no chrome
*
* Color cascades the accent for selected rows + sort indicator + focus.
*/
[data-table-root] {
--_table-radius: var(--radius-md);
--_table-row-block-size: var(--control-height-md);
--_table-cell-px: var(--space-3);
--_table-cell-py: var(--space-2);
--_table-font-size: var(--font-size-sm);
--_table-header-bg: var(--color-surface-subtle);
--_table-row-hover-bg: var(--color-surface-overlay);
--_table-row-striped-bg: var(--color-surface-subtle);
--_table-divider: var(--color-border-default);
--_table-accent: var(--color-primary-solid);
--_table-accent-soft: var(--color-primary-element);
position: relative;
display: block;
font-family: var(--font-ui);
color: var(--color-content-primary);
border-radius: var(--_table-radius);
overflow: hidden;
}
[data-table-root][data-block] {
inline-size: 100%;
}
/* ── Variant — surface (default) ─ */
[data-table-root][data-variant='surface'] {
border: 1px solid var(--_table-divider);
background: var(--color-surface-default);
}
[data-table-root][data-variant='outline'] {
border: 1px solid var(--_table-divider);
background: transparent;
}
[data-table-root][data-variant='ghost'] {
border: 1px solid transparent;
background: transparent;
}
/* ── Sizes ─ */
[data-table-root][data-size='xs'] {
--_table-row-block-size: var(--control-height-xs);
--_table-cell-px: var(--space-2);
--_table-cell-py: var(--space-1);
--_table-font-size: var(--font-size-xs);
}
[data-table-root][data-size='sm'] {
--_table-row-block-size: var(--control-height-sm);
--_table-cell-px: var(--space-2);
--_table-cell-py: var(--space-1);
--_table-font-size: var(--font-size-sm);
}
[data-table-root][data-size='lg'] {
--_table-row-block-size: var(--control-height-lg);
--_table-cell-px: var(--space-4);
--_table-cell-py: var(--space-3);
--_table-font-size: var(--font-size-md);
}
[data-table-root][data-size='xl'] {
--_table-row-block-size: var(--control-height-xl);
--_table-cell-px: var(--space-5);
--_table-cell-py: var(--space-3);
--_table-font-size: var(--font-size-lg);
}
/* ── Color cascades ─ */
[data-table-root][data-color='secondary'] {
--_table-accent: var(--color-secondary-solid);
--_table-accent-soft: var(--color-secondary-element);
}
[data-table-root][data-color='affirm'] {
--_table-accent: var(--color-affirm-solid);
--_table-accent-soft: var(--color-affirm-element);
}
[data-table-root][data-color='risk'] {
--_table-accent: var(--color-risk-solid);
--_table-accent-soft: var(--color-risk-element);
}
[data-table-root][data-color='threat'] {
--_table-accent: var(--color-threat-solid);
--_table-accent-soft: var(--color-threat-element);
}
[data-table-root][data-color='fulfill'] {
--_table-accent: var(--color-fulfill-solid);
--_table-accent-soft: var(--color-fulfill-element);
}
[data-table-root][data-color='loss'] {
--_table-accent: var(--color-loss-solid);
--_table-accent-soft: var(--color-loss-element);
}
[data-table-root][data-color='neutral'] {
--_table-accent: var(--color-neutral-solid);
--_table-accent-soft: var(--color-neutral-element);
}
/*
* Scrolling region — only when consumer sets `maxHeight`. Pure CSS
* overflow auto with overscroll containment so wheel scrolling inside
* the table doesn't bubble to the page.
*/
[data-table-root][data-scrollable] {
overflow: auto;
overscroll-behavior: contain;
}
/*
* Stable rows — reserve a vertical floor of `stableRows` row-heights
* (plus the header). Keeps the wrapper height steady so the surrounding
* layout (pagination, sticky footers, sibling cards) doesn't jump as
* filters / pageSize change the visible row count. Ignored when the
* wrapper is already capped by `maxHeight` (scroll region).
*
* The consumer sets `--_table-stable-rows` via inline style; the recipe
* multiplies by `--_table-row-block-size` (already scaled by `data-size`)
* and adds one row for the header.
*/
[data-table-root][data-stable-rows] {
/*
* Real row block-size at render = `--_table-row-block-size` (control
* height, the centred content) + 2 × `--_table-cell-py` (cell vertical
* padding) + 1px (cell `border-block-end`). Sum × (rows + 1 header).
*/
min-block-size: calc(
(var(--_table-row-block-size) + var(--_table-cell-py) * 2 + 1px)
* (var(--_table-stable-rows, 0) + 1)
);
}
[data-table-root][data-disabled] {
opacity: 0.55;
pointer-events: none;
}
/* ── Table element ─ */
[data-table] {
inline-size: 100%;
border-collapse: separate;
border-spacing: 0;
font-size: var(--_table-font-size);
line-height: var(--leading-ui);
color: inherit;
caption-side: top;
}
/* ── Header (thead) ─ */
[data-table-header] {
background: var(--_table-header-bg);
}
/*
* Sticky header — when the wrapper is scrollable AND `stickyHeader` is on,
* the `<th>` cells stick to the top of the wrapper. Position is set on
* `<th>` (not `<thead>`) because `<thead>` is not a valid containing
* block for `position: sticky` in legacy rendering paths.
*/
[data-table-root][data-sticky-header] [data-table-column-header] {
position: sticky;
inset-block-start: 0;
z-index: 2;
background: var(--_table-header-bg);
}
/* ── ColumnHeader (th) ─ */
[data-table-column-header] {
box-sizing: border-box;
padding-block: var(--_table-cell-py);
padding-inline: var(--_table-cell-px);
text-align: start;
font-weight: var(--font-weight-semibold, 600);
color: var(--color-content-primary);
border-block-end: 1px solid var(--_table-divider);
white-space: nowrap;
vertical-align: middle;
user-select: none;
}
[data-table-column-header][data-sortable] {
cursor: pointer;
}
[data-table-column-header][data-sorted] {
color: var(--_table-accent);
}
[data-table-column-header][data-pinned] {
background: var(--_table-header-bg);
}
/* ── Body (tbody) ─ */
[data-table-body] [data-table-row] {
background: var(--color-surface-default);
transition: background var(--duration-fast) var(--ease-default);
}
[data-table-root][data-variant='ghost'] [data-table-body] [data-table-row] {
background: transparent;
}
/* Striped — alternate body rows. Skip when ghost (no chrome). */
[data-table-root][data-striped]:not([data-variant='ghost'])
[data-table-body]
[data-table-row]:nth-of-type(even) {
background: var(--_table-row-striped-bg);
}
/* Hoverable — row hover highlight. Drop when row is selected. */
[data-table-root][data-hoverable]
[data-table-body]
[data-table-row]:not([data-selected]):hover {
background: var(--_table-row-hover-bg);
}
/* Selected row — accent tint. Overrides hover + striped. */
[data-table-body] [data-table-row][data-selected] {
background: var(--_table-accent-soft);
color: var(--color-content-primary);
}
/* Last row has no bottom divider — the wrapper border handles the edge. */
[data-table-body] [data-table-row]:last-of-type [data-table-cell] {
border-block-end: 0;
}
/* ── Row (tr) ─ */
[data-table-row] {
outline: none;
}
[data-table-row]:focus-visible {
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: -1px;
}
/* ── Cell (td) ─ */
[data-table-cell] {
box-sizing: border-box;
padding-block: var(--_table-cell-py);
padding-inline: var(--_table-cell-px);
border-block-end: 1px solid var(--_table-divider);
vertical-align: middle;
color: inherit;
}
/*
* Pinned cells take the row's background so the sticky offset doesn't
* reveal content behind them. Cascade from `data-pinned` on either the
* cell or the header.
*/
[data-table-cell][data-pinned] {
background: inherit;
}
/* ── Footer (tfoot) ─ */
[data-table-footer] {
background: var(--_table-header-bg);
}
[data-table-footer] [data-table-cell] {
font-weight: var(--font-weight-semibold, 600);
border-block-end: 0;
border-block-start: 1px solid var(--_table-divider);
}
/* ── RowDetail (disclosure) ─ */
[data-table-row-detail] {
background: var(--color-surface-subtle);
}
[data-table-row-detail][data-state='closed'] {
display: none;
}
[data-table-row-detail] > td {
padding: var(--space-3) var(--_table-cell-px);
border-block-end: 1px solid var(--_table-divider);
color: var(--color-content-secondary);
}
/* ── SortButton (eidos helper) ─ */
[data-table-sort-trigger] {
Build TextArea component + fix locale propagation bug across soma providers Major work in this session: 1. NumberField demo refactored to expose Intl.NumberFormatOptions live - 9 canonical presets (currency/unit/percent/compact/plain) - Locale/currency/unit lists derived from $libs/langs, $libs/currency, $format/units (no more hardcoded arrays) - Default locale from uix.format.numbers.getLocale() 2. Bug fix: locale prop ignored when soma.format service is active - soma/NumberField: 5 bypass points via new `hasOwnLocale` getter (decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue) - soma/Calendar: dateOrder respects locale prop (matches DateField precedence) - soma/RangeCalendar: same dateOrder fix - When the consumer passes `locale` prop, soma.nums/dates is bypassed and Intl is used directly with the prop locale 3. TextArea — new component, full 4-layer stack - morfo: 3 parts (provider/input/count), 3 events (commit-input/commit-submit/shift-count-overflow), APG textbox - soma: TextAreaProvider with autosize (scrollHeight measurement), submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp, Field integration (OR-merge), counter overflow tracking - eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize - sema: commit-submit + shift-count-overflow perceptual cues - demo: canonical 6-tab depth, all props exposed as live controls - PrimitiveTextareaAttributes added to soma/types/html.ts 4. Also includes accumulated unreleased work from prior sessions: - Eidos ports: announce, clipboard, drag-drop, feed, table, tree-grid, tree-view, virtual-grid, virtual-list, words - Their canonical demos under web/routes/uix/components/ - Semantic events defined for utility morfos (announce/clipboard/virtual-list/virtual-grid) - Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients) - Sidebar reorganized with Data + Utilities groups - Eidos words content layer and primitives Reference library survey performed before TextArea API design (Mantine, Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime). Decision documented: no separate CurrencyField/UnitField — single NumberField with formatOptions is the canon (matches all surveyed headless libs except PrimeReact's mode enum, which still uses 1 component). svelte-check: 0 errors in modified/created files. See CONTINUE.md for full session notes and next steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
display: inline-flex;
align-items: center;
gap: var(--space-1);
padding: 0;
margin: 0;
border: 0;
background: transparent;
color: inherit;
cursor: pointer;
font: inherit;
user-select: none;
border-radius: var(--radius-sm);
}
[data-table-sort-trigger]:focus-visible {
Build TextArea component + fix locale propagation bug across soma providers Major work in this session: 1. NumberField demo refactored to expose Intl.NumberFormatOptions live - 9 canonical presets (currency/unit/percent/compact/plain) - Locale/currency/unit lists derived from $libs/langs, $libs/currency, $format/units (no more hardcoded arrays) - Default locale from uix.format.numbers.getLocale() 2. Bug fix: locale prop ignored when soma.format service is active - soma/NumberField: 5 bypass points via new `hasOwnLocale` getter (decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue) - soma/Calendar: dateOrder respects locale prop (matches DateField precedence) - soma/RangeCalendar: same dateOrder fix - When the consumer passes `locale` prop, soma.nums/dates is bypassed and Intl is used directly with the prop locale 3. TextArea — new component, full 4-layer stack - morfo: 3 parts (provider/input/count), 3 events (commit-input/commit-submit/shift-count-overflow), APG textbox - soma: TextAreaProvider with autosize (scrollHeight measurement), submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp, Field integration (OR-merge), counter overflow tracking - eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize - sema: commit-submit + shift-count-overflow perceptual cues - demo: canonical 6-tab depth, all props exposed as live controls - PrimitiveTextareaAttributes added to soma/types/html.ts 4. Also includes accumulated unreleased work from prior sessions: - Eidos ports: announce, clipboard, drag-drop, feed, table, tree-grid, tree-view, virtual-grid, virtual-list, words - Their canonical demos under web/routes/uix/components/ - Semantic events defined for utility morfos (announce/clipboard/virtual-list/virtual-grid) - Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients) - Sidebar reorganized with Data + Utilities groups - Eidos words content layer and primitives Reference library survey performed before TextArea API design (Mantine, Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime). Decision documented: no separate CurrencyField/UnitField — single NumberField with formatOptions is the canon (matches all surveyed headless libs except PrimeReact's mode enum, which still uses 1 component). svelte-check: 0 errors in modified/created files. See CONTINUE.md for full session notes and next steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
outline: var(--focus-ring-width) solid var(--focus-ring-color);
outline-offset: 2px;
}
[data-table-sort-trigger][data-sorted] {
Build TextArea component + fix locale propagation bug across soma providers Major work in this session: 1. NumberField demo refactored to expose Intl.NumberFormatOptions live - 9 canonical presets (currency/unit/percent/compact/plain) - Locale/currency/unit lists derived from $libs/langs, $libs/currency, $format/units (no more hardcoded arrays) - Default locale from uix.format.numbers.getLocale() 2. Bug fix: locale prop ignored when soma.format service is active - soma/NumberField: 5 bypass points via new `hasOwnLocale` getter (decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue) - soma/Calendar: dateOrder respects locale prop (matches DateField precedence) - soma/RangeCalendar: same dateOrder fix - When the consumer passes `locale` prop, soma.nums/dates is bypassed and Intl is used directly with the prop locale 3. TextArea — new component, full 4-layer stack - morfo: 3 parts (provider/input/count), 3 events (commit-input/commit-submit/shift-count-overflow), APG textbox - soma: TextAreaProvider with autosize (scrollHeight measurement), submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp, Field integration (OR-merge), counter overflow tracking - eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize - sema: commit-submit + shift-count-overflow perceptual cues - demo: canonical 6-tab depth, all props exposed as live controls - PrimitiveTextareaAttributes added to soma/types/html.ts 4. Also includes accumulated unreleased work from prior sessions: - Eidos ports: announce, clipboard, drag-drop, feed, table, tree-grid, tree-view, virtual-grid, virtual-list, words - Their canonical demos under web/routes/uix/components/ - Semantic events defined for utility morfos (announce/clipboard/virtual-list/virtual-grid) - Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients) - Sidebar reorganized with Data + Utilities groups - Eidos words content layer and primitives Reference library survey performed before TextArea API design (Mantine, Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime). Decision documented: no separate CurrencyField/UnitField — single NumberField with formatOptions is the canon (matches all surveyed headless libs except PrimeReact's mode enum, which still uses 1 component). svelte-check: 0 errors in modified/created files. See CONTINUE.md for full session notes and next steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
color: var(--_table-accent);
}
[data-table-sort-indicator] {
display: inline-flex;
align-items: center;
justify-content: center;
inline-size: 1em;
block-size: 1em;
opacity: 0.55;
transition: opacity var(--duration-fast) var(--ease-default);
}
[data-table-sort-trigger][data-sorted] [data-table-sort-indicator] {
Build TextArea component + fix locale propagation bug across soma providers Major work in this session: 1. NumberField demo refactored to expose Intl.NumberFormatOptions live - 9 canonical presets (currency/unit/percent/compact/plain) - Locale/currency/unit lists derived from $libs/langs, $libs/currency, $format/units (no more hardcoded arrays) - Default locale from uix.format.numbers.getLocale() 2. Bug fix: locale prop ignored when soma.format service is active - soma/NumberField: 5 bypass points via new `hasOwnLocale` getter (decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue) - soma/Calendar: dateOrder respects locale prop (matches DateField precedence) - soma/RangeCalendar: same dateOrder fix - When the consumer passes `locale` prop, soma.nums/dates is bypassed and Intl is used directly with the prop locale 3. TextArea — new component, full 4-layer stack - morfo: 3 parts (provider/input/count), 3 events (commit-input/commit-submit/shift-count-overflow), APG textbox - soma: TextAreaProvider with autosize (scrollHeight measurement), submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp, Field integration (OR-merge), counter overflow tracking - eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize - sema: commit-submit + shift-count-overflow perceptual cues - demo: canonical 6-tab depth, all props exposed as live controls - PrimitiveTextareaAttributes added to soma/types/html.ts 4. Also includes accumulated unreleased work from prior sessions: - Eidos ports: announce, clipboard, drag-drop, feed, table, tree-grid, tree-view, virtual-grid, virtual-list, words - Their canonical demos under web/routes/uix/components/ - Semantic events defined for utility morfos (announce/clipboard/virtual-list/virtual-grid) - Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients) - Sidebar reorganized with Data + Utilities groups - Eidos words content layer and primitives Reference library survey performed before TextArea API design (Mantine, Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime). Decision documented: no separate CurrencyField/UnitField — single NumberField with formatOptions is the canon (matches all surveyed headless libs except PrimeReact's mode enum, which still uses 1 component). svelte-check: 0 errors in modified/created files. See CONTINUE.md for full session notes and next steps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
opacity: 1;
}

Powered by TurnKey Linux.