@human-kit/svelte-components 1.0.0-alpha.15 → 1.0.0-alpha.17
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/dist/table/PLAN.md +6 -6
- package/dist/table/README.md +4 -2
- package/dist/table/body/table-body.svelte +5 -0
- package/dist/table/cell/table-cell.svelte +17 -0
- package/dist/table/checkbox/README.md +1 -1
- package/dist/table/checkbox/table-checkbox.svelte +2 -15
- package/dist/table/checkbox-indicator/README.md +1 -1
- package/dist/table/column/README.md +11 -11
- package/dist/table/column-header-cell/table-column-header-cell.svelte +19 -16
- package/dist/table/column-resizer/table-column-resizer-fixed-width-test.svelte +57 -0
- package/dist/table/column-resizer/table-column-resizer-fixed-width-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte +2 -1
- package/dist/table/column-resizer/table-column-resizer-overflow-test.svelte +64 -0
- package/dist/table/column-resizer/table-column-resizer-overflow-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-padded-container-test.svelte +67 -0
- package/dist/table/column-resizer/table-column-resizer-padded-container-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte +2 -1
- package/dist/table/column-resizer/table-column-resizer-test.svelte +3 -3
- package/dist/table/column-resizer/table-column-resizer-three-column-relative-test.svelte +64 -0
- package/dist/table/column-resizer/table-column-resizer-three-column-relative-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer.svelte +49 -56
- package/dist/table/root/README.md +12 -12
- package/dist/table/root/context.d.ts +13 -7
- package/dist/table/root/context.js +363 -38
- package/dist/table/root/table-root.svelte +116 -17
- package/dist/table/types.d.ts +4 -4
- package/dist/table/utils/visually-hidden-style.d.ts +1 -0
- package/dist/table/utils/visually-hidden-style.js +1 -0
- package/package.json +1 -1
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
shouldShowFocusVisible,
|
|
17
17
|
trackInteractionModality
|
|
18
18
|
} from '../../primitives/input-modality';
|
|
19
|
+
import { visuallyHiddenStyle } from '../utils/visually-hidden-style';
|
|
19
20
|
import type { TableRootProps } from '../types.js';
|
|
20
21
|
import {
|
|
21
22
|
createTableContext,
|
|
22
23
|
setTableContext,
|
|
24
|
+
type TableColumnWidth,
|
|
23
25
|
type TableSelectionKey,
|
|
24
26
|
type TableSortDescriptor
|
|
25
27
|
} from './context';
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
let focusVisible = $state(false);
|
|
60
62
|
let pendingControlledHiddenColumns = $state<string[] | null>(null);
|
|
61
63
|
let pendingControlledSelection = $state<Set<TableSelectionKey> | null>(null);
|
|
62
|
-
let pendingControlledColumnWidths = $state<Map<string,
|
|
64
|
+
let pendingControlledColumnWidths = $state<Map<string, TableColumnWidth> | null>(null);
|
|
63
65
|
let sortAnnouncement = $state('');
|
|
64
66
|
let hasObservedSortState = $state(false);
|
|
65
67
|
let hasInitializedSortSync = $state(false);
|
|
@@ -136,7 +138,10 @@
|
|
|
136
138
|
return true;
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
function hasSameColumnWidths(
|
|
141
|
+
function hasSameColumnWidths(
|
|
142
|
+
left: Map<string, TableColumnWidth>,
|
|
143
|
+
right: Map<string, TableColumnWidth>
|
|
144
|
+
) {
|
|
140
145
|
if (left.size !== right.size) return false;
|
|
141
146
|
for (const [key, value] of left) {
|
|
142
147
|
if (right.get(key) !== value) return false;
|
|
@@ -163,7 +168,52 @@
|
|
|
163
168
|
return ctx.hasResizableColumns();
|
|
164
169
|
});
|
|
165
170
|
|
|
171
|
+
const hasDefinedColumnWidths = $derived.by(() => {
|
|
172
|
+
void $layoutVersion;
|
|
173
|
+
for (let index = 0; index < ctx.getColumnCount(); index += 1) {
|
|
174
|
+
const column = ctx.getColumnAt(index);
|
|
175
|
+
if (!column || ctx.isColumnHidden(column.id)) continue;
|
|
176
|
+
if (column.width !== undefined || column.defaultWidth !== undefined) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return false;
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const layoutColumns = $derived.by(() => {
|
|
184
|
+
void $layoutVersion;
|
|
185
|
+
void $widthVersion;
|
|
186
|
+
|
|
187
|
+
const columns: Array<{
|
|
188
|
+
id: string;
|
|
189
|
+
width: number | undefined;
|
|
190
|
+
widthStyle: string | undefined;
|
|
191
|
+
implicitWidth: boolean;
|
|
192
|
+
minWidth: number | undefined;
|
|
193
|
+
maxWidth: number | undefined;
|
|
194
|
+
}> = [];
|
|
195
|
+
|
|
196
|
+
for (let index = 0; index < ctx.getColumnCount(); index += 1) {
|
|
197
|
+
const column = ctx.getColumnAt(index);
|
|
198
|
+
if (!column || ctx.isColumnHidden(column.id)) continue;
|
|
199
|
+
|
|
200
|
+
columns.push({
|
|
201
|
+
id: column.id,
|
|
202
|
+
width: ctx.getColumnWidth(column.id),
|
|
203
|
+
widthStyle: ctx.getColumnWidthStyle(column.id),
|
|
204
|
+
implicitWidth: !ctx.hasAuthoredColumnWidthSpec(column.id),
|
|
205
|
+
minWidth: ctx.getColumnMinWidth(column.id),
|
|
206
|
+
maxWidth: ctx.getColumnMaxWidth(column.id)
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return columns;
|
|
211
|
+
});
|
|
212
|
+
|
|
166
213
|
const explicitManagedTableWidth = $derived.by(() => {
|
|
214
|
+
void $layoutVersion;
|
|
215
|
+
if (ctx.hasRelativeVisibleColumnWidths()) return undefined;
|
|
216
|
+
|
|
167
217
|
const widths = columnWidths ?? defaultColumnWidths;
|
|
168
218
|
if (!widths) return undefined;
|
|
169
219
|
|
|
@@ -171,8 +221,10 @@
|
|
|
171
221
|
let hasAnyWidth = false;
|
|
172
222
|
for (const [columnId, width] of widths) {
|
|
173
223
|
if (ctx.isColumnHidden(columnId)) continue;
|
|
174
|
-
if (!
|
|
175
|
-
|
|
224
|
+
if (typeof width === 'string' && !width.trim().endsWith('px')) return undefined;
|
|
225
|
+
const numericWidth = typeof width === 'number' ? width : Number.parseFloat(width);
|
|
226
|
+
if (!Number.isFinite(numericWidth)) return undefined;
|
|
227
|
+
total += numericWidth;
|
|
176
228
|
hasAnyWidth = true;
|
|
177
229
|
}
|
|
178
230
|
|
|
@@ -182,16 +234,37 @@
|
|
|
182
234
|
const managedTableWidth = $derived.by(() => {
|
|
183
235
|
void $widthVersion;
|
|
184
236
|
void $layoutVersion;
|
|
185
|
-
|
|
186
|
-
const widths = ctx.getVisibleColumnWidths();
|
|
237
|
+
const widths = ctx.getResolvedVisibleColumnWidths();
|
|
187
238
|
const columnCount = ctx.getVisibleColumnCount();
|
|
188
239
|
if (widths.size === 0 || widths.size < columnCount) return undefined;
|
|
240
|
+
if (ctx.hasRelativeVisibleColumnWidths()) return undefined;
|
|
189
241
|
let total = 0;
|
|
190
242
|
for (const w of widths.values()) total += w;
|
|
191
243
|
return total;
|
|
192
244
|
});
|
|
193
245
|
|
|
194
|
-
const
|
|
246
|
+
const relativeResolvedTableWidth = $derived.by(() => {
|
|
247
|
+
void $widthVersion;
|
|
248
|
+
void $layoutVersion;
|
|
249
|
+
if (!ctx.hasRelativeVisibleColumnWidths()) return undefined;
|
|
250
|
+
|
|
251
|
+
const widths = ctx.getResolvedVisibleColumnWidths();
|
|
252
|
+
const columnCount = ctx.getVisibleColumnCount();
|
|
253
|
+
if (widths.size === 0 || widths.size < columnCount) return undefined;
|
|
254
|
+
|
|
255
|
+
let total = 0;
|
|
256
|
+
for (const w of widths.values()) total += w;
|
|
257
|
+
return total;
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const fallbackRelativeTableWidth = $derived.by(() => {
|
|
261
|
+
void $layoutVersion;
|
|
262
|
+
return ctx.hasRelativeVisibleColumnWidths() ? '100%' : undefined;
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const resolvedTableWidth = $derived(
|
|
266
|
+
managedTableWidth ?? explicitManagedTableWidth ?? relativeResolvedTableWidth
|
|
267
|
+
);
|
|
195
268
|
|
|
196
269
|
context = ctx;
|
|
197
270
|
|
|
@@ -368,8 +441,13 @@
|
|
|
368
441
|
bind:this={tableElement}
|
|
369
442
|
role="grid"
|
|
370
443
|
class={className}
|
|
371
|
-
style
|
|
372
|
-
style:
|
|
444
|
+
style:--table-visible-column-count={ariaColCount ? `${ariaColCount}` : undefined}
|
|
445
|
+
style:table-layout={hasResizable || hasDefinedColumnWidths || resolvedTableWidth !== undefined
|
|
446
|
+
? 'fixed'
|
|
447
|
+
: undefined}
|
|
448
|
+
style:width={resolvedTableWidth !== undefined
|
|
449
|
+
? `${resolvedTableWidth}px`
|
|
450
|
+
: fallbackRelativeTableWidth}
|
|
373
451
|
style:min-width={resolvedTableWidth !== undefined ? '0' : undefined}
|
|
374
452
|
aria-label={ariaLabel}
|
|
375
453
|
aria-labelledby={ariaLabelledby}
|
|
@@ -387,21 +465,42 @@
|
|
|
387
465
|
onkeydown={handleKeyDown}
|
|
388
466
|
{...restProps}
|
|
389
467
|
>
|
|
468
|
+
{#if layoutColumns.length > 0}
|
|
469
|
+
<colgroup>
|
|
470
|
+
{#each layoutColumns as column (column.id)}
|
|
471
|
+
<col
|
|
472
|
+
data-table-implicit-width={column.implicitWidth ? 'true' : undefined}
|
|
473
|
+
style:width={column.widthStyle}
|
|
474
|
+
style:min-width={column.minWidth !== undefined ? `${column.minWidth}px` : undefined}
|
|
475
|
+
style:max-width={column.maxWidth !== undefined ? `${column.maxWidth}px` : undefined}
|
|
476
|
+
/>
|
|
477
|
+
{/each}
|
|
478
|
+
</colgroup>
|
|
479
|
+
{/if}
|
|
480
|
+
|
|
390
481
|
{#if children}
|
|
391
482
|
{@render children()}
|
|
392
483
|
{/if}
|
|
393
484
|
</table>
|
|
394
485
|
|
|
395
|
-
<span
|
|
396
|
-
role="status"
|
|
397
|
-
aria-live="polite"
|
|
398
|
-
aria-atomic="true"
|
|
399
|
-
style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;"
|
|
486
|
+
<span role="status" aria-live="polite" aria-atomic="true" style={visuallyHiddenStyle}
|
|
400
487
|
>{sortAnnouncement}</span
|
|
401
488
|
>
|
|
402
489
|
|
|
403
|
-
<span
|
|
404
|
-
id={ctx.selectionUnavailableDescriptionId}
|
|
405
|
-
style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;"
|
|
490
|
+
<span id={ctx.selectionUnavailableDescriptionId} style={visuallyHiddenStyle}
|
|
406
491
|
>Selection unavailable for this row.</span
|
|
407
492
|
>
|
|
493
|
+
|
|
494
|
+
<style>
|
|
495
|
+
:global(table[role='grid']:has([data-table-column-resizer='true'])) {
|
|
496
|
+
table-layout: fixed;
|
|
497
|
+
width: 100%;
|
|
498
|
+
min-width: 0;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
:global(
|
|
502
|
+
table[role='grid']:has([data-table-column-resizer='true']) col[data-table-implicit-width='true']
|
|
503
|
+
) {
|
|
504
|
+
width: calc(100% / var(--table-visible-column-count, 1));
|
|
505
|
+
}
|
|
506
|
+
</style>
|
package/dist/table/types.d.ts
CHANGED
|
@@ -35,16 +35,16 @@ export type TableRootProps = Omit<HTMLAttributes<HTMLTableElement>, 'children'>
|
|
|
35
35
|
defaultSelectedKeys?: Iterable<TableSelectionKey>;
|
|
36
36
|
sortDescriptor?: TableSortDescriptor;
|
|
37
37
|
defaultSortDescriptor?: TableSortDescriptor;
|
|
38
|
-
columnWidths?: Map<string,
|
|
39
|
-
defaultColumnWidths?: Iterable<readonly [string,
|
|
38
|
+
columnWidths?: Map<string, TableColumnWidth>;
|
|
39
|
+
defaultColumnWidths?: Iterable<readonly [string, TableColumnWidth]>;
|
|
40
40
|
disabledKeys?: Iterable<TableSelectionKey>;
|
|
41
41
|
onRowAction?: TableRowActionHandler;
|
|
42
42
|
onSelectionChange?: (keys: Set<TableSelectionKey>) => void;
|
|
43
43
|
onSortChange?: (descriptor: TableSortDescriptor | undefined) => void;
|
|
44
|
-
onColumnWidthsChange?: (widths: Map<string,
|
|
44
|
+
onColumnWidthsChange?: (widths: Map<string, TableColumnWidth>) => void;
|
|
45
45
|
onHiddenColumnsChange?: (columnIds: string[]) => void;
|
|
46
46
|
onColumnResizeStart?: (columnId: string) => void;
|
|
47
|
-
onColumnResizeEnd?: (widths: Map<string,
|
|
47
|
+
onColumnResizeEnd?: (widths: Map<string, TableColumnWidth>) => void;
|
|
48
48
|
children?: Snippet;
|
|
49
49
|
class?: string;
|
|
50
50
|
context?: TableContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const visuallyHiddenStyle = "position:fixed;top:0;left:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const visuallyHiddenStyle = 'position:fixed;top:0;left:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;';
|