@human-kit/svelte-components 1.0.0-alpha.16 → 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.
Files changed (27) hide show
  1. package/dist/table/PLAN.md +6 -6
  2. package/dist/table/README.md +4 -2
  3. package/dist/table/body/table-body.svelte +5 -0
  4. package/dist/table/cell/table-cell.svelte +17 -0
  5. package/dist/table/checkbox/README.md +1 -1
  6. package/dist/table/checkbox/table-checkbox.svelte +2 -15
  7. package/dist/table/checkbox-indicator/README.md +1 -1
  8. package/dist/table/column/README.md +11 -11
  9. package/dist/table/column-header-cell/table-column-header-cell.svelte +19 -16
  10. package/dist/table/column-resizer/table-column-resizer-fixed-width-test.svelte +57 -0
  11. package/dist/table/column-resizer/table-column-resizer-fixed-width-test.svelte.d.ts +3 -0
  12. package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte +2 -1
  13. package/dist/table/column-resizer/table-column-resizer-overflow-test.svelte +64 -0
  14. package/dist/table/column-resizer/table-column-resizer-overflow-test.svelte.d.ts +3 -0
  15. package/dist/table/column-resizer/table-column-resizer-padded-container-test.svelte +67 -0
  16. package/dist/table/column-resizer/table-column-resizer-padded-container-test.svelte.d.ts +3 -0
  17. package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte +2 -1
  18. package/dist/table/column-resizer/table-column-resizer-test.svelte +3 -3
  19. package/dist/table/column-resizer/table-column-resizer-three-column-relative-test.svelte +64 -0
  20. package/dist/table/column-resizer/table-column-resizer-three-column-relative-test.svelte.d.ts +3 -0
  21. package/dist/table/column-resizer/table-column-resizer.svelte +47 -54
  22. package/dist/table/root/README.md +12 -12
  23. package/dist/table/root/context.d.ts +13 -7
  24. package/dist/table/root/context.js +363 -38
  25. package/dist/table/root/table-root.svelte +113 -9
  26. package/dist/table/types.d.ts +4 -4
  27. package/package.json +1 -1
@@ -21,6 +21,7 @@
21
21
  import {
22
22
  createTableContext,
23
23
  setTableContext,
24
+ type TableColumnWidth,
24
25
  type TableSelectionKey,
25
26
  type TableSortDescriptor
26
27
  } from './context';
@@ -60,7 +61,7 @@
60
61
  let focusVisible = $state(false);
61
62
  let pendingControlledHiddenColumns = $state<string[] | null>(null);
62
63
  let pendingControlledSelection = $state<Set<TableSelectionKey> | null>(null);
63
- let pendingControlledColumnWidths = $state<Map<string, number> | null>(null);
64
+ let pendingControlledColumnWidths = $state<Map<string, TableColumnWidth> | null>(null);
64
65
  let sortAnnouncement = $state('');
65
66
  let hasObservedSortState = $state(false);
66
67
  let hasInitializedSortSync = $state(false);
@@ -137,7 +138,10 @@
137
138
  return true;
138
139
  }
139
140
 
140
- function hasSameColumnWidths(left: Map<string, number>, right: Map<string, number>) {
141
+ function hasSameColumnWidths(
142
+ left: Map<string, TableColumnWidth>,
143
+ right: Map<string, TableColumnWidth>
144
+ ) {
141
145
  if (left.size !== right.size) return false;
142
146
  for (const [key, value] of left) {
143
147
  if (right.get(key) !== value) return false;
@@ -164,7 +168,52 @@
164
168
  return ctx.hasResizableColumns();
165
169
  });
166
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
+
167
213
  const explicitManagedTableWidth = $derived.by(() => {
214
+ void $layoutVersion;
215
+ if (ctx.hasRelativeVisibleColumnWidths()) return undefined;
216
+
168
217
  const widths = columnWidths ?? defaultColumnWidths;
169
218
  if (!widths) return undefined;
170
219
 
@@ -172,8 +221,10 @@
172
221
  let hasAnyWidth = false;
173
222
  for (const [columnId, width] of widths) {
174
223
  if (ctx.isColumnHidden(columnId)) continue;
175
- if (!Number.isFinite(width)) continue;
176
- total += width;
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;
177
228
  hasAnyWidth = true;
178
229
  }
179
230
 
@@ -183,16 +234,37 @@
183
234
  const managedTableWidth = $derived.by(() => {
184
235
  void $widthVersion;
185
236
  void $layoutVersion;
186
- if (!hasResizable) return undefined;
187
- const widths = ctx.getVisibleColumnWidths();
237
+ const widths = ctx.getResolvedVisibleColumnWidths();
188
238
  const columnCount = ctx.getVisibleColumnCount();
189
239
  if (widths.size === 0 || widths.size < columnCount) return undefined;
240
+ if (ctx.hasRelativeVisibleColumnWidths()) return undefined;
190
241
  let total = 0;
191
242
  for (const w of widths.values()) total += w;
192
243
  return total;
193
244
  });
194
245
 
195
- const resolvedTableWidth = $derived(managedTableWidth ?? explicitManagedTableWidth);
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
+ );
196
268
 
197
269
  context = ctx;
198
270
 
@@ -369,8 +441,13 @@
369
441
  bind:this={tableElement}
370
442
  role="grid"
371
443
  class={className}
372
- style:table-layout={hasResizable || resolvedTableWidth !== undefined ? 'fixed' : undefined}
373
- style:width={resolvedTableWidth !== undefined ? `${resolvedTableWidth}px` : undefined}
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}
374
451
  style:min-width={resolvedTableWidth !== undefined ? '0' : undefined}
375
452
  aria-label={ariaLabel}
376
453
  aria-labelledby={ariaLabelledby}
@@ -388,6 +465,19 @@
388
465
  onkeydown={handleKeyDown}
389
466
  {...restProps}
390
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
+
391
481
  {#if children}
392
482
  {@render children()}
393
483
  {/if}
@@ -400,3 +490,17 @@
400
490
  <span id={ctx.selectionUnavailableDescriptionId} style={visuallyHiddenStyle}
401
491
  >Selection unavailable for this row.</span
402
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>
@@ -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, number>;
39
- defaultColumnWidths?: Iterable<readonly [string, number]>;
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, number>) => void;
44
+ onColumnWidthsChange?: (widths: Map<string, TableColumnWidth>) => void;
45
45
  onHiddenColumnsChange?: (columnIds: string[]) => void;
46
46
  onColumnResizeStart?: (columnId: string) => void;
47
- onColumnResizeEnd?: (widths: Map<string, number>) => void;
47
+ onColumnResizeEnd?: (widths: Map<string, TableColumnWidth>) => void;
48
48
  children?: Snippet;
49
49
  class?: string;
50
50
  context?: TableContext;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@human-kit/svelte-components",
3
- "version": "1.0.0-alpha.16",
3
+ "version": "1.0.0-alpha.17",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",