@ruckc/truss-ui 1.2.0 → 1.4.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 +6 -1
- package/dist/commands.svelte.d.ts +41 -0
- package/dist/commands.svelte.js +59 -0
- package/dist/components/Accordion.svelte +1 -1
- package/dist/components/Button.svelte +65 -8
- package/dist/components/Button.svelte.d.ts +2 -0
- package/dist/components/Calendar.svelte +2 -2
- package/dist/components/Card.svelte +1 -0
- package/dist/components/Card.svelte.d.ts +1 -0
- package/dist/components/Checkbox.svelte +1 -1
- package/dist/components/CommandPalette.svelte +207 -0
- package/dist/components/CommandPalette.svelte.d.ts +39 -0
- package/dist/components/DataTable.svelte +201 -27
- package/dist/components/DataTable.svelte.d.ts +50 -4
- package/dist/components/Dialog.svelte +2 -1
- package/dist/components/Drawer.svelte +1 -1
- package/dist/components/EditableText.svelte +2 -2
- package/dist/components/Eyebrow.svelte +1 -1
- package/dist/components/FileUpload.svelte +1 -1
- package/dist/components/Footer.svelte +29 -2
- package/dist/components/Footer.svelte.d.ts +8 -0
- package/dist/components/GridLayout.svelte +242 -0
- package/dist/components/GridLayout.svelte.d.ts +30 -0
- package/dist/components/HoverCard.svelte +158 -0
- package/dist/components/HoverCard.svelte.d.ts +46 -0
- package/dist/components/Kbd.svelte +36 -0
- package/dist/components/Kbd.svelte.d.ts +8 -0
- package/dist/components/Link.svelte +1 -1
- package/dist/components/List.svelte +113 -0
- package/dist/components/List.svelte.d.ts +17 -0
- package/dist/components/ListItem.svelte +13 -0
- package/dist/components/ListItem.svelte.d.ts +9 -0
- package/dist/components/Menu.svelte +4 -3
- package/dist/components/MultiSelect.svelte +2 -2
- package/dist/components/Navbar.svelte +13 -3
- package/dist/components/Navbar.svelte.d.ts +5 -1
- package/dist/components/Panel.svelte +2 -2
- package/dist/components/Popover.svelte +22 -1
- package/dist/components/Popover.svelte.d.ts +2 -0
- package/dist/components/RadioGroup.svelte +1 -1
- package/dist/components/Select.svelte +1 -1
- package/dist/components/Shell.svelte +12 -1
- package/dist/components/Shell.svelte.d.ts +2 -0
- package/dist/components/ShortcutSheet.svelte +62 -0
- package/dist/components/ShortcutSheet.svelte.d.ts +9 -0
- package/dist/components/Sidebar.svelte +2 -2
- package/dist/components/Skeleton.svelte +80 -6
- package/dist/components/Skeleton.svelte.d.ts +8 -1
- package/dist/components/Slider.svelte +1 -1
- package/dist/components/Switch.svelte +1 -1
- package/dist/components/Tabs.svelte +252 -32
- package/dist/components/Tabs.svelte.d.ts +21 -9
- package/dist/components/Tag.svelte +7 -7
- package/dist/components/TagInput.svelte +1 -1
- package/dist/components/Text.svelte +1 -1
- package/dist/components/Toaster.svelte +33 -2
- package/dist/components/ToggleChip.svelte +1 -1
- package/dist/components/Toolbar.svelte +27 -0
- package/dist/components/Toolbar.svelte.d.ts +10 -0
- package/dist/components/ToolbarSeparator.svelte +15 -0
- package/dist/components/ToolbarSeparator.svelte.d.ts +3 -0
- package/dist/components/Tooltip.svelte +19 -28
- package/dist/components/Tooltip.svelte.d.ts +6 -1
- package/dist/components/TooltipTip.svelte +59 -0
- package/dist/components/TooltipTip.svelte.d.ts +12 -0
- package/dist/components/Tree.svelte +343 -44
- package/dist/components/Tree.svelte.d.ts +29 -2
- package/dist/grid-layout.d.ts +42 -0
- package/dist/grid-layout.js +100 -0
- package/dist/hotkeys.svelte.d.ts +45 -0
- package/dist/hotkeys.svelte.js +108 -0
- package/dist/index.d.ts +21 -2
- package/dist/index.js +13 -0
- package/dist/keys.d.ts +25 -0
- package/dist/keys.js +88 -0
- package/dist/roving.d.ts +25 -0
- package/dist/roving.js +129 -0
- package/dist/styles/base.css +2 -0
- package/dist/styles/tokens.css +49 -0
- package/dist/table-export.d.ts +24 -0
- package/dist/table-export.js +130 -0
- package/dist/toast.svelte.d.ts +25 -1
- package/dist/toast.svelte.js +42 -4
- package/dist/types.d.ts +6 -0
- package/package.json +7 -3
package/dist/styles/tokens.css
CHANGED
|
@@ -46,6 +46,10 @@
|
|
|
46
46
|
--tr-control-h-sm: 24px;
|
|
47
47
|
--tr-control-h: 32px;
|
|
48
48
|
--tr-control-h-lg: 40px;
|
|
49
|
+
/* Row heights: table body rows, table header rows, tree rows. Density scales these. */
|
|
50
|
+
--tr-row-h: 32px;
|
|
51
|
+
--tr-row-h-head: 28px;
|
|
52
|
+
--tr-tree-row-h: 28px;
|
|
49
53
|
--tr-icon-sm: 16px;
|
|
50
54
|
--tr-icon-lg: 20px;
|
|
51
55
|
--tr-gap: 8px;
|
|
@@ -62,6 +66,7 @@
|
|
|
62
66
|
--tr-dur: 160ms;
|
|
63
67
|
|
|
64
68
|
/* Color roles — light */
|
|
69
|
+
/* --tr-primary-text / --tr-secondary-text are optional: unset, text follows the fill colour (also on a re-themed subtree). Set them when a brand fill is too light for small text. */
|
|
65
70
|
--tr-primary: #1f5fbf;
|
|
66
71
|
--tr-on-primary: #ffffff;
|
|
67
72
|
--tr-primary-container: #d8e4ff;
|
|
@@ -182,3 +187,47 @@
|
|
|
182
187
|
--tr-scrim: rgb(0 0 0 / 0.55);
|
|
183
188
|
--tr-shadow-color: 0 0 0;
|
|
184
189
|
}
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* Density: <html data-density="compact|default|comfortable"> or on any subtree element.
|
|
193
|
+
* Scales control, row and type tokens; a local override (e.g. InputGroup size) still wins.
|
|
194
|
+
*/
|
|
195
|
+
[data-density='compact'] {
|
|
196
|
+
--tr-control-h-sm: 20px;
|
|
197
|
+
--tr-control-h: 26px;
|
|
198
|
+
--tr-control-h-lg: 32px;
|
|
199
|
+
--tr-row-h: 24px;
|
|
200
|
+
--tr-row-h-head: 24px;
|
|
201
|
+
--tr-tree-row-h: 22px;
|
|
202
|
+
--tr-gap: 6px;
|
|
203
|
+
--tr-text-xs: 10px;
|
|
204
|
+
--tr-text-sm: 11px;
|
|
205
|
+
--tr-text-md: 13px;
|
|
206
|
+
--tr-text-lg: 15px;
|
|
207
|
+
}
|
|
208
|
+
[data-density='default'] {
|
|
209
|
+
--tr-control-h-sm: 24px;
|
|
210
|
+
--tr-control-h: 32px;
|
|
211
|
+
--tr-control-h-lg: 40px;
|
|
212
|
+
--tr-row-h: 32px;
|
|
213
|
+
--tr-row-h-head: 28px;
|
|
214
|
+
--tr-tree-row-h: 28px;
|
|
215
|
+
--tr-gap: 8px;
|
|
216
|
+
--tr-text-xs: 11px;
|
|
217
|
+
--tr-text-sm: 12px;
|
|
218
|
+
--tr-text-md: 14px;
|
|
219
|
+
--tr-text-lg: 16px;
|
|
220
|
+
}
|
|
221
|
+
[data-density='comfortable'] {
|
|
222
|
+
--tr-control-h-sm: 28px;
|
|
223
|
+
--tr-control-h: 40px;
|
|
224
|
+
--tr-control-h-lg: 48px;
|
|
225
|
+
--tr-row-h: 44px;
|
|
226
|
+
--tr-row-h-head: 36px;
|
|
227
|
+
--tr-tree-row-h: 36px;
|
|
228
|
+
--tr-gap: 12px;
|
|
229
|
+
--tr-text-xs: 12px;
|
|
230
|
+
--tr-text-sm: 13px;
|
|
231
|
+
--tr-text-md: 15px;
|
|
232
|
+
--tr-text-lg: 17px;
|
|
233
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Column } from './types.js';
|
|
2
|
+
export type ExportFormat = 'csv' | 'tsv' | 'json';
|
|
3
|
+
/** Custom serializer, e.g. SQL `VALUES`. Receives the rows and the columns being exported. */
|
|
4
|
+
export type ExportSerializer<T> = (rows: T[], columns: Column<T>[]) => string;
|
|
5
|
+
export type ExportOptions = {
|
|
6
|
+
/** Include a header line (CSV / TSV). Default true. */
|
|
7
|
+
header?: boolean;
|
|
8
|
+
/** Locale for the default display formatters. Defaults to the runtime locale. */
|
|
9
|
+
locale?: string;
|
|
10
|
+
};
|
|
11
|
+
/** The unambiguous (ISO 8601) form of a date / datetime value, or undefined. Date-only values never gain a time. */
|
|
12
|
+
export declare function isoValue(v: unknown, type: 'date' | 'datetime'): string | undefined;
|
|
13
|
+
/** Default display text for a cell (what the table shows when you give no `format`). */
|
|
14
|
+
export declare function displayValue<T>(row: T, column: Column<T>, locale?: string): string;
|
|
15
|
+
/** ISO tooltip for date / datetime columns (undefined otherwise). */
|
|
16
|
+
export declare function titleValue<T>(row: T, column: Column<T>): string | undefined;
|
|
17
|
+
/** CSV per RFC 4180 (comma separated, CRLF line breaks, no trailing newline). */
|
|
18
|
+
export declare const toCsv: <T>(rows: T[], columns: Column<T>[], opts?: ExportOptions) => string;
|
|
19
|
+
/** Tab separated, spreadsheet-friendly: fields with tabs, quotes or line breaks are quoted the way Excel and Sheets expect. */
|
|
20
|
+
export declare const toTsv: <T>(rows: T[], columns: Column<T>[], opts?: ExportOptions) => string;
|
|
21
|
+
/** JSON array of objects keyed by column key. Values keep their type (numbers stay numbers; dates become ISO strings); `Column.format` is not applied. */
|
|
22
|
+
export declare function toJson<T>(rows: T[], columns: Column<T>[]): string;
|
|
23
|
+
/** Serialize rows with the given columns. Pure: no DOM, no clipboard. */
|
|
24
|
+
export declare function serializeRows<T>(rows: T[], columns: Column<T>[], format: ExportFormat | ExportSerializer<T>, opts?: ExportOptions): string;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const nf = new Map();
|
|
2
|
+
const df = new Map();
|
|
3
|
+
function numberFormat(locale) {
|
|
4
|
+
const k = locale ?? '';
|
|
5
|
+
let f = nf.get(k);
|
|
6
|
+
if (!f)
|
|
7
|
+
nf.set(k, (f = new Intl.NumberFormat(locale, { maximumFractionDigits: 20 })));
|
|
8
|
+
return f;
|
|
9
|
+
}
|
|
10
|
+
function dateFormat(locale, kind, utc) {
|
|
11
|
+
const k = `${locale ?? ''}|${kind}|${utc}`;
|
|
12
|
+
let f = df.get(k);
|
|
13
|
+
if (!f)
|
|
14
|
+
df.set(k, (f = new Intl.DateTimeFormat(locale, kind === 'date' ? { dateStyle: 'medium', timeZone: utc ? 'UTC' : undefined } : { dateStyle: 'medium', timeStyle: 'short' })));
|
|
15
|
+
return f;
|
|
16
|
+
}
|
|
17
|
+
const DATE_ONLY = /^(\d{4})-(\d{2})-(\d{2})(?:[T ]00:00(?::00(?:\.0+)?)?(?:Z|[+-]00:?00)?)?$/;
|
|
18
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
19
|
+
/** Parse a date-ish value. `dateOnly` is true for `YYYY-MM-DD` strings (optionally with a midnight time), which carry no time zone. */
|
|
20
|
+
function toDate(v, type) {
|
|
21
|
+
if (typeof v === 'string') {
|
|
22
|
+
const s = v.trim();
|
|
23
|
+
const m = DATE_ONLY.exec(s);
|
|
24
|
+
if (m && (type === 'date' || /^\d{4}-\d{2}-\d{2}$/.test(s))) {
|
|
25
|
+
const d = new Date(Date.UTC(+m[1], +m[2] - 1, +m[3]));
|
|
26
|
+
return Number.isNaN(d.getTime()) ? null : { d, dateOnly: true };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const d = v instanceof Date ? v : new Date(v);
|
|
30
|
+
return Number.isNaN(d.getTime()) ? null : { d, dateOnly: false };
|
|
31
|
+
}
|
|
32
|
+
/** The unambiguous (ISO 8601) form of a date / datetime value, or undefined. Date-only values never gain a time. */
|
|
33
|
+
export function isoValue(v, type) {
|
|
34
|
+
if (v == null || v === '')
|
|
35
|
+
return undefined;
|
|
36
|
+
const p = toDate(v, type);
|
|
37
|
+
if (!p)
|
|
38
|
+
return undefined;
|
|
39
|
+
if (p.dateOnly)
|
|
40
|
+
return p.d.toISOString().slice(0, 10);
|
|
41
|
+
if (type === 'date')
|
|
42
|
+
return `${p.d.getFullYear()}-${pad(p.d.getMonth() + 1)}-${pad(p.d.getDate())}`;
|
|
43
|
+
return p.d.toISOString();
|
|
44
|
+
}
|
|
45
|
+
function safeJson(v) {
|
|
46
|
+
try {
|
|
47
|
+
return JSON.stringify(v) ?? '';
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return String(v);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Default display text for a cell (what the table shows when you give no `format`). */
|
|
54
|
+
export function displayValue(row, column, locale) {
|
|
55
|
+
const v = row[column.key];
|
|
56
|
+
if (column.format)
|
|
57
|
+
return column.format(v, row);
|
|
58
|
+
if (v == null)
|
|
59
|
+
return '';
|
|
60
|
+
switch (column.type) {
|
|
61
|
+
case 'number':
|
|
62
|
+
return typeof v === 'bigint' || (typeof v === 'number' && Number.isFinite(v)) ? numberFormat(locale).format(v) : String(v);
|
|
63
|
+
case 'date':
|
|
64
|
+
case 'datetime': {
|
|
65
|
+
const p = toDate(v, column.type);
|
|
66
|
+
if (!p)
|
|
67
|
+
return String(v);
|
|
68
|
+
return dateFormat(locale, column.type, column.type === 'date' && p.dateOnly).format(p.d);
|
|
69
|
+
}
|
|
70
|
+
case 'json':
|
|
71
|
+
return typeof v === 'string' ? v : safeJson(v);
|
|
72
|
+
default:
|
|
73
|
+
return typeof v === 'object' && !(v instanceof Date) ? safeJson(v) : String(v);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** ISO tooltip for date / datetime columns (undefined otherwise). */
|
|
77
|
+
export function titleValue(row, column) {
|
|
78
|
+
if (column.type !== 'date' && column.type !== 'datetime')
|
|
79
|
+
return undefined;
|
|
80
|
+
return isoValue(row[column.key], column.type);
|
|
81
|
+
}
|
|
82
|
+
/** Plain text for export: `Column.format` when given, otherwise the raw value (ISO dates, un-grouped numbers, JSON). */
|
|
83
|
+
function exportText(row, c) {
|
|
84
|
+
const v = row[c.key];
|
|
85
|
+
if (c.format)
|
|
86
|
+
return c.format(v, row);
|
|
87
|
+
if (v == null)
|
|
88
|
+
return '';
|
|
89
|
+
if (c.type === 'date' || c.type === 'datetime')
|
|
90
|
+
return isoValue(v, c.type) ?? String(v);
|
|
91
|
+
if (v instanceof Date)
|
|
92
|
+
return v.toISOString();
|
|
93
|
+
if (typeof v === 'object')
|
|
94
|
+
return safeJson(v);
|
|
95
|
+
return String(v);
|
|
96
|
+
}
|
|
97
|
+
/** RFC 4180: quote a field holding a quote, delimiter, CR or LF; double embedded quotes. */
|
|
98
|
+
function field(s, delim) {
|
|
99
|
+
return s.includes('"') || s.includes(delim) || s.includes('\n') || s.includes('\r') ? `"${s.replaceAll('"', '""')}"` : s;
|
|
100
|
+
}
|
|
101
|
+
function delimited(rows, columns, delim, eol, header) {
|
|
102
|
+
const lines = [];
|
|
103
|
+
if (header)
|
|
104
|
+
lines.push(columns.map((c) => field(c.header, delim)).join(delim));
|
|
105
|
+
for (const r of rows)
|
|
106
|
+
lines.push(columns.map((c) => field(exportText(r, c), delim)).join(delim));
|
|
107
|
+
return lines.join(eol);
|
|
108
|
+
}
|
|
109
|
+
/** CSV per RFC 4180 (comma separated, CRLF line breaks, no trailing newline). */
|
|
110
|
+
export const toCsv = (rows, columns, opts = {}) => delimited(rows, columns, ',', '\r\n', opts.header !== false);
|
|
111
|
+
/** Tab separated, spreadsheet-friendly: fields with tabs, quotes or line breaks are quoted the way Excel and Sheets expect. */
|
|
112
|
+
export const toTsv = (rows, columns, opts = {}) => delimited(rows, columns, '\t', '\n', opts.header !== false);
|
|
113
|
+
/** JSON array of objects keyed by column key. Values keep their type (numbers stay numbers; dates become ISO strings); `Column.format` is not applied. */
|
|
114
|
+
export function toJson(rows, columns) {
|
|
115
|
+
const out = rows.map((r) => {
|
|
116
|
+
const o = {};
|
|
117
|
+
for (const c of columns) {
|
|
118
|
+
const v = r[c.key];
|
|
119
|
+
o[c.key] = (c.type === 'date' || c.type === 'datetime') && v != null ? (isoValue(v, c.type) ?? v) : (v ?? null);
|
|
120
|
+
}
|
|
121
|
+
return o;
|
|
122
|
+
});
|
|
123
|
+
return JSON.stringify(out, null, 2);
|
|
124
|
+
}
|
|
125
|
+
/** Serialize rows with the given columns. Pure: no DOM, no clipboard. */
|
|
126
|
+
export function serializeRows(rows, columns, format, opts = {}) {
|
|
127
|
+
if (typeof format === 'function')
|
|
128
|
+
return format(rows, columns);
|
|
129
|
+
return format === 'csv' ? toCsv(rows, columns, opts) : format === 'tsv' ? toTsv(rows, columns, opts) : toJson(rows, columns);
|
|
130
|
+
}
|
package/dist/toast.svelte.d.ts
CHANGED
|
@@ -1,21 +1,45 @@
|
|
|
1
1
|
export type ToastIntent = 'primary' | 'success' | 'warning' | 'danger';
|
|
2
|
+
export type ToastAction = {
|
|
3
|
+
label: string;
|
|
4
|
+
run: () => void;
|
|
5
|
+
};
|
|
2
6
|
export type Toast = {
|
|
3
7
|
id: number;
|
|
4
8
|
intent: ToastIntent;
|
|
5
9
|
message: string;
|
|
6
10
|
timeout: number;
|
|
11
|
+
action?: ToastAction;
|
|
7
12
|
};
|
|
8
13
|
declare class ToastStore {
|
|
9
14
|
#private;
|
|
10
15
|
items: Toast[];
|
|
11
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Show a toast. `timeout: 0` keeps it until dismissed. `action` adds a button that runs its
|
|
18
|
+
* `run` callback and dismisses the toast. Returns its id.
|
|
19
|
+
*/
|
|
12
20
|
push(message: string, opts?: {
|
|
13
21
|
intent?: ToastIntent;
|
|
14
22
|
timeout?: number;
|
|
23
|
+
action?: ToastAction;
|
|
15
24
|
}): number;
|
|
16
25
|
success: (message: string, timeout?: number) => number;
|
|
17
26
|
warning: (message: string, timeout?: number) => number;
|
|
18
27
|
danger: (message: string, timeout?: number) => number;
|
|
28
|
+
/**
|
|
29
|
+
* Run `run()` now and show a toast with an Undo action that calls `undo()` if pressed before
|
|
30
|
+
* the toast times out. Returns its id.
|
|
31
|
+
*/
|
|
32
|
+
undoable({ message, run, undo, timeout, intent }: {
|
|
33
|
+
message: string;
|
|
34
|
+
run: () => void;
|
|
35
|
+
undo: () => void;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
intent?: ToastIntent;
|
|
38
|
+
}): number;
|
|
39
|
+
/** Stop the auto-dismiss timer, remembering the time that is left. No-op if not timed or already paused. */
|
|
40
|
+
pause(id: number): void;
|
|
41
|
+
/** Restart the auto-dismiss timer with the time that was left when it was paused. */
|
|
42
|
+
resume(id: number): void;
|
|
19
43
|
dismiss(id: number): void;
|
|
20
44
|
}
|
|
21
45
|
export declare const toasts: ToastStore;
|
package/dist/toast.svelte.js
CHANGED
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
class ToastStore {
|
|
2
2
|
items = $state([]);
|
|
3
3
|
#next = 1;
|
|
4
|
-
|
|
4
|
+
#timers = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* Show a toast. `timeout: 0` keeps it until dismissed. `action` adds a button that runs its
|
|
7
|
+
* `run` callback and dismisses the toast. Returns its id.
|
|
8
|
+
*/
|
|
5
9
|
push(message, opts = {}) {
|
|
6
|
-
const toast = { id: this.#next++, intent: opts.intent ?? 'primary', message, timeout: opts.timeout ?? 5000 };
|
|
10
|
+
const toast = { id: this.#next++, intent: opts.intent ?? 'primary', message, timeout: opts.timeout ?? 5000, action: opts.action };
|
|
7
11
|
this.items.push(toast);
|
|
8
12
|
if (toast.timeout > 0)
|
|
9
|
-
|
|
13
|
+
this.#arm(toast.id, toast.timeout);
|
|
10
14
|
return toast.id;
|
|
11
15
|
}
|
|
12
16
|
success = (message, timeout) => this.push(message, { intent: 'success', timeout });
|
|
13
17
|
warning = (message, timeout) => this.push(message, { intent: 'warning', timeout });
|
|
14
18
|
danger = (message, timeout) => this.push(message, { intent: 'danger', timeout });
|
|
19
|
+
/**
|
|
20
|
+
* Run `run()` now and show a toast with an Undo action that calls `undo()` if pressed before
|
|
21
|
+
* the toast times out. Returns its id.
|
|
22
|
+
*/
|
|
23
|
+
undoable({ message, run, undo, timeout = 8000, intent = 'primary' }) {
|
|
24
|
+
run();
|
|
25
|
+
return this.push(message, { intent, timeout, action: { label: 'Undo', run: undo } });
|
|
26
|
+
}
|
|
27
|
+
/** Stop the auto-dismiss timer, remembering the time that is left. No-op if not timed or already paused. */
|
|
28
|
+
pause(id) {
|
|
29
|
+
const t = this.#timers.get(id);
|
|
30
|
+
if (!t?.handle)
|
|
31
|
+
return;
|
|
32
|
+
clearTimeout(t.handle);
|
|
33
|
+
t.handle = undefined;
|
|
34
|
+
t.remaining -= Date.now() - t.started;
|
|
35
|
+
}
|
|
36
|
+
/** Restart the auto-dismiss timer with the time that was left when it was paused. */
|
|
37
|
+
resume(id) {
|
|
38
|
+
const t = this.#timers.get(id);
|
|
39
|
+
if (!t || t.handle)
|
|
40
|
+
return;
|
|
41
|
+
t.started = Date.now();
|
|
42
|
+
t.handle = setTimeout(() => this.dismiss(id), Math.max(0, t.remaining));
|
|
43
|
+
}
|
|
15
44
|
dismiss(id) {
|
|
16
|
-
|
|
45
|
+
const t = this.#timers.get(id);
|
|
46
|
+
if (t?.handle)
|
|
47
|
+
clearTimeout(t.handle);
|
|
48
|
+
this.#timers.delete(id);
|
|
49
|
+
this.items = this.items.filter((x) => x.id !== id);
|
|
50
|
+
}
|
|
51
|
+
#arm(id, ms) {
|
|
52
|
+
const timer = { remaining: ms, started: Date.now() };
|
|
53
|
+
timer.handle = setTimeout(() => this.dismiss(id), ms);
|
|
54
|
+
this.#timers.set(id, timer);
|
|
17
55
|
}
|
|
18
56
|
}
|
|
19
57
|
export const toasts = new ToastStore();
|
package/dist/types.d.ts
CHANGED
|
@@ -24,11 +24,17 @@ export type MenuEntry = MenuItem | {
|
|
|
24
24
|
} | {
|
|
25
25
|
heading: string;
|
|
26
26
|
};
|
|
27
|
+
export type ColumnType = 'text' | 'number' | 'date' | 'datetime' | 'boolean' | 'json';
|
|
27
28
|
export type Column<R> = {
|
|
28
29
|
key: keyof R & string;
|
|
29
30
|
header: string;
|
|
31
|
+
/** Data type: sets default alignment (numbers and dates end-align with tabular figures) and default cell and export formatting. */
|
|
32
|
+
type?: ColumnType;
|
|
33
|
+
/** Overrides the default cell text, and is used for CSV / TSV export. Return plain text. */
|
|
34
|
+
format?: (value: R[keyof R & string], row: R) => string;
|
|
30
35
|
width?: number;
|
|
31
36
|
minWidth?: number;
|
|
37
|
+
/** Defaults to `end` for number, date and datetime columns. */
|
|
32
38
|
align?: 'start' | 'end';
|
|
33
39
|
sortable?: boolean;
|
|
34
40
|
/** Defaults to true (except the last column). */
|
package/package.json
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
16
16
|
"@types/node": "^26.6.6",
|
|
17
17
|
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
18
|
+
"monocart-coverage-reports": "^3.2.0",
|
|
18
19
|
"semantic-release": "^25.0.9",
|
|
19
20
|
"svelte": "^5.57.2",
|
|
20
21
|
"svelte-check": "^4.7.5",
|
|
@@ -67,14 +68,17 @@
|
|
|
67
68
|
"url": "git+https://github.com/ruckc/truss-ui.git"
|
|
68
69
|
},
|
|
69
70
|
"scripts": {
|
|
71
|
+
"check:contrast": "node scripts/check-contrast.mjs",
|
|
70
72
|
"build": "npm run docs && vite build",
|
|
71
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
73
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && node scripts/component-count.mjs --check",
|
|
72
74
|
"dev": "vite dev",
|
|
73
|
-
"docs": "node scripts/extract-api.mjs",
|
|
75
|
+
"docs": "node scripts/extract-api.mjs && node scripts/component-count.mjs",
|
|
74
76
|
"package": "svelte-kit sync && svelte-package",
|
|
75
77
|
"package:all": "npm run package && npm run package --workspaces",
|
|
76
78
|
"preview": "vite preview",
|
|
79
|
+
"coverage:report": "node scripts/coverage-report.mjs",
|
|
77
80
|
"test": "playwright test",
|
|
81
|
+
"test:coverage": "rm -rf coverage && COVERAGE=1 playwright test && node scripts/coverage-report.mjs",
|
|
78
82
|
"test:quick": "playwright test tests/lib.spec.ts tests/inputs.spec.ts tests/misc.spec.ts"
|
|
79
83
|
},
|
|
80
84
|
"sideEffects": [
|
|
@@ -83,7 +87,7 @@
|
|
|
83
87
|
"svelte": "./dist/index.js",
|
|
84
88
|
"type": "module",
|
|
85
89
|
"types": "./dist/index.d.ts",
|
|
86
|
-
"version": "1.
|
|
90
|
+
"version": "1.4.0",
|
|
87
91
|
"workspaces": [
|
|
88
92
|
"packages/*"
|
|
89
93
|
]
|