@human-kit/svelte-components 1.0.0-alpha.13 → 1.0.0-alpha.15

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 (57) hide show
  1. package/dist/checkbox/root/checkbox-root.svelte +22 -2
  2. package/dist/checkbox/root/checkbox-root.svelte.d.ts +4 -1
  3. package/dist/combobox/root/combobox.svelte +1 -0
  4. package/dist/listbox/item/listbox-item.svelte +13 -0
  5. package/dist/listbox/root/listbox.svelte +7 -1
  6. package/dist/table/IMPLEMENTATION_NOTES.md +2 -1
  7. package/dist/table/PLAN.md +445 -33
  8. package/dist/table/README.md +11 -0
  9. package/dist/table/TODO.md +40 -2
  10. package/dist/table/body/README.md +2 -0
  11. package/dist/table/body/table-body.svelte +1 -7
  12. package/dist/table/body/table-body.svelte.d.ts +1 -6
  13. package/dist/table/cell/README.md +2 -0
  14. package/dist/table/cell/table-cell.svelte +87 -86
  15. package/dist/table/cell/table-cell.svelte.d.ts +1 -6
  16. package/dist/table/checkbox/README.md +2 -0
  17. package/dist/table/checkbox/table-checkbox-test.svelte +7 -0
  18. package/dist/table/checkbox/table-checkbox-test.svelte.d.ts +3 -1
  19. package/dist/table/checkbox/table-checkbox.svelte +56 -52
  20. package/dist/table/checkbox/table-checkbox.svelte.d.ts +1 -10
  21. package/dist/table/checkbox-indicator/README.md +2 -0
  22. package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte +1 -8
  23. package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte.d.ts +1 -7
  24. package/dist/table/column/README.md +17 -14
  25. package/dist/table/column/table-column.svelte +2 -26
  26. package/dist/table/column/table-column.svelte.d.ts +1 -15
  27. package/dist/table/column-header-cell/README.md +2 -0
  28. package/dist/table/column-header-cell/table-column-header-cell.svelte +1 -7
  29. package/dist/table/column-header-cell/table-column-header-cell.svelte.d.ts +1 -6
  30. package/dist/table/column-resizer/README.md +2 -1
  31. package/dist/table/column-resizer/table-column-resizer.svelte +1 -9
  32. package/dist/table/column-resizer/table-column-resizer.svelte.d.ts +1 -8
  33. package/dist/table/empty-state/README.md +2 -0
  34. package/dist/table/empty-state/table-empty-state.svelte +1 -6
  35. package/dist/table/empty-state/table-empty-state.svelte.d.ts +1 -5
  36. package/dist/table/footer/README.md +2 -0
  37. package/dist/table/footer/table-footer.svelte +1 -7
  38. package/dist/table/footer/table-footer.svelte.d.ts +1 -6
  39. package/dist/table/header/README.md +2 -0
  40. package/dist/table/header/table-header.svelte +1 -7
  41. package/dist/table/header/table-header.svelte.d.ts +1 -6
  42. package/dist/table/index.d.ts +2 -1
  43. package/dist/table/root/README.md +31 -21
  44. package/dist/table/root/context.d.ts +19 -6
  45. package/dist/table/root/context.js +203 -29
  46. package/dist/table/root/table-root.svelte +30 -33
  47. package/dist/table/root/table-root.svelte.d.ts +1 -26
  48. package/dist/table/root/table-test.svelte +29 -0
  49. package/dist/table/root/table-test.svelte.d.ts +5 -1
  50. package/dist/table/row/README.md +2 -0
  51. package/dist/table/row/table-row.svelte +46 -83
  52. package/dist/table/row/table-row.svelte.d.ts +1 -10
  53. package/dist/table/types.d.ts +90 -0
  54. package/dist/table/types.js +1 -0
  55. package/dist/table/utils/handle-body-keydown.d.ts +13 -0
  56. package/dist/table/utils/handle-body-keydown.js +67 -0
  57. package/package.json +1 -1
@@ -7,20 +7,23 @@
7
7
  ### Table.Column
8
8
 
9
9
  Name: `Table.Column`
10
- Description: Logical metadata wrapper for a header column. It does not render DOM and is used to register stable column identity, sorting capability, row-header semantics, and resize metadata.
11
-
12
- | Prop | Type | Default | Description |
13
- | ---------------- | --------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------- |
14
- | `id` | `string` | `-` | Stable identifier for the column. |
15
- | `allowsSorting` | `boolean` | `false` | Enables sorting for the wrapped header cell. |
16
- | `allowsResizing` | `boolean` | `false` | Legacy explicit resize opt-in. `Table.ColumnResizer` now enables resizing automatically; keep this only for backward compatibility. |
17
- | `isRowHeader` | `boolean` | `false` | Marks the associated body column as row-header cells. |
18
- | `textValue` | `string` | `undefined` | Optional spoken label used by `Table.Root` sort announcements when it should differ from `id`. |
19
- | `width` | `number \| \`${number}px\`` | `undefined` | Explicit column width hint. Px numbers are the first-class format for the current resize release. |
20
- | `defaultWidth` | `number \| \`${number}px\`` | `undefined` | Uncontrolled initial width hint for the column. |
21
- | `minWidth` | `number` | `undefined` | Minimum width in px enforced during resize interactions. |
22
- | `maxWidth` | `number` | `undefined` | Maximum width in px enforced during resize interactions. |
23
- | `children` | `Snippet` | `undefined` | Usually a single `Table.ColumnHeaderCell`. |
10
+ Description: Logical metadata wrapper for a header column. It does not render DOM and is used to register stable column identity, sorting capability, row-header semantics, and width constraints.
11
+
12
+ Public prop type: `TableColumnProps`
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`. |
25
+
26
+ `Table.ColumnResizer` is the public resize opt-in. Compose it inside `Table.ColumnHeaderCell` when the owning column should be resizable.
24
27
 
25
28
  ### Context utilities
26
29
 
@@ -1,31 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy } from 'svelte';
3
- import type { Snippet } from 'svelte';
4
- import {
5
- setTableColumnContext,
6
- useTableContext,
7
- useTableSectionContext,
8
- type TableColumnWidth
9
- } from '../root/context';
10
-
11
- type TableColumnProps = {
12
- id: string;
13
- allowsSorting?: boolean;
14
- /** @deprecated `Table.ColumnResizer` now enables resizing automatically. */
15
- allowsResizing?: boolean;
16
- isRowHeader?: boolean;
17
- textValue?: string;
18
- width?: TableColumnWidth;
19
- defaultWidth?: TableColumnWidth;
20
- minWidth?: number;
21
- maxWidth?: number;
22
- children?: Snippet;
23
- };
3
+ import { setTableColumnContext, useTableContext, useTableSectionContext } from '../root/context';
4
+ import type { TableColumnProps } from '../types.js';
24
5
 
25
6
  let {
26
7
  id,
27
8
  allowsSorting = false,
28
- allowsResizing = false,
29
9
  isRowHeader = false,
30
10
  textValue,
31
11
  width,
@@ -51,9 +31,6 @@
51
31
  get allowsSorting() {
52
32
  return allowsSorting;
53
33
  },
54
- get allowsResizing() {
55
- return allowsResizing || table.isColumnResizable(id);
56
- },
57
34
  get isHidden() {
58
35
  return table.isColumnHidden(id);
59
36
  },
@@ -82,7 +59,6 @@
82
59
  token,
83
60
  id,
84
61
  allowsSorting,
85
- allowsResizing,
86
62
  isRowHeader,
87
63
  textValue,
88
64
  width,
@@ -1,18 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import { type TableColumnWidth } from '../root/context';
3
- type TableColumnProps = {
4
- id: string;
5
- allowsSorting?: boolean;
6
- /** @deprecated `Table.ColumnResizer` now enables resizing automatically. */
7
- allowsResizing?: boolean;
8
- isRowHeader?: boolean;
9
- textValue?: string;
10
- width?: TableColumnWidth;
11
- defaultWidth?: TableColumnWidth;
12
- minWidth?: number;
13
- maxWidth?: number;
14
- children?: Snippet;
15
- };
1
+ import type { TableColumnProps } from '../types.js';
16
2
  declare const TableColumn: import("svelte").Component<TableColumnProps, {}, "">;
17
3
  type TableColumn = ReturnType<typeof TableColumn>;
18
4
  export default TableColumn;
@@ -9,6 +9,8 @@
9
9
  Name: `Table.ColumnHeaderCell`
10
10
  Description: Focusable header cell for a column. It participates in roving focus and toggles sorting when the wrapping `Table.Column` allows it.
11
11
 
12
+ Public prop type: `TableColumnHeaderCellProps`
13
+
12
14
  - When a nested control like `Table.ColumnResizer` receives focus, the header exposes `data-focus-within` / `data-focus-visible-within` instead of remaining `data-focused`.
13
15
 
14
16
  | Prop | Type | Default | Description |
@@ -1,23 +1,17 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy } from 'svelte';
3
- import type { Snippet } from 'svelte';
4
- import type { HTMLAttributes } from 'svelte/elements';
5
3
  import {
6
4
  setTableCellContext,
7
5
  useTableColumnContext,
8
6
  useTableContext,
9
7
  useTableRowContext
10
8
  } from '../root/context';
9
+ import type { TableColumnHeaderCellProps } from '../types.js';
11
10
  import {
12
11
  shouldShowFocusVisible,
13
12
  trackInteractionModality
14
13
  } from '../../primitives/input-modality';
15
14
 
16
- type TableColumnHeaderCellProps = Omit<HTMLAttributes<HTMLTableCellElement>, 'children'> & {
17
- children?: Snippet;
18
- class?: string;
19
- };
20
-
21
15
  let { children, class: className = '', ...restProps }: TableColumnHeaderCellProps = $props();
22
16
 
23
17
  const table = useTableContext();
@@ -1,9 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type TableColumnHeaderCellProps = Omit<HTMLAttributes<HTMLTableCellElement>, 'children'> & {
4
- children?: Snippet;
5
- class?: string;
6
- };
1
+ import type { TableColumnHeaderCellProps } from '../types.js';
7
2
  declare const TableColumnHeaderCell: import("svelte").Component<TableColumnHeaderCellProps, {}, "">;
8
3
  type TableColumnHeaderCell = ReturnType<typeof TableColumnHeaderCell>;
9
4
  export default TableColumnHeaderCell;
@@ -9,6 +9,8 @@
9
9
  Name: `Table.ColumnResizer`
10
10
  Description: Interactive resize handle for the current `Table.Column`. It must be composed inside `Table.ColumnHeaderCell`, and it resizes the column that owns the surrounding `Table.Column` context.
11
11
 
12
+ Public prop type: `TableColumnResizerProps`
13
+
12
14
  | Prop | Type | Default | Description |
13
15
  | ----------- | --------- | ----------- | -------------------------------------------------------------------- |
14
16
  | `step` | `number` | `16` | Keyboard resize delta in px for `ArrowLeft` / `ArrowRight`. |
@@ -20,7 +22,6 @@ Description: Interactive resize handle for the current `Table.Column`. It must b
20
22
 
21
23
  - `Table.ColumnResizer` must be used inside `Table.ColumnHeaderCell`.
22
24
  - Rendering `Table.ColumnResizer` inside `Table.ColumnHeaderCell` is enough to make the owning `Table.Column` resizable.
23
- - `Table.Column.allowsResizing` is still accepted for backward compatibility, but it is no longer required.
24
25
  - The handle resolves the active column from `Table.Column` context. It does not accept a separate `columnId` prop.
25
26
  - Width state lives in `Table.Root` through `columnWidths` / `defaultColumnWidths`.
26
27
  - Pointer resizing uses Pointer Events, so mouse, touch, and pen interactions share the same behavior.
@@ -1,20 +1,12 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy } from 'svelte';
3
- import type { Snippet } from 'svelte';
4
- import type { HTMLAttributes } from 'svelte/elements';
5
3
  import { getTableCellContext, useTableColumnContext, useTableContext } from '../root/context';
4
+ import type { TableColumnResizerProps } from '../types.js';
6
5
  import {
7
6
  shouldShowFocusVisible,
8
7
  trackInteractionModality
9
8
  } from '../../primitives/input-modality';
10
9
 
11
- type TableColumnResizerProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
12
- step?: number;
13
- shiftStep?: number;
14
- children?: Snippet;
15
- class?: string;
16
- };
17
-
18
10
  let {
19
11
  step = 16,
20
12
  shiftStep = 48,
@@ -1,11 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type TableColumnResizerProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
4
- step?: number;
5
- shiftStep?: number;
6
- children?: Snippet;
7
- class?: string;
8
- };
1
+ import type { TableColumnResizerProps } from '../types.js';
9
2
  declare const TableColumnResizer: import("svelte").Component<TableColumnResizerProps, {}, "">;
10
3
  type TableColumnResizer = ReturnType<typeof TableColumnResizer>;
11
4
  export default TableColumnResizer;
@@ -9,6 +9,8 @@
9
9
  Name: `Table.EmptyState`
10
10
  Description: Convenience part for rendering a semantic empty row inside `Table.Body` when no data rows are registered.
11
11
 
12
+ Public prop type: `TableEmptyStateProps`
13
+
12
14
  | Prop | Type | Default | Description |
13
15
  | ---------- | --------- | ----------- | ------------------------------------------------------- |
14
16
  | `class` | `string` | `''` | Class names for the generated empty row. |
@@ -1,11 +1,6 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
2
  import { useTableContext, useTableSectionContext } from '../root/context';
4
-
5
- type TableEmptyStateProps = {
6
- children?: Snippet;
7
- class?: string;
8
- };
3
+ import type { TableEmptyStateProps } from '../types.js';
9
4
 
10
5
  let { children, class: className = '' }: TableEmptyStateProps = $props();
11
6
 
@@ -1,8 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- type TableEmptyStateProps = {
3
- children?: Snippet;
4
- class?: string;
5
- };
1
+ import type { TableEmptyStateProps } from '../types.js';
6
2
  declare const TableEmptyState: import("svelte").Component<TableEmptyStateProps, {}, "">;
7
3
  type TableEmptyState = ReturnType<typeof TableEmptyState>;
8
4
  export default TableEmptyState;
@@ -9,6 +9,8 @@
9
9
  Name: `Table.Footer`
10
10
  Description: Footer rowgroup for summary rows or aggregate information. In v1 it is semantic only and excluded from keyboard navigation.
11
11
 
12
+ Public prop type: `TableFooterProps`
13
+
12
14
  | Prop | Type | Default | Description |
13
15
  | ---------- | --------- | ----------- | ------------------------------------ |
14
16
  | `class` | `string` | `''` | Class names for the `tfoot` element. |
@@ -1,12 +1,6 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
- import type { HTMLAttributes } from 'svelte/elements';
4
2
  import { setTableSectionContext } from '../root/context';
5
-
6
- type TableFooterProps = Omit<HTMLAttributes<HTMLTableSectionElement>, 'children'> & {
7
- children?: Snippet;
8
- class?: string;
9
- };
3
+ import type { TableFooterProps } from '../types.js';
10
4
 
11
5
  let { children, class: className = '', ...restProps }: TableFooterProps = $props();
12
6
  setTableSectionContext({ section: 'footer' });
@@ -1,9 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type TableFooterProps = Omit<HTMLAttributes<HTMLTableSectionElement>, 'children'> & {
4
- children?: Snippet;
5
- class?: string;
6
- };
1
+ import type { TableFooterProps } from '../types.js';
7
2
  declare const TableFooter: import("svelte").Component<TableFooterProps, {}, "">;
8
3
  type TableFooter = ReturnType<typeof TableFooter>;
9
4
  export default TableFooter;
@@ -9,6 +9,8 @@
9
9
  Name: `Table.Header`
10
10
  Description: Header rowgroup for a `Table`, typically containing a single row of sortable or static column headers.
11
11
 
12
+ Public prop type: `TableHeaderProps`
13
+
12
14
  | Prop | Type | Default | Description |
13
15
  | ---------- | --------- | ----------- | ------------------------------------ |
14
16
  | `class` | `string` | `''` | Class names for the `thead` element. |
@@ -1,12 +1,6 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
- import type { HTMLAttributes } from 'svelte/elements';
4
2
  import { setTableSectionContext } from '../root/context';
5
-
6
- type TableHeaderProps = Omit<HTMLAttributes<HTMLTableSectionElement>, 'children'> & {
7
- children?: Snippet;
8
- class?: string;
9
- };
3
+ import type { TableHeaderProps } from '../types.js';
10
4
 
11
5
  let { children, class: className = '', ...restProps }: TableHeaderProps = $props();
12
6
  setTableSectionContext({ section: 'header' });
@@ -1,9 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- type TableHeaderProps = Omit<HTMLAttributes<HTMLTableSectionElement>, 'children'> & {
4
- children?: Snippet;
5
- class?: string;
6
- };
1
+ import type { TableHeaderProps } from '../types.js';
7
2
  declare const TableHeader: import("svelte").Component<TableHeaderProps, {}, "">;
8
3
  type TableHeader = ReturnType<typeof TableHeader>;
9
4
  export default TableHeader;
@@ -1,4 +1,5 @@
1
1
  export * as Table from './index.parts.js';
2
+ export type { TableBodyProps, TableCellProps, TableCheckboxIndicatorProps, TableCheckboxProps, TableColumnHeaderCellProps, TableColumnProps, TableColumnResizerProps, TableEmptyStateProps, TableFooterProps, TableHeaderProps, TableRowProps, TableRootProps } from './types.js';
2
3
  export { default as TableRoot } from './root/table-root.svelte';
3
4
  export { default as TableColumn } from './column/table-column.svelte';
4
5
  export { default as TableHeader } from './header/table-header.svelte';
@@ -11,6 +12,6 @@ export { default as TableColumnResizer } from './column-resizer/table-column-res
11
12
  export { default as TableCheckbox } from './checkbox/table-checkbox.svelte';
12
13
  export { default as TableCheckboxIndicator } from './checkbox-indicator/table-checkbox-indicator.svelte';
13
14
  export { default as TableCell } from './cell/table-cell.svelte';
14
- export { createTableContext, getTableContext, setTableContext, useTableContext, getTableSectionContext, setTableSectionContext, useTableSectionContext, getTableRowContext, setTableRowContext, useTableRowContext, getTableColumnContext, setTableColumnContext, useTableColumnContext, type TableContext, type TableSelectionBehavior, type TableSelectionCheckboxState, type TableSelectionKey, type TableSelectionMode, type TableSortDirection, type TableSortDescriptor, type TableColumnWidth, type TableGridCoord, type TableColumnRegistration, type TableSectionKind, type TableSectionContext, type TableRowContext, type TableColumnContext, type CreateTableContextOptions } from './root/context.js';
15
+ export { createTableContext, getTableContext, setTableContext, useTableContext, getTableSectionContext, setTableSectionContext, useTableSectionContext, getTableRowContext, setTableRowContext, useTableRowContext, getTableColumnContext, setTableColumnContext, useTableColumnContext, type TableContext, type TableDisabledBehavior, type TableSelectionBehavior, type TableSelectionCheckboxState, type TableSelectionKey, type TableSelectionMode, type TableRowActionHandler, type TableSortDirection, type TableSortDescriptor, type TableColumnWidth, type TableGridCoord, type TableSectionKind, type TableSectionContext, type TableRowContext, type TableColumnContext, type CreateTableContextOptions } from './root/context.js';
15
16
  import * as TableParts from './index.parts.js';
16
17
  export default TableParts;
@@ -9,26 +9,36 @@
9
9
  Name: `Table.Root`
10
10
  Description: State container for interactive table behavior, including roving focus, row selection, disabled row handling, and sortable column state.
11
11
 
12
- | Prop | Type | Default | Description |
13
- | ----------------------- | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
14
- | `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | Controls row selection behavior. |
15
- | `selectionBehavior` | `'toggle' \| 'replace'` | `'toggle'` | `toggle` uses checkbox-style selection. `replace` makes click replace selection, vertical arrows move selection, and `Shift+ArrowUp/Down` extend it. |
16
- | `selectedKeys` | `Iterable<string \| number>` | `undefined` | Controlled selected row ids. Supports `bind:selectedKeys`. |
17
- | `defaultSelectedKeys` | `Iterable<string \| number>` | `undefined` | Initial selected row ids for uncontrolled usage. When `selectionMode` later becomes `none`, the internal selection is cleared. |
18
- | `sortDescriptor` | `{ column: string; direction: 'ascending' \| 'descending' }` | `undefined` | Controlled sort state. Supports `bind:sortDescriptor`. Setting it back to `undefined` clears the sort. |
19
- | `defaultSortDescriptor` | `{ column: string; direction: 'ascending' \| 'descending' }` | `undefined` | Initial sort state for uncontrolled usage. |
20
- | `columnWidths` | `Map<string, number>` | `undefined` | Controlled column width state in px. Supports `bind:columnWidths`. |
21
- | `defaultColumnWidths` | `Iterable<[string, number]>` | `undefined` | Initial uncontrolled column widths in px. |
22
- | `disabledKeys` | `Iterable<string \| number>` | `undefined` | Row ids that should be non-selectable. |
23
- | `onSelectionChange` | `(keys: Set<string \| number>) => void` | `undefined` | Called when row selection changes. |
24
- | `onSortChange` | `(descriptor) => void` | `undefined` | Called when sortable header state changes. |
25
- | `onColumnWidthsChange` | `(widths: Map<string, number>) => void` | `undefined` | Called when resize interactions update column widths. |
26
- | `onColumnResizeStart` | `(columnId: string) => void` | `undefined` | Called when a column resize drag starts. |
27
- | `onColumnResizeEnd` | `(widths: Map<string, number>) => void` | `undefined` | Called when a column resize drag ends. |
28
- | `aria-label` | `string` | `undefined` | Accessible name when no external label is present. |
29
- | `aria-labelledby` | `string` | `undefined` | Id reference for an external label. |
30
- | `class` | `string` | `''` | Class names for the root table element. |
31
- | `children` | `Snippet` | `undefined` | Composed table parts. |
12
+ Public prop type: `TableRootProps`
13
+
14
+ | Prop | Type | Default | Description |
15
+ | ------------------------ | ------------------------------------------------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
16
+ | `selectionMode` | `'none' \| 'single' \| 'multiple'` | `'none'` | Controls row selection behavior. |
17
+ | `selectionBehavior` | `'toggle' \| 'replace'` | `'toggle'` | `toggle` uses checkbox-style selection. `replace` makes click replace selection, vertical arrows move selection, and `Shift+ArrowUp/Down` extend it. |
18
+ | `disabledBehavior` | `'selection' \| 'all'` | `'all'` | Controls whether disabled rows only block selection or block both selection and row actions. |
19
+ | `disallowEmptySelection` | `boolean` | `false` | Prevents the internal selection state from becoming empty when selection is enabled. |
20
+ | `hiddenColumns` | `Iterable<string>` | `undefined` | Controlled hidden column ids. Supports `bind:hiddenColumns`. |
21
+ | `defaultHiddenColumns` | `Iterable<string>` | `undefined` | Initial hidden column ids for uncontrolled usage. |
22
+ | `selectedKeys` | `Iterable<string \| number>` | `undefined` | Controlled selected row ids. Supports `bind:selectedKeys`. |
23
+ | `defaultSelectedKeys` | `Iterable<string \| number>` | `undefined` | Initial selected row ids for uncontrolled usage. When `selectionMode` later becomes `none`, the internal selection is cleared. |
24
+ | `sortDescriptor` | `{ column: string; direction: 'ascending' \| 'descending' }` | `undefined` | Controlled sort state. Supports `bind:sortDescriptor`. Setting it back to `undefined` clears the sort. |
25
+ | `defaultSortDescriptor` | `{ column: string; direction: 'ascending' \| 'descending' }` | `undefined` | Initial sort state for uncontrolled usage. |
26
+ | `columnWidths` | `Map<string, number>` | `undefined` | Controlled column width state in px. Supports `bind:columnWidths`. |
27
+ | `defaultColumnWidths` | `Iterable<[string, number]>` | `undefined` | Initial uncontrolled column widths in px. |
28
+ | `disabledKeys` | `Iterable<string \| number>` | `undefined` | Row ids that should be non-selectable. |
29
+ | `onRowAction` | `(id: string \| number) => void` | `undefined` | Called when a row action is triggered for an actionable row. |
30
+ | `onSelectionChange` | `(keys: Set<string \| number>) => void` | `undefined` | Called when row selection changes. |
31
+ | `onSortChange` | `(descriptor) => void` | `undefined` | Called when sortable header state changes. |
32
+ | `onColumnWidthsChange` | `(widths: Map<string, number>) => void` | `undefined` | Called when resize interactions update column widths. |
33
+ | `onHiddenColumnsChange` | `(columnIds: string[]) => void` | `undefined` | Called when hidden column state changes. |
34
+ | `onColumnResizeStart` | `(columnId: string) => void` | `undefined` | Called when a column resize drag starts. |
35
+ | `onColumnResizeEnd` | `(widths: Map<string, number>) => void` | `undefined` | Called when a column resize drag ends. |
36
+ | `aria-label` | `string` | `undefined` | Accessible name when no external label is present. |
37
+ | `aria-labelledby` | `string` | `undefined` | Id reference for an external label. |
38
+ | `class` | `string` | `''` | Class names for the root table element. |
39
+ | `context` | `TableContext` | `undefined` | Bindable reference to the active internal table context instance. |
40
+ | `element` | `HTMLTableElement` | `undefined` | Bindable reference to the rendered table element. |
41
+ | `children` | `Snippet` | `undefined` | Composed table parts. |
32
42
 
33
43
  ### Behavior notes
34
44
 
@@ -41,7 +51,7 @@ Description: Current v1 interaction constraints that affect consumer expectation
41
51
  | Text selection and copy | Browser-native text selection and `Ctrl+C` behavior are preserved; the component does not implement custom clipboard logic. |
42
52
  | `replace` mode blur | Clicking or tabbing outside the table clears focus state but does not clear row selection. |
43
53
  | Sort announcements | Sort changes are mirrored into a polite live region. Use `Table.Column.textValue` when the announced label should differ from the column `id`. |
44
- | Column resizing | Width state is normalized to px values and a resize handle only affects the `Table.Column` it is composed within. |
54
+ | Column resizing | Width state is normalized to px values and a `Table.ColumnResizer` only affects the `Table.Column` it is composed within. |
45
55
  | Row edge focus | In body rows, `ArrowLeft` before the first cell and `ArrowRight` after the last cell move focus onto the row itself; `ArrowUp` / `ArrowDown` keep that row-edge focus aligned across rows, repeating the same horizontal arrow loops back into the opposite edge cell, and `Home` / `End` jump to the first or last focusable body row while row focus is active. |
46
56
 
47
57
  ### Context utilities
@@ -2,14 +2,17 @@ import { type Readable } from 'svelte/store';
2
2
  export type TableSelectionKey = string | number;
3
3
  export type TableSelectionMode = 'none' | 'single' | 'multiple';
4
4
  export type TableSelectionBehavior = 'toggle' | 'replace';
5
+ export type TableDisabledBehavior = 'selection' | 'all';
5
6
  export type TableSortDirection = 'ascending' | 'descending';
6
7
  export type TableSectionKind = 'header' | 'body' | 'footer';
8
+ export type TableRowActionHandler = (id: TableSelectionKey) => void;
7
9
  type TableSelectionInteraction = {
8
10
  shiftKey?: boolean;
9
11
  ctrlKey?: boolean;
10
12
  metaKey?: boolean;
11
13
  altKey?: boolean;
12
14
  };
15
+ type TableRowPressSource = 'pointer' | 'pointer-double' | 'keyboard-enter' | 'keyboard-space';
13
16
  export type TableSortDescriptor = {
14
17
  column: string;
15
18
  direction: TableSortDirection;
@@ -20,11 +23,10 @@ export type TableGridCoord = {
20
23
  col: number;
21
24
  };
22
25
  export type TableRowFocusEdge = 'start' | 'end';
23
- export type TableColumnRegistration = {
26
+ type TableColumnMetadata = {
24
27
  token: string;
25
28
  id: string;
26
29
  allowsSorting: boolean;
27
- allowsResizing: boolean;
28
30
  isRowHeader: boolean;
29
31
  textValue?: string;
30
32
  width?: TableColumnWidth;
@@ -52,11 +54,14 @@ type TableCellRegistration = {
52
54
  export type CreateTableContextOptions = {
53
55
  selectionMode?: TableSelectionMode;
54
56
  selectionBehavior?: TableSelectionBehavior;
57
+ disabledBehavior?: TableDisabledBehavior;
58
+ disallowEmptySelection?: boolean;
55
59
  initialSelectedKeys?: Iterable<TableSelectionKey>;
56
60
  initialSortDescriptor?: TableSortDescriptor;
57
61
  initialColumnWidths?: Iterable<readonly [string, number]>;
58
62
  initialHiddenColumns?: Iterable<string>;
59
63
  disabledKeys?: Iterable<TableSelectionKey>;
64
+ onRowAction?: TableRowActionHandler;
60
65
  onSelectionChange?: (keys: Set<TableSelectionKey>) => void;
61
66
  onSortChange?: (descriptor: TableSortDescriptor | undefined) => void;
62
67
  onColumnWidthsChange?: (widths: Map<string, number>) => void;
@@ -74,18 +79,21 @@ export type TableContext = {
74
79
  createInstanceToken: (prefix: string) => string;
75
80
  selectionMode: TableSelectionMode;
76
81
  selectionBehavior: TableSelectionBehavior;
82
+ disabledBehavior: TableDisabledBehavior;
83
+ disallowEmptySelection: boolean;
84
+ selectionUnavailableDescriptionId: string;
77
85
  disabledKeys: Set<TableSelectionKey>;
78
86
  focusedCellKey: string | null;
79
87
  focusVisible: boolean;
80
88
  sortDescriptor: TableSortDescriptor | undefined;
81
89
  resizingColumnId: string | null;
82
- registerColumn: (column: TableColumnRegistration) => void;
90
+ registerColumn: (column: TableColumnMetadata) => void;
83
91
  unregisterColumn: (token: string) => void;
84
92
  registerColumnResizer: (columnToken: string) => void;
85
93
  unregisterColumnResizer: (columnToken: string) => void;
86
94
  getColumnCount: () => number;
87
95
  getVisibleColumnCount: () => number;
88
- getColumnAt: (index: number) => TableColumnRegistration | undefined;
96
+ getColumnAt: (index: number) => TableColumnMetadata | undefined;
89
97
  getColumnIndexByToken: (token: string) => number;
90
98
  getVisibleColumnIndexByToken: (token: string) => number;
91
99
  getColumnTextValue: (columnId: string) => string | undefined;
@@ -114,6 +122,9 @@ export type TableContext = {
114
122
  isRowFocusTarget: (token: string) => boolean;
115
123
  getRowFocusEdge: (token: string) => TableRowFocusEdge | null;
116
124
  isRowDisabled: (id: TableSelectionKey | undefined, localDisabled?: boolean) => boolean;
125
+ isRowSelectionDisabled: (id: TableSelectionKey | undefined, localDisabled?: boolean) => boolean;
126
+ isRowActionDisabled: (id: TableSelectionKey | undefined, localDisabled?: boolean) => boolean;
127
+ isRowActionable: (id: TableSelectionKey | undefined, localDisabled?: boolean) => boolean;
117
128
  hasSelectableRows: () => boolean;
118
129
  getSelectionCheckboxState: () => TableSelectionCheckboxState;
119
130
  registerCell: (cell: TableCellRegistration) => void;
@@ -123,7 +134,7 @@ export type TableContext = {
123
134
  isRowTabStop: (token: string) => boolean;
124
135
  focusCellByKey: (key: string | null) => void;
125
136
  focusRowByToken: (token: string, edge: TableRowFocusEdge) => void;
126
- pressRow: (id: TableSelectionKey | undefined, interaction?: TableSelectionInteraction) => void;
137
+ pressRow: (id: TableSelectionKey | undefined, source: TableRowPressSource, interaction?: TableSelectionInteraction, localDisabled?: boolean) => void;
127
138
  setFocusedCell: (key: string | null) => void;
128
139
  setFocusedRow: (token: string | null, edge?: TableRowFocusEdge) => void;
129
140
  setFocusVisible: (visible: boolean) => void;
@@ -140,7 +151,10 @@ export type TableContext = {
140
151
  setSelection: (keys: Iterable<TableSelectionKey>) => void;
141
152
  setSelectionMode: (mode: TableSelectionMode) => void;
142
153
  setSelectionBehavior: (behavior: TableSelectionBehavior) => void;
154
+ setDisabledBehavior: (behavior: TableDisabledBehavior) => void;
155
+ setDisallowEmptySelection: (disallow: boolean) => void;
143
156
  setDisabledKeys: (keys?: Iterable<TableSelectionKey>) => void;
157
+ setRowActionHandler: (handler?: TableRowActionHandler) => void;
144
158
  setSortDescriptor: (descriptor: TableSortDescriptor | undefined) => void;
145
159
  toggleSort: (columnId: string) => void;
146
160
  isColumnSortable: (columnId: string) => boolean;
@@ -163,7 +177,6 @@ export type TableColumnContext = {
163
177
  token: string;
164
178
  id: string;
165
179
  allowsSorting: boolean;
166
- allowsResizing: boolean;
167
180
  isHidden: boolean;
168
181
  isRowHeader: boolean;
169
182
  textValue?: string;