@dorsk/tsumikit 0.68.0 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/components/molecules/SegmentedControl.svelte +6 -3
- package/dist/components/molecules/SegmentedControl.svelte.d.ts +4 -2
- package/dist/components/molecules/segmented-control-count.d.ts +2 -0
- package/dist/components/molecules/segmented-control-count.js +6 -0
- package/dist/components/organisms/DataTable.svelte +26 -2
- package/dist/components/organisms/DataTable.svelte.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -334,7 +334,8 @@ bindable, `onselect`/`onclose(reason)` report picks; `findTrigger`/`applyTrigger
|
|
|
334
334
|
are exported for trigger-char detection and token replacement).
|
|
335
335
|
|
|
336
336
|
**Organisms:** ConversationPanel / ConversationFeed (chat column + sticky
|
|
337
|
-
feed, see below), DataTable (generic `<T>`, typed columns + cell snippets;
|
|
337
|
+
feed, see below), DataTable (generic `<T>`, typed columns + cell snippets; `headerSnippets[key]`
|
|
338
|
+
replaces a header cell (a select-all checkbox);
|
|
338
339
|
`layout="fixed"` makes column widths authoritative, `Column.truncate` /
|
|
339
340
|
`nowrap` / `hideBelow="sm|md|lg"` (container-query on the table's own box),
|
|
340
341
|
`hideHeader` clips the header but keeps it for assistive tech, `rowTone(row)`
|
|
@@ -346,7 +347,9 @@ for a hover/focus-revealed trailing cell (always visible on touch; under
|
|
|
346
347
|
hooks on head/row/cell; `responsive="stack"` turns rows into cards below
|
|
347
348
|
`stackBelow` (48rem, measured on the table's own box) using `Column.role`
|
|
348
349
|
`title | detail | meta | actions | hidden` — detail cells get a `data-label`
|
|
349
|
-
prefix,
|
|
350
|
+
prefix, `Column.stackLabel: false` drops it so metas join on one `·` line
|
|
351
|
+
and details share lines, `--dt-meta-font` restyles meta values, the `<table>`
|
|
352
|
+
stays a table for assistive tech), FilterSearchBar /
|
|
350
353
|
FilterInput (`size="sm"` compact bar on `--control-height-compact`,
|
|
351
354
|
`shape="pill"`, `surface`, `hotkey="/"` focuses the input from anywhere
|
|
352
355
|
outside an editable element, `showHotkey` renders the `<kbd>` hint, `grow`;
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
value: string;
|
|
4
4
|
/** Visible text. Optional in `icon` mode where the icon carries the meaning. */
|
|
5
5
|
label?: string;
|
|
6
|
-
/** Optional count badge rendered after the label (filter-pill use).
|
|
7
|
-
|
|
6
|
+
/** Optional count badge rendered after the label (filter-pill use). Numbers
|
|
7
|
+
* get thousands separators (`11178` → `11,178`, fixed en-US so SSR and
|
|
8
|
+
* hydration agree); strings render verbatim (`'99+'`, another locale). */
|
|
9
|
+
count?: number | string;
|
|
8
10
|
/** Icon glyph — required for icon-toggle mode, optional alongside a label. */
|
|
9
11
|
icon?: import('../atoms/Icon.svelte').IconName;
|
|
10
12
|
/** Greyed out, not selectable, skipped by keyboard navigation. */
|
|
@@ -23,6 +25,7 @@
|
|
|
23
25
|
// Space/Enter (or click) activate. `value` is bindable.
|
|
24
26
|
import type { Snippet } from 'svelte';
|
|
25
27
|
import Icon from '../atoms/Icon.svelte';
|
|
28
|
+
import { formatSegmentCount } from './segmented-control-count.js';
|
|
26
29
|
import { nextEnabledSegment } from './segmented-control-keyboard.js';
|
|
27
30
|
|
|
28
31
|
let {
|
|
@@ -143,7 +146,7 @@
|
|
|
143
146
|
{:else}
|
|
144
147
|
{#if o.icon}<Icon name={o.icon} />{/if}
|
|
145
148
|
{#if o.label}<span class="seg-label">{o.label}</span>{/if}
|
|
146
|
-
{#if o.count !== undefined}<span class="seg-count">{o.count}</span>{/if}
|
|
149
|
+
{#if o.count !== undefined}<span class="seg-count">{formatSegmentCount(o.count)}</span>{/if}
|
|
147
150
|
{/if}
|
|
148
151
|
</button>
|
|
149
152
|
{/each}
|
|
@@ -2,8 +2,10 @@ export interface SegmentOption {
|
|
|
2
2
|
value: string;
|
|
3
3
|
/** Visible text. Optional in `icon` mode where the icon carries the meaning. */
|
|
4
4
|
label?: string;
|
|
5
|
-
/** Optional count badge rendered after the label (filter-pill use).
|
|
6
|
-
|
|
5
|
+
/** Optional count badge rendered after the label (filter-pill use). Numbers
|
|
6
|
+
* get thousands separators (`11178` → `11,178`, fixed en-US so SSR and
|
|
7
|
+
* hydration agree); strings render verbatim (`'99+'`, another locale). */
|
|
8
|
+
count?: number | string;
|
|
7
9
|
/** Icon glyph — required for icon-toggle mode, optional alongside a label. */
|
|
8
10
|
icon?: import('../atoms/Icon.svelte').IconName;
|
|
9
11
|
/** Greyed out, not selectable, skipped by keyboard navigation. */
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
/** Placement inside the stacked card (`responsive="stack"` only). Columns
|
|
22
22
|
* without a role render as `label: value` detail lines. */
|
|
23
23
|
role?: 'title' | 'detail' | 'meta' | 'actions' | 'hidden';
|
|
24
|
+
/** `false` drops the stacked label: meta cells join on one `·` line and
|
|
25
|
+
* detail cells share lines (`responsive="stack"` only, default true). */
|
|
26
|
+
stackLabel?: boolean;
|
|
24
27
|
}
|
|
25
28
|
</script>
|
|
26
29
|
|
|
@@ -40,6 +43,7 @@
|
|
|
40
43
|
onrowclick,
|
|
41
44
|
onsort,
|
|
42
45
|
cellSnippets = {},
|
|
46
|
+
headerSnippets = {},
|
|
43
47
|
empty = 'No data.',
|
|
44
48
|
stickyHeader = false,
|
|
45
49
|
stickyOffset,
|
|
@@ -69,6 +73,8 @@
|
|
|
69
73
|
* table only reflects the indicator and emits; it does not reorder rows. */
|
|
70
74
|
onsort?: (key: string, dir: 'asc' | 'desc') => void;
|
|
71
75
|
cellSnippets?: Record<string, Snippet<[T]>>;
|
|
76
|
+
/** Replaces a column's header content (e.g. a select-all checkbox). */
|
|
77
|
+
headerSnippets?: Record<string, Snippet<[Column<T>]>>;
|
|
72
78
|
empty?: string | Snippet;
|
|
73
79
|
stickyHeader?: boolean;
|
|
74
80
|
/** Distance from the scroll container's top for the sticky header, e.g.
|
|
@@ -210,7 +216,9 @@
|
|
|
210
216
|
: 'none'
|
|
211
217
|
: undefined}
|
|
212
218
|
>
|
|
213
|
-
{#if col.
|
|
219
|
+
{#if headerSnippets[col.key]}
|
|
220
|
+
{@render headerSnippets[col.key](col)}
|
|
221
|
+
{:else if col.sortable}
|
|
214
222
|
<button type="button" class="dt-sort" onclick={() => toggleSort(col)}>
|
|
215
223
|
<span>{col.label}</span>
|
|
216
224
|
<span class="dt-arrow" class:active={sortKey === col.key}>
|
|
@@ -264,6 +272,7 @@
|
|
|
264
272
|
data-hide-below={col.hideBelow}
|
|
265
273
|
data-role={responsive === 'stack' ? (col.role ?? 'detail') : undefined}
|
|
266
274
|
data-label={responsive === 'stack' ? col.label : undefined}
|
|
275
|
+
data-stack-label={responsive === 'stack' && col.stackLabel === false ? 'false' : undefined}
|
|
267
276
|
class:truncate={col.truncate}
|
|
268
277
|
class:nowrap={col.nowrap}
|
|
269
278
|
style:text-align={stacked ? undefined : (col.align ?? 'left')}
|
|
@@ -528,12 +537,27 @@
|
|
|
528
537
|
[data-stacked] td[data-role='meta'] {
|
|
529
538
|
flex: none;
|
|
530
539
|
order: 1;
|
|
531
|
-
font-family: var(--font-mono);
|
|
540
|
+
font-family: var(--dt-meta-font, var(--font-mono));
|
|
532
541
|
font-size: var(--fs-xs);
|
|
533
542
|
color: var(--text-muted);
|
|
534
543
|
}
|
|
535
544
|
[data-stacked] td[data-role='meta']::before {
|
|
536
545
|
content: attr(data-label) ' ';
|
|
546
|
+
font-family: var(--font-sans);
|
|
547
|
+
color: var(--text-faint);
|
|
548
|
+
}
|
|
549
|
+
[data-stacked] td[data-role='detail'][data-stack-label='false'] {
|
|
550
|
+
flex: 0 1 auto;
|
|
551
|
+
}
|
|
552
|
+
[data-stacked] td[data-stack-label='false']::before {
|
|
553
|
+
content: none;
|
|
554
|
+
}
|
|
555
|
+
[data-stacked] td[data-role='meta'] ~ td[data-role='meta'][data-stack-label='false'] {
|
|
556
|
+
margin-inline-start: calc(var(--sp-1) - var(--sp-3));
|
|
557
|
+
}
|
|
558
|
+
[data-stacked] td[data-role='meta'] ~ td[data-role='meta'][data-stack-label='false']::before {
|
|
559
|
+
content: '·';
|
|
560
|
+
margin-inline-end: var(--sp-1);
|
|
537
561
|
color: var(--text-faint);
|
|
538
562
|
}
|
|
539
563
|
[data-stacked] td[data-role='actions'],
|
|
@@ -19,6 +19,9 @@ export interface Column<T> {
|
|
|
19
19
|
/** Placement inside the stacked card (`responsive="stack"` only). Columns
|
|
20
20
|
* without a role render as `label: value` detail lines. */
|
|
21
21
|
role?: 'title' | 'detail' | 'meta' | 'actions' | 'hidden';
|
|
22
|
+
/** `false` drops the stacked label: meta cells join on one `·` line and
|
|
23
|
+
* detail cells share lines (`responsive="stack"` only, default true). */
|
|
24
|
+
stackLabel?: boolean;
|
|
22
25
|
}
|
|
23
26
|
import type { Snippet } from 'svelte';
|
|
24
27
|
declare function $$render<T>(): {
|
|
@@ -32,6 +35,8 @@ declare function $$render<T>(): {
|
|
|
32
35
|
* table only reflects the indicator and emits; it does not reorder rows. */
|
|
33
36
|
onsort?: (key: string, dir: "asc" | "desc") => void;
|
|
34
37
|
cellSnippets?: Record<string, Snippet<[T]>>;
|
|
38
|
+
/** Replaces a column's header content (e.g. a select-all checkbox). */
|
|
39
|
+
headerSnippets?: Record<string, Snippet<[Column<T>]>>;
|
|
35
40
|
empty?: string | Snippet;
|
|
36
41
|
stickyHeader?: boolean;
|
|
37
42
|
/** Distance from the scroll container's top for the sticky header, e.g.
|
package/package.json
CHANGED