@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
@@ -911,7 +911,7 @@ Minimum regression coverage:
911
911
 
912
912
  ## Phase 3: Row Actions and Disabled Behavior Plan
913
913
 
914
- ### Goal
914
+ ### Phase 3 Goal
915
915
 
916
916
  Add row actions in a way that matches the React Aria Components mental model closely enough for consumers to predict behavior, while still fitting the existing `Table` architecture in this repository:
917
917
 
@@ -936,7 +936,7 @@ The goal is functional parity for the supported cases, not a byte-for-byte clone
936
936
 
937
937
  ### Public API Recommendation
938
938
 
939
- #### `Table.Root`
939
+ #### `Table.Root` Props
940
940
 
941
941
  Add the following props:
942
942
 
@@ -970,7 +970,7 @@ Reasons:
970
970
  - React Aria already establishes a recognizable interaction contract based on those inputs
971
971
  - a separate `rowPressBehavior` prop would create redundant states and undocumented invalid combinations
972
972
 
973
- ### Interaction Model
973
+ ### Phase 3 Interaction Model
974
974
 
975
975
  #### Core Principle
976
976
 
@@ -1163,7 +1163,7 @@ The coordinator should decide behavior using:
1163
1163
 
1164
1164
  ### Affected Parts
1165
1165
 
1166
- #### `root/context.ts`
1166
+ #### `root/context.ts` Changes
1167
1167
 
1168
1168
  Will need to own:
1169
1169
 
@@ -1278,7 +1278,7 @@ This is important because reusing the current all-or-nothing `aria-disabled` con
1278
1278
  | `single` / `multiple` | no | existing selection behavior | existing selection behavior |
1279
1279
  | `single` / `multiple` | yes | action | selection |
1280
1280
 
1281
- ### Testing Plan
1281
+ ### Phase 3 Testing Plan
1282
1282
 
1283
1283
  Minimum regression coverage:
1284
1284
 
@@ -1320,7 +1320,7 @@ This phase should not attempt to solve:
1320
1320
 
1321
1321
  These can be revisited later, but they should not block the collection-level row action API.
1322
1322
 
1323
- ### Recommended Implementation Order
1323
+ ### Phase 3 Recommended Implementation Order
1324
1324
 
1325
1325
  1. Add `onRowAction` and `disabledBehavior` to `Table.Root` and root context.
1326
1326
  2. Refactor disabled-state helpers into selection-vs-action-aware logic.
@@ -90,8 +90,10 @@ All public Table part prop types are exported from the table barrel, including `
90
90
  - Use `defaultSortDescriptor` for uncontrolled initial sort state.
91
91
  - Use `hiddenColumns` for controlled column visibility when consumers need to show or hide columns without changing the table markup.
92
92
  - Use `defaultHiddenColumns` for uncontrolled initial column visibility.
93
- - Use `columnWidths` / `onColumnWidthsChange` for controlled column width state.
94
- - Use `defaultColumnWidths`, `Table.Column.defaultWidth`, and `Table.Column.width` to seed explicit widths.
93
+ - Use `columnWidths` / `onColumnWidthsChange` for controlled column width state. Width specs can be px, `%`, or `fr`.
94
+ - Use `defaultColumnWidths` and `Table.Column.defaultWidth` to seed uncontrolled initial widths that can still be resized by the user.
95
+ - Use `Table.Column.width` when a column should stay fixed at an explicit width. Fixed-width columns ignore resize attempts even if a `Table.ColumnResizer` is composed.
96
+ - In resizable tables, unspecified columns behave like an implicit `1fr` width before interaction. On the first real resize, visible columns are materialized to px; the trailing column absorbs the delta until its minimum width, and further growth overflows the table horizontally.
95
97
  - Setting `sortDescriptor` back to `undefined` clears the controlled sort state, matching React Aria Table semantics.
96
98
  - Set `Table.Column.textValue` when the spoken column label should differ from the column id; `Table.Root` uses it for polite sort announcements.
97
99
  - Use `Table.EmptyState` inside `Table.Body` instead of conditionally rendering freeform body content.
@@ -6,6 +6,11 @@
6
6
  setTableSectionContext({ section: 'body' });
7
7
  const table = useTableContext();
8
8
  const layoutVersion = table.layoutVersion;
9
+
10
+ $effect(() => {
11
+ table.markBodyRowsInitialized();
12
+ });
13
+
9
14
  const isEmpty = $derived.by(() => {
10
15
  void $layoutVersion;
11
16
  return table.getBodyRowCount() === 0;
@@ -21,6 +21,7 @@
21
21
  const layoutVersion = table.layoutVersion;
22
22
  const focusVersion = table.focusVersion;
23
23
  const selectionVersion = table.selectionVersion;
24
+ const widthVersion = table.widthVersion;
24
25
  const cellOrderVersion = row.cellOrderVersion;
25
26
 
26
27
  let element = $state<HTMLElement | undefined>(undefined);
@@ -82,6 +83,18 @@
82
83
  void $layoutVersion;
83
84
  return column ? table.getVisibleColumnIndexByToken(column.token) : -1;
84
85
  });
86
+ const columnWidthStyle = $derived.by(() => {
87
+ void $widthVersion;
88
+ return column ? table.getColumnWidthStyle(column.id) : undefined;
89
+ });
90
+ const columnMinWidth = $derived.by(() => {
91
+ void $widthVersion;
92
+ return column ? table.getColumnMinWidth(column.id) : undefined;
93
+ });
94
+ const columnMaxWidth = $derived.by(() => {
95
+ void $widthVersion;
96
+ return column ? table.getColumnMaxWidth(column.id) : undefined;
97
+ });
85
98
  const tagName = $derived(row.section === 'body' && column?.isRowHeader ? 'th' : 'td');
86
99
  const role = $derived.by(() => {
87
100
  if (isColumnHidden) return undefined;
@@ -234,6 +247,10 @@
234
247
  : undefined}
235
248
  data-disabled={isRowDisabled || undefined}
236
249
  data-column-index={visibleColumnIndex >= 0 ? visibleColumnIndex : undefined}
250
+ style:box-sizing="border-box"
251
+ style:width={columnWidthStyle}
252
+ style:min-width={columnMinWidth !== undefined ? `${columnMinWidth}px` : undefined}
253
+ style:max-width={columnMaxWidth !== undefined ? `${columnMaxWidth}px` : undefined}
237
254
  style:display={isColumnHidden ? 'none' : undefined}
238
255
  onfocus={row.section === 'body' ? handleFocus : undefined}
239
256
  onclick={row.section === 'body' ? handleClick : undefined}
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## API reference
4
4
 
5
- ### Table.Checkbox
5
+ ### Checkbox Part
6
6
 
7
7
  Name: `Table.Checkbox`
8
8
  Description: Headless selection-aware checkbox root for tables. In body cells it toggles the owning row. In header cells it becomes a select-all checkbox for multiple selection mode.
@@ -30,8 +30,6 @@
30
30
  const layoutVersion = table.layoutVersion;
31
31
 
32
32
  let checkboxElement = $state<HTMLSpanElement | null>(null);
33
- let checkboxChecked = $state(false);
34
- let checkboxIndeterminate = $state(false);
35
33
 
36
34
  const isVisible = $derived.by(() => {
37
35
  if (table.selectionMode === 'none') return false;
@@ -85,17 +83,6 @@
85
83
  return checkboxElement ?? undefined;
86
84
  }
87
85
 
88
- $effect(() => {
89
- void $selectionVersion;
90
- checkboxChecked = isChecked;
91
- });
92
-
93
- $effect(() => {
94
- void $selectionVersion;
95
- void $layoutVersion;
96
- checkboxIndeterminate = isIndeterminate;
97
- });
98
-
99
86
  $effect(() => {
100
87
  if (!isVisible || isDisabled) {
101
88
  cell.unregisterFocusDelegate();
@@ -260,8 +247,8 @@
260
247
  <Checkbox.Root
261
248
  {id}
262
249
  bind:element={checkboxElement}
263
- bind:isChecked={checkboxChecked}
264
- bind:isIndeterminate={checkboxIndeterminate}
250
+ {isChecked}
251
+ {isIndeterminate}
265
252
  {isDisabled}
266
253
  onCheckedChange={applySelection}
267
254
  {title}
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## API reference
4
4
 
5
- ### Table.CheckboxIndicator
5
+ ### Indicator Part
6
6
 
7
7
  Name: `Table.CheckboxIndicator`
8
8
  Description: Headless presence wrapper for indicator content inside `Table.Checkbox`. It renders when the checkbox is checked or indeterminate.
@@ -11,17 +11,17 @@ Description: Logical metadata wrapper for a header column. It does not render DO
11
11
 
12
12
  Public prop type: `TableColumnProps`
13
13
 
14
- | Prop | Type | Default | Description |
15
- | --------------- | --------------------------- | ----------- | ------------------------------------------------------------------------------------------------- |
16
- | `id` | `string` | `-` | Stable identifier for the column. |
17
- | `allowsSorting` | `boolean` | `false` | Enables sorting for the wrapped header cell. |
18
- | `isRowHeader` | `boolean` | `false` | Marks the associated body column as row-header cells. |
19
- | `textValue` | `string` | `undefined` | Optional spoken label used by `Table.Root` sort announcements when it should differ from `id`. |
20
- | `width` | `number \| \`${number}px\`` | `undefined` | Explicit column width hint. Px numbers are the first-class format for the current resize release. |
21
- | `defaultWidth` | `number \| \`${number}px\`` | `undefined` | Uncontrolled initial width hint for the column. |
22
- | `minWidth` | `number` | `undefined` | Minimum width in px enforced during resize interactions. |
23
- | `maxWidth` | `number` | `undefined` | Maximum width in px enforced during resize interactions. |
24
- | `children` | `Snippet` | `undefined` | Usually a single `Table.ColumnHeaderCell`. |
14
+ | Prop | Type | Default | Description |
15
+ | --------------- | --------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------- |
16
+ | `id` | `string` | `-` | Stable identifier for the column. |
17
+ | `allowsSorting` | `boolean` | `false` | Enables sorting for the wrapped header cell. |
18
+ | `isRowHeader` | `boolean` | `false` | Marks the associated body column as row-header cells. |
19
+ | `textValue` | `string` | `undefined` | Optional spoken label used by `Table.Root` sort announcements when it should differ from `id`. |
20
+ | `width` | `number \| \`${number}px\`` | `undefined` | Fixed column width. When set, the column keeps that width and user resize interactions are disabled. |
21
+ | `defaultWidth` | `number \| \`${number}px\`` | `undefined` | Uncontrolled initial width hint for the column. The column remains user-resizable when a resizer is composed. |
22
+ | `minWidth` | `number` | `undefined` | Minimum width in px enforced during resize interactions. |
23
+ | `maxWidth` | `number` | `undefined` | Maximum width in px enforced during resize interactions. |
24
+ | `children` | `Snippet` | `undefined` | Usually a single `Table.ColumnHeaderCell`. |
25
25
 
26
26
  `Table.ColumnResizer` is the public resize opt-in. Compose it inside `Table.ColumnHeaderCell` when the owning column should be resizable.
27
27
 
@@ -93,10 +93,17 @@
93
93
  void $layoutVersion;
94
94
  return column.isHidden;
95
95
  });
96
-
97
- const columnWidth = $derived.by(() => {
96
+ const columnWidthStyle = $derived.by(() => {
97
+ void $widthVersion;
98
+ return table.getColumnWidthStyle(column.id);
99
+ });
100
+ const columnMinWidth = $derived.by(() => {
101
+ void $widthVersion;
102
+ return table.getColumnMinWidth(column.id);
103
+ });
104
+ const columnMaxWidth = $derived.by(() => {
98
105
  void $widthVersion;
99
- return table.getColumnWidth(column.id);
106
+ return table.getColumnMaxWidth(column.id);
100
107
  });
101
108
  const visibleColumnIndex = $derived.by(() => {
102
109
  void $layoutVersion;
@@ -249,7 +256,12 @@
249
256
  data-sortable={column.allowsSorting || undefined}
250
257
  data-sort-direction={sortDirection}
251
258
  data-column-index={visibleColumnIndex >= 0 ? visibleColumnIndex : undefined}
252
- style:width={columnWidth !== undefined ? `${columnWidth}px` : undefined}
259
+ style:box-sizing="border-box"
260
+ style:position="relative"
261
+ style:overflow="visible"
262
+ style:width={columnWidthStyle}
263
+ style:min-width={columnMinWidth !== undefined ? `${columnMinWidth}px` : undefined}
264
+ style:max-width={columnMaxWidth !== undefined ? `${columnMaxWidth}px` : undefined}
253
265
  style:display={isHidden ? 'none' : undefined}
254
266
  onfocusin={handleFocusIn}
255
267
  onfocusout={handleFocusOut}
@@ -260,16 +272,7 @@
260
272
  onkeydown={handleKeyDown}
261
273
  {...restProps}
262
274
  >
263
- <div
264
- data-table-header-content
265
- style:overflow="visible"
266
- style:position="relative"
267
- style:min-width="0"
268
- style:width="100%"
269
- style:height="100%"
270
- >
271
- {#if children}
272
- {@render children()}
273
- {/if}
274
- </div>
275
+ {#if children}
276
+ {@render children()}
277
+ {/if}
275
278
  </th>
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
4
+
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth>>(new Map());
6
+ </script>
7
+
8
+ <Table.Root aria-label="Fixed width table" bind:columnWidths={currentColumnWidths}>
9
+ <Table.Header>
10
+ <Table.Row>
11
+ <Table.Column
12
+ id="email"
13
+ isRowHeader
14
+ textValue="Email"
15
+ width={220}
16
+ minWidth={220}
17
+ maxWidth={220}
18
+ >
19
+ <Table.ColumnHeaderCell>
20
+ <div class="flex items-center justify-between gap-3">
21
+ <span>Email</span>
22
+ <Table.ColumnResizer
23
+ data-testid="fixed-email-resizer"
24
+ class="inline-flex w-3 cursor-col-resize justify-center"
25
+ />
26
+ </div>
27
+ </Table.ColumnHeaderCell>
28
+ </Table.Column>
29
+ <Table.Column id="role" textValue="Role" defaultWidth={180} minWidth={120}>
30
+ <Table.ColumnHeaderCell>
31
+ <div class="flex items-center justify-between gap-3">
32
+ <span>Role</span>
33
+ <Table.ColumnResizer
34
+ data-testid="role-resizer"
35
+ class="inline-flex w-3 cursor-col-resize justify-center"
36
+ />
37
+ </div>
38
+ </Table.ColumnHeaderCell>
39
+ </Table.Column>
40
+ </Table.Row>
41
+ </Table.Header>
42
+
43
+ <Table.Body>
44
+ <Table.Row id="danilo">
45
+ <Table.Cell>danilo.fernandez+workspace-owner@example.com</Table.Cell>
46
+ <Table.Cell>Developer</Table.Cell>
47
+ </Table.Row>
48
+ <Table.Row id="zahra">
49
+ <Table.Cell>zahra@example.com</Table.Cell>
50
+ <Table.Cell>Admin</Table.Cell>
51
+ </Table.Row>
52
+ </Table.Body>
53
+ </Table.Root>
54
+
55
+ <output data-testid="column-widths"
56
+ >{JSON.stringify(Object.fromEntries(currentColumnWidths))}</output
57
+ >
@@ -0,0 +1,3 @@
1
+ declare const TableColumnResizerFixedWidthTest: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TableColumnResizerFixedWidthTest = ReturnType<typeof TableColumnResizerFixedWidthTest>;
3
+ export default TableColumnResizerFixedWidthTest;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
3
4
 
4
- let currentColumnWidths = $state<Map<string, number> | undefined>(undefined);
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth> | undefined>(undefined);
5
6
  </script>
6
7
 
7
8
  <div style="width: 640px;">
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
4
+
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth> | undefined>(undefined);
6
+ </script>
7
+
8
+ <div style="width: 640px; overflow-x: auto;">
9
+ <Table.Root
10
+ aria-label="Resizable overflow table"
11
+ bind:columnWidths={currentColumnWidths}
12
+ class="min-w-full border-collapse text-left"
13
+ >
14
+ <Table.Header>
15
+ <Table.Row>
16
+ <Table.Column id="name" isRowHeader textValue="Name" width={240}>
17
+ <Table.ColumnHeaderCell data-testid="overflow-name-header-cell">
18
+ <div class="flex items-center justify-between gap-3">
19
+ <span>Name</span>
20
+ <Table.ColumnResizer
21
+ data-testid="overflow-name-resizer"
22
+ class="inline-flex w-3 cursor-col-resize justify-center"
23
+ />
24
+ </div>
25
+ </Table.ColumnHeaderCell>
26
+ </Table.Column>
27
+ <Table.Column id="region" textValue="Region" defaultWidth={180} minWidth={140}>
28
+ <Table.ColumnHeaderCell data-testid="overflow-region-header-cell">
29
+ <div class="flex items-center justify-between gap-3">
30
+ <span>Region</span>
31
+ <Table.ColumnResizer
32
+ data-testid="overflow-region-resizer"
33
+ class="inline-flex w-3 cursor-col-resize justify-center"
34
+ />
35
+ </div>
36
+ </Table.ColumnHeaderCell>
37
+ </Table.Column>
38
+ <Table.Column id="plan" textValue="Plan">
39
+ <Table.ColumnHeaderCell data-testid="overflow-plan-header-cell">
40
+ <div class="flex items-center justify-between gap-3">
41
+ <span>Plan</span>
42
+ <Table.ColumnResizer
43
+ data-testid="overflow-plan-resizer"
44
+ class="inline-flex w-3 cursor-col-resize justify-center"
45
+ />
46
+ </div>
47
+ </Table.ColumnHeaderCell>
48
+ </Table.Column>
49
+ </Table.Row>
50
+ </Table.Header>
51
+
52
+ <Table.Body>
53
+ <Table.Row id="danilo">
54
+ <Table.Cell>Danilo Fernandez</Table.Cell>
55
+ <Table.Cell>Buenos Aires</Table.Cell>
56
+ <Table.Cell>Enterprise</Table.Cell>
57
+ </Table.Row>
58
+ </Table.Body>
59
+ </Table.Root>
60
+ </div>
61
+
62
+ <output data-testid="overflow-column-widths"
63
+ >{JSON.stringify(Object.fromEntries(currentColumnWidths ?? new Map()))}</output
64
+ >
@@ -0,0 +1,3 @@
1
+ declare const TableColumnResizerOverflowTest: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TableColumnResizerOverflowTest = ReturnType<typeof TableColumnResizerOverflowTest>;
3
+ export default TableColumnResizerOverflowTest;
@@ -0,0 +1,67 @@
1
+ <script lang="ts">
2
+ import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
4
+
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth> | undefined>(undefined);
6
+ </script>
7
+
8
+ <div
9
+ data-testid="padded-relative-container"
10
+ style="width: 640px; box-sizing: border-box; overflow-x: auto; padding: 12px; border: 1px solid transparent;"
11
+ >
12
+ <Table.Root
13
+ aria-label="Padded relative resize table"
14
+ bind:columnWidths={currentColumnWidths}
15
+ class="min-w-full border-collapse text-left"
16
+ >
17
+ <Table.Header>
18
+ <Table.Row>
19
+ <Table.Column id="name" isRowHeader textValue="Name">
20
+ <Table.ColumnHeaderCell data-testid="padded-name-header-cell">
21
+ <div class="flex items-center justify-between gap-3">
22
+ <span>Name</span>
23
+ <Table.ColumnResizer
24
+ data-testid="padded-name-resizer"
25
+ class="inline-flex w-3 cursor-col-resize justify-center"
26
+ />
27
+ </div>
28
+ </Table.ColumnHeaderCell>
29
+ </Table.Column>
30
+ <Table.Column id="region" textValue="Region" defaultWidth={180} minWidth={140}>
31
+ <Table.ColumnHeaderCell data-testid="padded-region-header-cell">
32
+ <div class="flex items-center justify-between gap-3">
33
+ <span>Region</span>
34
+ <Table.ColumnResizer
35
+ data-testid="padded-region-resizer"
36
+ class="inline-flex w-3 cursor-col-resize justify-center"
37
+ />
38
+ </div>
39
+ </Table.ColumnHeaderCell>
40
+ </Table.Column>
41
+ <Table.Column id="plan" textValue="Plan">
42
+ <Table.ColumnHeaderCell data-testid="padded-plan-header-cell">
43
+ <div class="flex items-center justify-between gap-3">
44
+ <span>Plan</span>
45
+ <Table.ColumnResizer
46
+ data-testid="padded-plan-resizer"
47
+ class="inline-flex w-3 cursor-col-resize justify-center"
48
+ />
49
+ </div>
50
+ </Table.ColumnHeaderCell>
51
+ </Table.Column>
52
+ </Table.Row>
53
+ </Table.Header>
54
+
55
+ <Table.Body>
56
+ <Table.Row id="danilo">
57
+ <Table.Cell>Danilo Fernandez</Table.Cell>
58
+ <Table.Cell>Buenos Aires</Table.Cell>
59
+ <Table.Cell>Enterprise</Table.Cell>
60
+ </Table.Row>
61
+ </Table.Body>
62
+ </Table.Root>
63
+ </div>
64
+
65
+ <output data-testid="padded-relative-widths"
66
+ >{JSON.stringify(Object.fromEntries(currentColumnWidths ?? new Map()))}</output
67
+ >
@@ -0,0 +1,3 @@
1
+ declare const TableColumnResizerPaddedContainerTest: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TableColumnResizerPaddedContainerTest = ReturnType<typeof TableColumnResizerPaddedContainerTest>;
3
+ export default TableColumnResizerPaddedContainerTest;
@@ -1,7 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
3
4
 
4
- let currentColumnWidths = $state<Map<string, number> | undefined>(undefined);
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth> | undefined>(undefined);
5
6
 
6
7
  const checkboxStyle =
7
8
  'display:inline-flex;height:20px;width:20px;align-items:center;justify-content:center;border:1px solid currentColor;border-radius:4px;';
@@ -1,8 +1,8 @@
1
1
  <script lang="ts">
2
2
  import { Table } from '../index';
3
- import type { TableSortDescriptor } from '../root/context';
3
+ import type { TableColumnWidth, TableSortDescriptor } from '../root/context';
4
4
 
5
- let currentColumnWidths = $state<Map<string, number>>(
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth>>(
6
6
  new Map([
7
7
  ['email', 200],
8
8
  ['group', 160]
@@ -10,7 +10,7 @@
10
10
  );
11
11
  let currentSortDescriptor = $state<TableSortDescriptor | undefined>(undefined);
12
12
  let resizeStartColumnId = $state('');
13
- let resizeEndWidths = $state<Record<string, number>>({});
13
+ let resizeEndWidths = $state<Record<string, TableColumnWidth>>({});
14
14
  </script>
15
15
 
16
16
  <Table.Root
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ import { Table } from '../index';
3
+ import type { TableColumnWidth } from '../root/context';
4
+
5
+ let currentColumnWidths = $state<Map<string, TableColumnWidth> | undefined>(undefined);
6
+ </script>
7
+
8
+ <div data-testid="three-column-relative-container" style="width: 640px; overflow-x: auto;">
9
+ <Table.Root
10
+ aria-label="Three column relative resize table"
11
+ bind:columnWidths={currentColumnWidths}
12
+ class="min-w-full border-collapse text-left"
13
+ >
14
+ <Table.Header>
15
+ <Table.Row>
16
+ <Table.Column id="name" isRowHeader textValue="Name">
17
+ <Table.ColumnHeaderCell data-testid="three-column-name-header-cell">
18
+ <div class="flex items-center justify-between gap-3">
19
+ <span>Name</span>
20
+ <Table.ColumnResizer
21
+ data-testid="three-column-name-resizer"
22
+ class="inline-flex w-3 cursor-col-resize justify-center"
23
+ />
24
+ </div>
25
+ </Table.ColumnHeaderCell>
26
+ </Table.Column>
27
+ <Table.Column id="region" textValue="Region" defaultWidth={180} minWidth={140}>
28
+ <Table.ColumnHeaderCell data-testid="three-column-region-header-cell">
29
+ <div class="flex items-center justify-between gap-3">
30
+ <span>Region</span>
31
+ <Table.ColumnResizer
32
+ data-testid="three-column-region-resizer"
33
+ class="inline-flex w-3 cursor-col-resize justify-center"
34
+ />
35
+ </div>
36
+ </Table.ColumnHeaderCell>
37
+ </Table.Column>
38
+ <Table.Column id="plan" textValue="Plan">
39
+ <Table.ColumnHeaderCell data-testid="three-column-plan-header-cell">
40
+ <div class="flex items-center justify-between gap-3">
41
+ <span>Plan</span>
42
+ <Table.ColumnResizer
43
+ data-testid="three-column-plan-resizer"
44
+ class="inline-flex w-3 cursor-col-resize justify-center"
45
+ />
46
+ </div>
47
+ </Table.ColumnHeaderCell>
48
+ </Table.Column>
49
+ </Table.Row>
50
+ </Table.Header>
51
+
52
+ <Table.Body>
53
+ <Table.Row id="danilo">
54
+ <Table.Cell>Danilo Fernandez</Table.Cell>
55
+ <Table.Cell>Buenos Aires</Table.Cell>
56
+ <Table.Cell>Enterprise</Table.Cell>
57
+ </Table.Row>
58
+ </Table.Body>
59
+ </Table.Root>
60
+ </div>
61
+
62
+ <output data-testid="three-column-relative-widths"
63
+ >{JSON.stringify(Object.fromEntries(currentColumnWidths ?? new Map()))}</output
64
+ >
@@ -0,0 +1,3 @@
1
+ declare const TableColumnResizerThreeColumnRelativeTest: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type TableColumnResizerThreeColumnRelativeTest = ReturnType<typeof TableColumnResizerThreeColumnRelativeTest>;
3
+ export default TableColumnResizerThreeColumnRelativeTest;