@human-kit/svelte-components 1.0.0-alpha.3 → 1.0.0-alpha.5
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/FOCUS_STATE_CONTRACT.md +12 -0
- package/dist/calendar/body-cell/README.md +15 -0
- package/dist/calendar/grid/README.md +13 -0
- package/dist/calendar/grid-body/README.md +13 -0
- package/dist/calendar/grid-header/README.md +13 -0
- package/dist/calendar/header-cell/README.md +14 -0
- package/dist/calendar/heading/README.md +13 -0
- package/dist/calendar/root/README.md +24 -0
- package/dist/calendar/trigger-next/README.md +14 -0
- package/dist/calendar/trigger-previous/README.md +14 -0
- package/dist/checkbox/README.md +53 -0
- package/dist/checkbox/TODO.md +16 -0
- package/dist/checkbox/index.d.ts +6 -0
- package/dist/checkbox/index.js +6 -0
- package/dist/checkbox/index.parts.d.ts +2 -0
- package/dist/checkbox/index.parts.js +2 -0
- package/dist/checkbox/indicator/README.md +23 -0
- package/dist/checkbox/indicator/checkbox-indicator.svelte +43 -0
- package/dist/checkbox/indicator/checkbox-indicator.svelte.d.ts +10 -0
- package/dist/checkbox/root/README.md +47 -0
- package/dist/checkbox/root/checkbox-label-test.svelte +10 -0
- package/dist/checkbox/root/checkbox-label-test.svelte.d.ts +18 -0
- package/dist/checkbox/root/checkbox-root.svelte +361 -0
- package/dist/checkbox/root/checkbox-root.svelte.d.ts +23 -0
- package/dist/checkbox/root/checkbox-test.svelte +59 -0
- package/dist/checkbox/root/checkbox-test.svelte.d.ts +18 -0
- package/dist/checkbox/root/context.d.ts +21 -0
- package/dist/checkbox/root/context.js +15 -0
- package/dist/clock/README.md +75 -0
- package/dist/clock/axis/README.md +24 -0
- package/dist/clock/axis/clock-axis.svelte +37 -0
- package/dist/clock/axis/clock-axis.svelte.d.ts +8 -0
- package/dist/clock/hooks/use-wheel-scroll.svelte.d.ts +16 -0
- package/dist/clock/hooks/use-wheel-scroll.svelte.js +336 -0
- package/dist/clock/index.d.ts +10 -0
- package/dist/clock/index.js +10 -0
- package/dist/clock/index.parts.d.ts +4 -0
- package/dist/clock/index.parts.js +4 -0
- package/dist/clock/root/README.md +38 -0
- package/dist/clock/root/clock-root-test.svelte +62 -0
- package/dist/clock/root/clock-root-test.svelte.d.ts +14 -0
- package/dist/clock/root/clock-root.svelte +329 -0
- package/dist/clock/root/clock-root.svelte.d.ts +25 -0
- package/dist/clock/root/context.d.ts +22 -0
- package/dist/clock/root/context.js +15 -0
- package/dist/clock/root/resolve-visible-columns.d.ts +7 -0
- package/dist/clock/root/resolve-visible-columns.js +16 -0
- package/dist/clock/root/time-utils.d.ts +48 -0
- package/dist/clock/root/time-utils.js +314 -0
- package/dist/clock/root/wheel-options.d.ts +17 -0
- package/dist/clock/root/wheel-options.js +63 -0
- package/dist/clock/wheel-column/README.md +25 -0
- package/dist/clock/wheel-column/clock-wheel-column-bindable-test.svelte +16 -0
- package/dist/clock/wheel-column/clock-wheel-column-bindable-test.svelte.d.ts +3 -0
- package/dist/clock/wheel-column/clock-wheel-column-custom-snippet-test.svelte +29 -0
- package/dist/clock/wheel-column/clock-wheel-column-custom-snippet-test.svelte.d.ts +6 -0
- package/dist/clock/wheel-column/clock-wheel-column-default-height-test.svelte +11 -0
- package/dist/clock/wheel-column/clock-wheel-column-default-height-test.svelte.d.ts +3 -0
- package/dist/clock/wheel-column/clock-wheel-column-test.svelte +38 -0
- package/dist/clock/wheel-column/clock-wheel-column-test.svelte.d.ts +12 -0
- package/dist/clock/wheel-column/clock-wheel-column-tp-test.svelte +38 -0
- package/dist/clock/wheel-column/clock-wheel-column-tp-test.svelte.d.ts +12 -0
- package/dist/clock/wheel-column/clock-wheel-column-untagged-snippet-test.svelte +29 -0
- package/dist/clock/wheel-column/clock-wheel-column-untagged-snippet-test.svelte.d.ts +6 -0
- package/dist/clock/wheel-column/clock-wheel-column.svelte +499 -0
- package/dist/clock/wheel-column/clock-wheel-column.svelte.d.ts +17 -0
- package/dist/clock/wheel-item/README.md +17 -0
- package/dist/clock/wheel-item/clock-wheel-item.svelte +49 -0
- package/dist/clock/wheel-item/clock-wheel-item.svelte.d.ts +17 -0
- package/dist/combobox/list/combobox-listbox.svelte.d.ts +1 -1
- package/dist/datepicker/TODO.md +2 -2
- package/dist/datepicker/calendar/README.md +19 -0
- package/dist/datepicker/input/README.md +15 -0
- package/dist/datepicker/popover/README.md +20 -0
- package/dist/datepicker/root/README.md +38 -0
- package/dist/datepicker/segment/README.md +14 -0
- package/dist/datepicker/trigger/README.md +14 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/primitives/focus-trap.js +11 -12
- package/dist/primitives/input-modality.js +10 -1
- package/dist/table/IMPLEMENTATION_NOTES.md +8 -0
- package/dist/table/PLAN-HIDDEN-COLUMNS.md +152 -0
- package/dist/table/PLAN.md +924 -0
- package/dist/table/README.md +116 -0
- package/dist/table/SELECTION_CHECKBOX_PLAN.md +234 -0
- package/dist/table/TODO.md +100 -0
- package/dist/table/body/README.md +24 -0
- package/dist/table/body/table-body.svelte +25 -0
- package/dist/table/body/table-body.svelte.d.ts +9 -0
- package/dist/table/cell/README.md +25 -0
- package/dist/table/cell/table-cell.svelte +247 -0
- package/dist/table/cell/table-cell.svelte.d.ts +9 -0
- package/dist/table/checkbox/README.md +38 -0
- package/dist/table/checkbox/table-checkbox-test.svelte +121 -0
- package/dist/table/checkbox/table-checkbox-test.svelte.d.ts +16 -0
- package/dist/table/checkbox/table-checkbox.svelte +274 -0
- package/dist/table/checkbox/table-checkbox.svelte.d.ts +13 -0
- package/dist/table/checkbox-indicator/README.md +29 -0
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte +22 -0
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte.d.ts +10 -0
- package/dist/table/column/README.md +32 -0
- package/dist/table/column/table-column.svelte +108 -0
- package/dist/table/column/table-column.svelte.d.ts +18 -0
- package/dist/table/column-header-cell/README.md +28 -0
- package/dist/table/column-header-cell/table-column-header-cell.svelte +281 -0
- package/dist/table/column-header-cell/table-column-header-cell.svelte.d.ts +9 -0
- package/dist/table/column-resizer/README.md +32 -0
- package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte +51 -0
- package/dist/table/column-resizer/table-column-resizer-freeze-layout-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte +83 -0
- package/dist/table/column-resizer/table-column-resizer-selection-column-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer-test.svelte +75 -0
- package/dist/table/column-resizer/table-column-resizer-test.svelte.d.ts +3 -0
- package/dist/table/column-resizer/table-column-resizer.svelte +616 -0
- package/dist/table/column-resizer/table-column-resizer.svelte.d.ts +11 -0
- package/dist/table/empty-state/README.md +25 -0
- package/dist/table/empty-state/table-empty-state.svelte +38 -0
- package/dist/table/empty-state/table-empty-state.svelte.d.ts +8 -0
- package/dist/table/footer/README.md +24 -0
- package/dist/table/footer/table-footer.svelte +19 -0
- package/dist/table/footer/table-footer.svelte.d.ts +9 -0
- package/dist/table/header/README.md +24 -0
- package/dist/table/header/table-header.svelte +19 -0
- package/dist/table/header/table-header.svelte.d.ts +9 -0
- package/dist/table/index.d.ts +16 -0
- package/dist/table/index.js +16 -0
- package/dist/table/index.parts.d.ts +12 -0
- package/dist/table/index.parts.js +12 -0
- package/dist/table/root/README.md +56 -0
- package/dist/table/root/context.d.ts +198 -0
- package/dist/table/root/context.js +1426 -0
- package/dist/table/root/table-reorder-test.svelte +64 -0
- package/dist/table/root/table-reorder-test.svelte.d.ts +3 -0
- package/dist/table/root/table-root.svelte +410 -0
- package/dist/table/root/table-root.svelte.d.ts +29 -0
- package/dist/table/root/table-test.svelte +165 -0
- package/dist/table/root/table-test.svelte.d.ts +25 -0
- package/dist/table/row/README.md +27 -0
- package/dist/table/row/table-row.svelte +321 -0
- package/dist/table/row/table-row.svelte.d.ts +13 -0
- package/dist/timepicker/IMPLEMENTATION_PLAN.md +254 -0
- package/dist/timepicker/README.md +97 -0
- package/dist/timepicker/TODO.md +86 -0
- package/dist/timepicker/clock/README.md +14 -0
- package/dist/timepicker/clock/time-picker-clock-test.svelte +45 -0
- package/dist/timepicker/clock/time-picker-clock-test.svelte.d.ts +11 -0
- package/dist/timepicker/clock/time-picker-clock.svelte +65 -0
- package/dist/timepicker/clock/time-picker-clock.svelte.d.ts +10 -0
- package/dist/timepicker/index.d.ts +14 -0
- package/dist/timepicker/index.js +14 -0
- package/dist/timepicker/index.parts.d.ts +8 -0
- package/dist/timepicker/index.parts.js +8 -0
- package/dist/timepicker/input/README.md +15 -0
- package/dist/timepicker/input/time-picker-input-forwarding-test.svelte +40 -0
- package/dist/timepicker/input/time-picker-input-forwarding-test.svelte.d.ts +3 -0
- package/dist/timepicker/input/time-picker-input.svelte +109 -0
- package/dist/timepicker/input/time-picker-input.svelte.d.ts +11 -0
- package/dist/timepicker/internal/strict-props.d.ts +4 -0
- package/dist/timepicker/internal/strict-props.js +51 -0
- package/dist/timepicker/popover/README.md +20 -0
- package/dist/timepicker/popover/time-picker-popover-unsafe-props-test.svelte +22 -0
- package/dist/timepicker/popover/time-picker-popover-unsafe-props-test.svelte.d.ts +3 -0
- package/dist/timepicker/popover/time-picker-popover.svelte +89 -0
- package/dist/timepicker/popover/time-picker-popover.svelte.d.ts +7 -0
- package/dist/timepicker/root/README.md +42 -0
- package/dist/timepicker/root/context.d.ts +51 -0
- package/dist/timepicker/root/context.js +15 -0
- package/dist/timepicker/root/time-picker-12h-test.svelte +22 -0
- package/dist/timepicker/root/time-picker-12h-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-bindable-test.svelte +25 -0
- package/dist/timepicker/root/time-picker-bindable-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-empty-test.svelte +20 -0
- package/dist/timepicker/root/time-picker-empty-test.svelte.d.ts +3 -0
- package/dist/timepicker/root/time-picker-root.svelte +625 -0
- package/dist/timepicker/root/time-picker-root.svelte.d.ts +28 -0
- package/dist/timepicker/root/time-picker-test.svelte +72 -0
- package/dist/timepicker/root/time-picker-test.svelte.d.ts +15 -0
- package/dist/timepicker/root/time-utils.d.ts +1 -0
- package/dist/timepicker/root/time-utils.js +3 -0
- package/dist/timepicker/segment/README.md +14 -0
- package/dist/timepicker/segment/time-picker-segment.svelte +365 -0
- package/dist/timepicker/segment/time-picker-segment.svelte.d.ts +9 -0
- package/dist/timepicker/trigger/README.md +14 -0
- package/dist/timepicker/trigger/time-picker-trigger-forwarding-test.svelte +35 -0
- package/dist/timepicker/trigger/time-picker-trigger-forwarding-test.svelte.d.ts +3 -0
- package/dist/timepicker/trigger/time-picker-trigger.svelte +122 -0
- package/dist/timepicker/trigger/time-picker-trigger.svelte.d.ts +9 -0
- package/package.json +21 -1
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onDestroy } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
|
+
import {
|
|
6
|
+
setTableCellContext,
|
|
7
|
+
useTableContext,
|
|
8
|
+
useTableRowContext,
|
|
9
|
+
type TableSelectionKey
|
|
10
|
+
} from '../root/context';
|
|
11
|
+
import {
|
|
12
|
+
shouldShowFocusVisible,
|
|
13
|
+
trackInteractionModality
|
|
14
|
+
} from '../../primitives/input-modality';
|
|
15
|
+
|
|
16
|
+
type TableCellProps = Omit<HTMLAttributes<HTMLTableCellElement>, 'children'> & {
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
class?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
let { children, class: className = '', ...restProps }: TableCellProps = $props();
|
|
22
|
+
|
|
23
|
+
const table = useTableContext();
|
|
24
|
+
const row = useTableRowContext();
|
|
25
|
+
const key = table.createInstanceToken('cell');
|
|
26
|
+
const layoutVersion = table.layoutVersion;
|
|
27
|
+
const focusVersion = table.focusVersion;
|
|
28
|
+
const selectionVersion = table.selectionVersion;
|
|
29
|
+
const cellOrderVersion = row.cellOrderVersion;
|
|
30
|
+
|
|
31
|
+
let element = $state<HTMLElement | undefined>(undefined);
|
|
32
|
+
let focusDelegate = $state<(() => HTMLElement | undefined) | undefined>(undefined);
|
|
33
|
+
row.registerCellToken(key, () => element);
|
|
34
|
+
const cellIndex = $derived.by(() => {
|
|
35
|
+
void $cellOrderVersion;
|
|
36
|
+
return row.getCellIndex(key);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
function syncCellRegistration() {
|
|
40
|
+
if (row.section !== 'body') return;
|
|
41
|
+
table.registerCell({
|
|
42
|
+
key,
|
|
43
|
+
rowToken: row.rowToken,
|
|
44
|
+
section: 'body',
|
|
45
|
+
columnIndex: cellIndex,
|
|
46
|
+
element,
|
|
47
|
+
focusDelegate
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function registerFocusDelegate(getElement: () => HTMLElement | undefined) {
|
|
52
|
+
focusDelegate = getElement;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function unregisterFocusDelegate() {
|
|
56
|
+
focusDelegate = undefined;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
setTableCellContext({
|
|
60
|
+
cellKey: key,
|
|
61
|
+
registerFocusDelegate,
|
|
62
|
+
unregisterFocusDelegate
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
syncCellRegistration();
|
|
66
|
+
|
|
67
|
+
$effect(() => {
|
|
68
|
+
syncCellRegistration();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
onDestroy(() => {
|
|
72
|
+
row.unregisterCellToken(key);
|
|
73
|
+
if (row.section === 'body') {
|
|
74
|
+
table.unregisterCell(key);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const column = $derived.by(() => {
|
|
79
|
+
void $layoutVersion;
|
|
80
|
+
return cellIndex >= 0 ? table.getColumnAt(cellIndex) : undefined;
|
|
81
|
+
});
|
|
82
|
+
const isColumnHidden = $derived.by(() => {
|
|
83
|
+
void $layoutVersion;
|
|
84
|
+
return column ? table.isColumnHidden(column.id) : false;
|
|
85
|
+
});
|
|
86
|
+
const visibleColumnIndex = $derived.by(() => {
|
|
87
|
+
void $layoutVersion;
|
|
88
|
+
return column ? table.getVisibleColumnIndexByToken(column.token) : -1;
|
|
89
|
+
});
|
|
90
|
+
const tagName = $derived(row.section === 'body' && column?.isRowHeader ? 'th' : 'td');
|
|
91
|
+
const role = $derived.by(() => {
|
|
92
|
+
if (isColumnHidden) return undefined;
|
|
93
|
+
if (row.section !== 'body') return undefined;
|
|
94
|
+
return column?.isRowHeader ? 'rowheader' : 'gridcell';
|
|
95
|
+
});
|
|
96
|
+
const isFocused = $derived.by(() => {
|
|
97
|
+
void $focusVersion;
|
|
98
|
+
return row.section === 'body' ? table.isCellFocused(key) : false;
|
|
99
|
+
});
|
|
100
|
+
const isFocusVisible = $derived.by(() => {
|
|
101
|
+
void $focusVersion;
|
|
102
|
+
return row.section === 'body' ? isFocused && table.focusVisible : false;
|
|
103
|
+
});
|
|
104
|
+
const isRowSelected = $derived.by(() => {
|
|
105
|
+
void $selectionVersion;
|
|
106
|
+
return row.section === 'body' ? table.isRowSelected(row.rowId) : false;
|
|
107
|
+
});
|
|
108
|
+
const isRowDisabled = $derived.by(() => {
|
|
109
|
+
void $selectionVersion;
|
|
110
|
+
return row.section === 'body' ? table.isRowDisabled(row.rowId, row.isDisabled) : row.isDisabled;
|
|
111
|
+
});
|
|
112
|
+
const isCellFocusable = $derived(row.section !== 'body' || !isRowDisabled);
|
|
113
|
+
const cellTabIndex = $derived.by(() => {
|
|
114
|
+
if (row.section !== 'body') return undefined;
|
|
115
|
+
if (isColumnHidden) return undefined;
|
|
116
|
+
if (!isCellFocusable) return undefined;
|
|
117
|
+
if (focusDelegate) return undefined;
|
|
118
|
+
return table.isCellTabStop(key) ? 0 : -1;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
function handleFocus() {
|
|
122
|
+
if (row.section !== 'body' || isRowDisabled) return;
|
|
123
|
+
table.setFocusedCell(key);
|
|
124
|
+
table.setFocusVisible(shouldShowFocusVisible(element ?? null));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function handleClick(event: MouseEvent) {
|
|
128
|
+
if (row.section !== 'body') return;
|
|
129
|
+
if (isRowDisabled) return;
|
|
130
|
+
table.focusCellByKey(key);
|
|
131
|
+
table.pressRow(row.rowId as TableSelectionKey | undefined, {
|
|
132
|
+
shiftKey: event.shiftKey,
|
|
133
|
+
ctrlKey: event.ctrlKey,
|
|
134
|
+
metaKey: event.metaKey,
|
|
135
|
+
altKey: event.altKey
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function handleMouseDown(event: MouseEvent) {
|
|
140
|
+
trackInteractionModality(event, element ?? null);
|
|
141
|
+
table.setFocusVisible(false);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
145
|
+
if (row.section !== 'body') return;
|
|
146
|
+
trackInteractionModality(event, element ?? null);
|
|
147
|
+
|
|
148
|
+
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {
|
|
149
|
+
if (table.selectionMode === 'multiple') {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
table.selectAllRows();
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'Home') {
|
|
157
|
+
event.preventDefault();
|
|
158
|
+
table.moveToGridStart();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'End') {
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
table.moveToGridEnd();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
switch (event.key) {
|
|
169
|
+
case 'ArrowUp':
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
table.moveFocus('up', {
|
|
172
|
+
shiftKey: event.shiftKey,
|
|
173
|
+
ctrlKey: event.ctrlKey,
|
|
174
|
+
metaKey: event.metaKey,
|
|
175
|
+
altKey: event.altKey
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
case 'ArrowDown':
|
|
179
|
+
event.preventDefault();
|
|
180
|
+
table.moveFocus('down', {
|
|
181
|
+
shiftKey: event.shiftKey,
|
|
182
|
+
ctrlKey: event.ctrlKey,
|
|
183
|
+
metaKey: event.metaKey,
|
|
184
|
+
altKey: event.altKey
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
case 'ArrowLeft':
|
|
188
|
+
event.preventDefault();
|
|
189
|
+
table.moveFocus('left');
|
|
190
|
+
return;
|
|
191
|
+
case 'ArrowRight':
|
|
192
|
+
event.preventDefault();
|
|
193
|
+
table.moveFocus('right');
|
|
194
|
+
return;
|
|
195
|
+
case 'Home':
|
|
196
|
+
event.preventDefault();
|
|
197
|
+
table.moveToRowStart();
|
|
198
|
+
return;
|
|
199
|
+
case 'End':
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
table.moveToRowEnd();
|
|
202
|
+
return;
|
|
203
|
+
case 'Enter':
|
|
204
|
+
case ' ':
|
|
205
|
+
event.preventDefault();
|
|
206
|
+
if (event.repeat) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (!isRowDisabled) {
|
|
210
|
+
table.pressRow(row.rowId as TableSelectionKey | undefined, {
|
|
211
|
+
shiftKey: event.shiftKey,
|
|
212
|
+
ctrlKey: event.ctrlKey,
|
|
213
|
+
metaKey: event.metaKey,
|
|
214
|
+
altKey: event.altKey
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
</script>
|
|
221
|
+
|
|
222
|
+
<svelte:element
|
|
223
|
+
this={tagName}
|
|
224
|
+
bind:this={element}
|
|
225
|
+
{role}
|
|
226
|
+
class={className}
|
|
227
|
+
tabindex={cellTabIndex}
|
|
228
|
+
scope={row.section === 'body' && column?.isRowHeader ? 'row' : undefined}
|
|
229
|
+
aria-colindex={!isColumnHidden && visibleColumnIndex >= 0 ? visibleColumnIndex + 1 : undefined}
|
|
230
|
+
aria-hidden={isColumnHidden ? true : undefined}
|
|
231
|
+
aria-disabled={row.section === 'body' && isRowDisabled ? true : undefined}
|
|
232
|
+
data-focused={isFocused ? 'true' : undefined}
|
|
233
|
+
data-focus-visible={isFocusVisible ? 'true' : undefined}
|
|
234
|
+
data-row-selected={isRowSelected ? 'true' : undefined}
|
|
235
|
+
data-disabled={isRowDisabled || undefined}
|
|
236
|
+
data-column-index={visibleColumnIndex >= 0 ? visibleColumnIndex : undefined}
|
|
237
|
+
style:display={isColumnHidden ? 'none' : undefined}
|
|
238
|
+
onfocus={handleFocus}
|
|
239
|
+
onclick={handleClick}
|
|
240
|
+
onmousedown={handleMouseDown}
|
|
241
|
+
onkeydown={handleKeyDown}
|
|
242
|
+
{...restProps}
|
|
243
|
+
>
|
|
244
|
+
{#if children}
|
|
245
|
+
{@render children()}
|
|
246
|
+
{/if}
|
|
247
|
+
</svelte:element>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type TableCellProps = Omit<HTMLAttributes<HTMLTableCellElement>, 'children'> & {
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
class?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const TableCell: import("svelte").Component<TableCellProps, {}, "">;
|
|
8
|
+
type TableCell = ReturnType<typeof TableCell>;
|
|
9
|
+
export default TableCell;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Table.Checkbox
|
|
2
|
+
|
|
3
|
+
## API reference
|
|
4
|
+
|
|
5
|
+
### Table.Checkbox
|
|
6
|
+
|
|
7
|
+
Name: `Table.Checkbox`
|
|
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.
|
|
9
|
+
|
|
10
|
+
| Prop | Type | Default | Description |
|
|
11
|
+
| ----------------- | ------------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------- |
|
|
12
|
+
| `id` | `string` | `undefined` | Optional id forwarded to the composed checkbox root. |
|
|
13
|
+
| `title` | `string` | `undefined` | Optional title forwarded to the composed checkbox root. |
|
|
14
|
+
| `style` | `HTMLAttributes<HTMLSpanElement>['style']` | `undefined` | Optional inline style forwarded to the composed checkbox root. |
|
|
15
|
+
| `data-testid` | `string` | `undefined` | Test id forwarded to the composed checkbox root. |
|
|
16
|
+
| `children` | `Snippet` | `undefined` | Composed child content, typically `Table.CheckboxIndicator`. |
|
|
17
|
+
| `class` | `string` | `''` | CSS class names for the composed checkbox root element. |
|
|
18
|
+
| `aria-label` | `string` | `undefined` | Accessible label override. Defaults to `Select all rows` in headers and `Select row <id>` in body rows. |
|
|
19
|
+
| `aria-labelledby` | `string` | `undefined` | Accessible label source id when the checkbox should be named by external content. |
|
|
20
|
+
|
|
21
|
+
## Usage notes
|
|
22
|
+
|
|
23
|
+
- Use `Table.Checkbox` inside `Table.Cell` or `Table.ColumnHeaderCell`.
|
|
24
|
+
- In body rows it mirrors and toggles the row selection state.
|
|
25
|
+
- In header cells it only renders when `selectionMode="multiple"` and toggles all selectable rows.
|
|
26
|
+
- When `selectionMode="none"`, the part renders nothing.
|
|
27
|
+
- `Table.Checkbox` is headless and unstyled. Apply classes from the consumer or docs layer.
|
|
28
|
+
- The checkbox receives DOM focus directly and is the intended visible focus target for selection controls inside the table.
|
|
29
|
+
|
|
30
|
+
```svelte
|
|
31
|
+
<Table.Cell>
|
|
32
|
+
<Table.Checkbox class="inline-flex h-5 w-5 items-center justify-center rounded border">
|
|
33
|
+
<Table.CheckboxIndicator>
|
|
34
|
+
<CheckIcon class="h-3.5 w-3.5" />
|
|
35
|
+
</Table.CheckboxIndicator>
|
|
36
|
+
</Table.Checkbox>
|
|
37
|
+
</Table.Cell>
|
|
38
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Table } from '../index';
|
|
3
|
+
import type {
|
|
4
|
+
TableSelectionBehavior,
|
|
5
|
+
TableSelectionKey,
|
|
6
|
+
TableSelectionMode
|
|
7
|
+
} from '../root/context';
|
|
8
|
+
|
|
9
|
+
type DemoRow = {
|
|
10
|
+
id: string;
|
|
11
|
+
email: string;
|
|
12
|
+
group: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const defaultRows: DemoRow[] = [
|
|
16
|
+
{ id: 'danilo', email: 'danilo@example.com', group: 'Developer' },
|
|
17
|
+
{ id: 'zahra', email: 'zahra@example.com', group: 'Admin' },
|
|
18
|
+
{ id: 'jasper', email: 'jasper@example.com', group: 'Developer' }
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const checkboxStyle =
|
|
22
|
+
'display:inline-flex;height:20px;width:20px;align-items:center;justify-content:center;border:1px solid currentColor;border-radius:4px;';
|
|
23
|
+
const indicatorStyle =
|
|
24
|
+
'display:inline-flex;height:14px;width:14px;align-items:center;justify-content:center;';
|
|
25
|
+
|
|
26
|
+
type CheckboxTestProps = {
|
|
27
|
+
rows?: DemoRow[];
|
|
28
|
+
selectionMode?: TableSelectionMode;
|
|
29
|
+
selectionBehavior?: TableSelectionBehavior;
|
|
30
|
+
disabledKeys?: Iterable<TableSelectionKey>;
|
|
31
|
+
initialSelectedKeys?: Iterable<TableSelectionKey>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
rows = defaultRows,
|
|
36
|
+
selectionMode = 'multiple',
|
|
37
|
+
selectionBehavior = 'toggle',
|
|
38
|
+
disabledKeys,
|
|
39
|
+
initialSelectedKeys
|
|
40
|
+
}: CheckboxTestProps = $props();
|
|
41
|
+
|
|
42
|
+
let currentSelectedKeys = $state<Set<TableSelectionKey>>(
|
|
43
|
+
new Set((() => initialSelectedKeys ?? [])())
|
|
44
|
+
);
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<Table.Root
|
|
48
|
+
aria-label="Users table"
|
|
49
|
+
{selectionMode}
|
|
50
|
+
{selectionBehavior}
|
|
51
|
+
bind:selectedKeys={currentSelectedKeys}
|
|
52
|
+
{disabledKeys}
|
|
53
|
+
>
|
|
54
|
+
<Table.Header>
|
|
55
|
+
<Table.Row>
|
|
56
|
+
<Table.Column id="selection" textValue="Selection">
|
|
57
|
+
<Table.ColumnHeaderCell data-testid="selection-header-cell">
|
|
58
|
+
<Table.Checkbox style={checkboxStyle} data-testid="header-checkbox">
|
|
59
|
+
<Table.CheckboxIndicator style={indicatorStyle}>
|
|
60
|
+
<svg aria-hidden="true" viewBox="0 0 16 16" class="h-3.5 w-3.5">
|
|
61
|
+
<path
|
|
62
|
+
d="M3.75 8.5 6.75 11.5 12.25 5.5"
|
|
63
|
+
fill="none"
|
|
64
|
+
stroke="currentColor"
|
|
65
|
+
stroke-linecap="round"
|
|
66
|
+
stroke-linejoin="round"
|
|
67
|
+
stroke-width="2"
|
|
68
|
+
/>
|
|
69
|
+
</svg>
|
|
70
|
+
</Table.CheckboxIndicator>
|
|
71
|
+
</Table.Checkbox>
|
|
72
|
+
</Table.ColumnHeaderCell>
|
|
73
|
+
</Table.Column>
|
|
74
|
+
<Table.Column id="email" isRowHeader textValue="Email">
|
|
75
|
+
<Table.ColumnHeaderCell>Email</Table.ColumnHeaderCell>
|
|
76
|
+
</Table.Column>
|
|
77
|
+
<Table.Column id="group" textValue="Group">
|
|
78
|
+
<Table.ColumnHeaderCell>Group</Table.ColumnHeaderCell>
|
|
79
|
+
</Table.Column>
|
|
80
|
+
</Table.Row>
|
|
81
|
+
</Table.Header>
|
|
82
|
+
|
|
83
|
+
<Table.Body>
|
|
84
|
+
{#each rows as row (row.id)}
|
|
85
|
+
<Table.Row
|
|
86
|
+
id={row.id}
|
|
87
|
+
isDisabled={disabledKeys ? Array.from(disabledKeys).includes(row.id) : false}
|
|
88
|
+
>
|
|
89
|
+
<Table.Cell data-testid={`selection-cell-${row.id}`}>
|
|
90
|
+
<Table.Checkbox style={checkboxStyle} data-testid={`row-checkbox-${row.id}`}>
|
|
91
|
+
<Table.CheckboxIndicator style={indicatorStyle}>
|
|
92
|
+
<svg aria-hidden="true" viewBox="0 0 16 16" class="h-3.5 w-3.5">
|
|
93
|
+
<path
|
|
94
|
+
d="M3.75 8.5 6.75 11.5 12.25 5.5"
|
|
95
|
+
fill="none"
|
|
96
|
+
stroke="currentColor"
|
|
97
|
+
stroke-linecap="round"
|
|
98
|
+
stroke-linejoin="round"
|
|
99
|
+
stroke-width="2"
|
|
100
|
+
/>
|
|
101
|
+
</svg>
|
|
102
|
+
</Table.CheckboxIndicator>
|
|
103
|
+
</Table.Checkbox>
|
|
104
|
+
</Table.Cell>
|
|
105
|
+
<Table.Cell data-testid={`email-cell-${row.id}`}>{row.email}</Table.Cell>
|
|
106
|
+
<Table.Cell data-testid={`group-cell-${row.id}`}>{row.group}</Table.Cell>
|
|
107
|
+
</Table.Row>
|
|
108
|
+
{/each}
|
|
109
|
+
<Table.EmptyState>No users found.</Table.EmptyState>
|
|
110
|
+
</Table.Body>
|
|
111
|
+
|
|
112
|
+
<Table.Footer>
|
|
113
|
+
<Table.Row>
|
|
114
|
+
<Table.Cell />
|
|
115
|
+
<Table.Cell>Total</Table.Cell>
|
|
116
|
+
<Table.Cell>{rows.length} users</Table.Cell>
|
|
117
|
+
</Table.Row>
|
|
118
|
+
</Table.Footer>
|
|
119
|
+
</Table.Root>
|
|
120
|
+
|
|
121
|
+
<output data-testid="selected-keys">{JSON.stringify([...currentSelectedKeys])}</output>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TableSelectionBehavior, TableSelectionKey, TableSelectionMode } from '../root/context';
|
|
2
|
+
type DemoRow = {
|
|
3
|
+
id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
group: string;
|
|
6
|
+
};
|
|
7
|
+
type CheckboxTestProps = {
|
|
8
|
+
rows?: DemoRow[];
|
|
9
|
+
selectionMode?: TableSelectionMode;
|
|
10
|
+
selectionBehavior?: TableSelectionBehavior;
|
|
11
|
+
disabledKeys?: Iterable<TableSelectionKey>;
|
|
12
|
+
initialSelectedKeys?: Iterable<TableSelectionKey>;
|
|
13
|
+
};
|
|
14
|
+
declare const TableCheckboxTest: import("svelte").Component<CheckboxTestProps, {}, "">;
|
|
15
|
+
type TableCheckboxTest = ReturnType<typeof TableCheckboxTest>;
|
|
16
|
+
export default TableCheckboxTest;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { Checkbox } from '../../checkbox';
|
|
5
|
+
import {
|
|
6
|
+
useTableCellContext,
|
|
7
|
+
useTableContext,
|
|
8
|
+
useTableRowContext,
|
|
9
|
+
useTableSectionContext
|
|
10
|
+
} from '../root/context';
|
|
11
|
+
import {
|
|
12
|
+
shouldShowFocusVisible,
|
|
13
|
+
trackInteractionModality
|
|
14
|
+
} from '../../primitives/input-modality';
|
|
15
|
+
|
|
16
|
+
type TableCheckboxProps = Omit<
|
|
17
|
+
HTMLAttributes<HTMLSpanElement>,
|
|
18
|
+
| 'children'
|
|
19
|
+
| 'class'
|
|
20
|
+
| 'id'
|
|
21
|
+
| 'role'
|
|
22
|
+
| 'tabindex'
|
|
23
|
+
| 'aria-checked'
|
|
24
|
+
| 'aria-disabled'
|
|
25
|
+
| 'onclick'
|
|
26
|
+
| 'onkeydown'
|
|
27
|
+
> & {
|
|
28
|
+
id?: string;
|
|
29
|
+
title?: string;
|
|
30
|
+
children?: Snippet;
|
|
31
|
+
class?: string;
|
|
32
|
+
'aria-label'?: string;
|
|
33
|
+
'aria-labelledby'?: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let {
|
|
37
|
+
id,
|
|
38
|
+
title,
|
|
39
|
+
children,
|
|
40
|
+
class: className = '',
|
|
41
|
+
'aria-label': ariaLabel,
|
|
42
|
+
'aria-labelledby': ariaLabelledby,
|
|
43
|
+
...restProps
|
|
44
|
+
}: TableCheckboxProps = $props();
|
|
45
|
+
|
|
46
|
+
const table = useTableContext();
|
|
47
|
+
const section = useTableSectionContext();
|
|
48
|
+
const row = useTableRowContext();
|
|
49
|
+
const cell = useTableCellContext();
|
|
50
|
+
const selectionVersion = table.selectionVersion;
|
|
51
|
+
const layoutVersion = table.layoutVersion;
|
|
52
|
+
|
|
53
|
+
let wrapperElement = $state<HTMLElement | undefined>(undefined);
|
|
54
|
+
|
|
55
|
+
const isVisible = $derived.by(() => {
|
|
56
|
+
if (table.selectionMode === 'none') return false;
|
|
57
|
+
if (section.section === 'footer') return false;
|
|
58
|
+
if (section.section === 'header') return table.selectionMode === 'multiple';
|
|
59
|
+
return section.section === 'body';
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const checkboxState = $derived.by(() => {
|
|
63
|
+
void $selectionVersion;
|
|
64
|
+
void $layoutVersion;
|
|
65
|
+
return section.section === 'header' ? table.getSelectionCheckboxState() : 'none';
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const isChecked = $derived.by(() => {
|
|
69
|
+
void $selectionVersion;
|
|
70
|
+
if (section.section === 'header') {
|
|
71
|
+
return checkboxState === 'all';
|
|
72
|
+
}
|
|
73
|
+
return section.section === 'body' ? table.isRowSelected(row.rowId) : false;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const isIndeterminate = $derived(section.section === 'header' && checkboxState === 'some');
|
|
77
|
+
|
|
78
|
+
const isDisabled = $derived.by(() => {
|
|
79
|
+
void $selectionVersion;
|
|
80
|
+
void $layoutVersion;
|
|
81
|
+
if (!isVisible) return true;
|
|
82
|
+
if (section.section === 'header') {
|
|
83
|
+
return !table.hasSelectableRows();
|
|
84
|
+
}
|
|
85
|
+
if (section.section === 'body') {
|
|
86
|
+
return table.isRowDisabled(row.rowId, row.isDisabled) || row.rowId === undefined;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const tabIndex = $derived.by(() => {
|
|
92
|
+
if (!isVisible || isDisabled) return undefined;
|
|
93
|
+
return table.isCellTabStop(cell.cellKey) ? 0 : -1;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const accessibleLabel = $derived.by(() => {
|
|
97
|
+
if (ariaLabel) return ariaLabel;
|
|
98
|
+
if (ariaLabelledby) return undefined;
|
|
99
|
+
if (section.section === 'header') return 'Select all rows';
|
|
100
|
+
return row.rowId !== undefined ? `Select row ${String(row.rowId)}` : 'Select row';
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
function getCheckboxRootElement() {
|
|
104
|
+
return wrapperElement?.querySelector<HTMLElement>('[data-checkbox-root="true"]') ?? undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
$effect(() => {
|
|
108
|
+
if (!isVisible || isDisabled) {
|
|
109
|
+
cell.unregisterFocusDelegate();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
cell.registerFocusDelegate(() => getCheckboxRootElement());
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
cell.unregisterFocusDelegate();
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
$effect(() => {
|
|
121
|
+
const checkboxElement = getCheckboxRootElement();
|
|
122
|
+
if (!checkboxElement) return;
|
|
123
|
+
|
|
124
|
+
if (!isVisible || isDisabled || tabIndex === undefined) {
|
|
125
|
+
checkboxElement.removeAttribute('tabindex');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
checkboxElement.tabIndex = tabIndex;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
function applySelection(nextChecked: boolean) {
|
|
133
|
+
if (isDisabled) return;
|
|
134
|
+
|
|
135
|
+
if (section.section === 'header') {
|
|
136
|
+
if (nextChecked) {
|
|
137
|
+
table.selectAllRows();
|
|
138
|
+
} else {
|
|
139
|
+
table.deselectAllRows();
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (section.section === 'body') {
|
|
145
|
+
table.toggleRowSelection(row.rowId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function handleFocusIn(event: FocusEvent) {
|
|
150
|
+
const target = event.target instanceof HTMLElement ? event.target : getCheckboxRootElement();
|
|
151
|
+
table.setFocusedCell(cell.cellKey);
|
|
152
|
+
table.setFocusVisible(shouldShowFocusVisible(target ?? null));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function handleFocusOut(event: FocusEvent) {
|
|
156
|
+
const nextFocused = event.relatedTarget;
|
|
157
|
+
if (nextFocused instanceof Node && wrapperElement?.contains(nextFocused)) return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function handleMouseDown(event: MouseEvent) {
|
|
161
|
+
trackInteractionModality(event, getCheckboxRootElement() ?? null);
|
|
162
|
+
table.setFocusVisible(false);
|
|
163
|
+
event.stopPropagation();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function handleClick(event: MouseEvent) {
|
|
167
|
+
event.stopPropagation();
|
|
168
|
+
if (!isVisible || isDisabled) return;
|
|
169
|
+
table.focusCellByKey(cell.cellKey);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
173
|
+
trackInteractionModality(event, getCheckboxRootElement() ?? null);
|
|
174
|
+
|
|
175
|
+
if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'a') {
|
|
176
|
+
if (table.selectionMode === 'multiple') {
|
|
177
|
+
event.preventDefault();
|
|
178
|
+
event.stopPropagation();
|
|
179
|
+
table.selectAllRows();
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'Home') {
|
|
185
|
+
event.preventDefault();
|
|
186
|
+
event.stopPropagation();
|
|
187
|
+
table.moveToGridStart();
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'End') {
|
|
192
|
+
event.preventDefault();
|
|
193
|
+
event.stopPropagation();
|
|
194
|
+
table.moveToGridEnd();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
switch (event.key) {
|
|
199
|
+
case 'ArrowUp':
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
event.stopPropagation();
|
|
202
|
+
table.moveFocus('up', {
|
|
203
|
+
shiftKey: event.shiftKey,
|
|
204
|
+
ctrlKey: event.ctrlKey,
|
|
205
|
+
metaKey: event.metaKey,
|
|
206
|
+
altKey: event.altKey
|
|
207
|
+
});
|
|
208
|
+
return;
|
|
209
|
+
case 'ArrowDown':
|
|
210
|
+
event.preventDefault();
|
|
211
|
+
event.stopPropagation();
|
|
212
|
+
table.moveFocus('down', {
|
|
213
|
+
shiftKey: event.shiftKey,
|
|
214
|
+
ctrlKey: event.ctrlKey,
|
|
215
|
+
metaKey: event.metaKey,
|
|
216
|
+
altKey: event.altKey
|
|
217
|
+
});
|
|
218
|
+
return;
|
|
219
|
+
case 'ArrowLeft':
|
|
220
|
+
event.preventDefault();
|
|
221
|
+
event.stopPropagation();
|
|
222
|
+
table.moveFocus('left');
|
|
223
|
+
return;
|
|
224
|
+
case 'ArrowRight':
|
|
225
|
+
event.preventDefault();
|
|
226
|
+
event.stopPropagation();
|
|
227
|
+
table.moveFocus('right');
|
|
228
|
+
return;
|
|
229
|
+
case 'Home':
|
|
230
|
+
event.preventDefault();
|
|
231
|
+
event.stopPropagation();
|
|
232
|
+
table.moveToRowStart();
|
|
233
|
+
return;
|
|
234
|
+
case 'End':
|
|
235
|
+
event.preventDefault();
|
|
236
|
+
event.stopPropagation();
|
|
237
|
+
table.moveToRowEnd();
|
|
238
|
+
return;
|
|
239
|
+
case 'Enter':
|
|
240
|
+
case ' ':
|
|
241
|
+
event.stopPropagation();
|
|
242
|
+
if (event.repeat || isDisabled) return;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
</script>
|
|
247
|
+
|
|
248
|
+
{#if isVisible}
|
|
249
|
+
<div
|
|
250
|
+
bind:this={wrapperElement}
|
|
251
|
+
role="presentation"
|
|
252
|
+
onfocusin={handleFocusIn}
|
|
253
|
+
onfocusout={handleFocusOut}
|
|
254
|
+
onmousedown={handleMouseDown}
|
|
255
|
+
onclick={handleClick}
|
|
256
|
+
onkeydown={handleKeyDown}
|
|
257
|
+
>
|
|
258
|
+
<Checkbox.Root
|
|
259
|
+
{id}
|
|
260
|
+
{isChecked}
|
|
261
|
+
{isIndeterminate}
|
|
262
|
+
{isDisabled}
|
|
263
|
+
onCheckedChange={applySelection}
|
|
264
|
+
{title}
|
|
265
|
+
aria-label={accessibleLabel}
|
|
266
|
+
aria-labelledby={ariaLabelledby}
|
|
267
|
+
data-table-checkbox="true"
|
|
268
|
+
class={className}
|
|
269
|
+
{...restProps}
|
|
270
|
+
>
|
|
271
|
+
{@render children?.()}
|
|
272
|
+
</Checkbox.Root>
|
|
273
|
+
</div>
|
|
274
|
+
{/if}
|