@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.
- package/dist/checkbox/root/checkbox-root.svelte +22 -2
- package/dist/checkbox/root/checkbox-root.svelte.d.ts +4 -1
- package/dist/combobox/root/combobox.svelte +1 -0
- package/dist/listbox/item/listbox-item.svelte +13 -0
- package/dist/listbox/root/listbox.svelte +7 -1
- package/dist/table/IMPLEMENTATION_NOTES.md +2 -1
- package/dist/table/PLAN.md +445 -33
- package/dist/table/README.md +11 -0
- package/dist/table/TODO.md +40 -2
- package/dist/table/body/README.md +2 -0
- package/dist/table/body/table-body.svelte +1 -7
- package/dist/table/body/table-body.svelte.d.ts +1 -6
- package/dist/table/cell/README.md +2 -0
- package/dist/table/cell/table-cell.svelte +87 -86
- package/dist/table/cell/table-cell.svelte.d.ts +1 -6
- package/dist/table/checkbox/README.md +2 -0
- package/dist/table/checkbox/table-checkbox-test.svelte +7 -0
- package/dist/table/checkbox/table-checkbox-test.svelte.d.ts +3 -1
- package/dist/table/checkbox/table-checkbox.svelte +56 -52
- package/dist/table/checkbox/table-checkbox.svelte.d.ts +1 -10
- package/dist/table/checkbox-indicator/README.md +2 -0
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte +1 -8
- package/dist/table/checkbox-indicator/table-checkbox-indicator.svelte.d.ts +1 -7
- package/dist/table/column/README.md +17 -14
- package/dist/table/column/table-column.svelte +2 -26
- package/dist/table/column/table-column.svelte.d.ts +1 -15
- package/dist/table/column-header-cell/README.md +2 -0
- package/dist/table/column-header-cell/table-column-header-cell.svelte +1 -7
- package/dist/table/column-header-cell/table-column-header-cell.svelte.d.ts +1 -6
- package/dist/table/column-resizer/README.md +2 -1
- package/dist/table/column-resizer/table-column-resizer.svelte +1 -9
- package/dist/table/column-resizer/table-column-resizer.svelte.d.ts +1 -8
- package/dist/table/empty-state/README.md +2 -0
- package/dist/table/empty-state/table-empty-state.svelte +1 -6
- package/dist/table/empty-state/table-empty-state.svelte.d.ts +1 -5
- package/dist/table/footer/README.md +2 -0
- package/dist/table/footer/table-footer.svelte +1 -7
- package/dist/table/footer/table-footer.svelte.d.ts +1 -6
- package/dist/table/header/README.md +2 -0
- package/dist/table/header/table-header.svelte +1 -7
- package/dist/table/header/table-header.svelte.d.ts +1 -6
- package/dist/table/index.d.ts +2 -1
- package/dist/table/root/README.md +31 -21
- package/dist/table/root/context.d.ts +19 -6
- package/dist/table/root/context.js +203 -29
- package/dist/table/root/table-root.svelte +30 -33
- package/dist/table/root/table-root.svelte.d.ts +1 -26
- package/dist/table/root/table-test.svelte +29 -0
- package/dist/table/root/table-test.svelte.d.ts +5 -1
- package/dist/table/row/README.md +2 -0
- package/dist/table/row/table-row.svelte +46 -83
- package/dist/table/row/table-row.svelte.d.ts +1 -10
- package/dist/table/types.d.ts +90 -0
- package/dist/table/types.js +1 -0
- package/dist/table/utils/handle-body-keydown.d.ts +13 -0
- package/dist/table/utils/handle-body-keydown.js +67 -0
- package/package.json +1 -1
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
| 'value'
|
|
25
25
|
> & {
|
|
26
26
|
id?: string;
|
|
27
|
+
element?: HTMLSpanElement | null;
|
|
27
28
|
name?: string;
|
|
28
29
|
value?: string;
|
|
29
30
|
isChecked?: boolean;
|
|
@@ -39,8 +40,20 @@
|
|
|
39
40
|
class?: string;
|
|
40
41
|
'aria-label'?: string;
|
|
41
42
|
'aria-labelledby'?: string;
|
|
43
|
+
onclick?: HTMLAttributes<HTMLSpanElement>['onclick'];
|
|
44
|
+
onkeydown?: HTMLAttributes<HTMLSpanElement>['onkeydown'];
|
|
42
45
|
};
|
|
43
46
|
|
|
47
|
+
function composeEventHandlers<TEvent extends Event>(
|
|
48
|
+
internalHandler: ((event: TEvent) => void) | undefined,
|
|
49
|
+
externalHandler: ((event: TEvent) => void) | undefined
|
|
50
|
+
): (event: TEvent) => void {
|
|
51
|
+
return (event: TEvent) => {
|
|
52
|
+
internalHandler?.(event);
|
|
53
|
+
externalHandler?.(event);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
44
57
|
function resolveState(isChecked: boolean, isIndeterminate: boolean): CheckboxState {
|
|
45
58
|
if (isIndeterminate) return 'indeterminate';
|
|
46
59
|
return isChecked ? 'checked' : 'unchecked';
|
|
@@ -56,6 +69,7 @@
|
|
|
56
69
|
|
|
57
70
|
let {
|
|
58
71
|
id,
|
|
72
|
+
element = $bindable(),
|
|
59
73
|
name,
|
|
60
74
|
value = 'on',
|
|
61
75
|
isChecked = $bindable(),
|
|
@@ -71,6 +85,8 @@
|
|
|
71
85
|
class: className = '',
|
|
72
86
|
'aria-label': ariaLabel,
|
|
73
87
|
'aria-labelledby': ariaLabelledby,
|
|
88
|
+
onclick: onClickExternal,
|
|
89
|
+
onkeydown: onKeyDownExternal,
|
|
74
90
|
...restProps
|
|
75
91
|
}: CheckboxRootProps = $props();
|
|
76
92
|
|
|
@@ -91,6 +107,10 @@
|
|
|
91
107
|
let rootRef: HTMLSpanElement | null = $state(null);
|
|
92
108
|
let inputRef: HTMLInputElement | null = $state(null);
|
|
93
109
|
|
|
110
|
+
$effect(() => {
|
|
111
|
+
element = rootRef;
|
|
112
|
+
});
|
|
113
|
+
|
|
94
114
|
if (untrack(() => isChecked) === undefined) {
|
|
95
115
|
isChecked = initialState === 'checked';
|
|
96
116
|
}
|
|
@@ -326,8 +346,8 @@
|
|
|
326
346
|
data-required={required || undefined}
|
|
327
347
|
data-focused={focused || undefined}
|
|
328
348
|
data-focus-visible={focusVisible || undefined}
|
|
329
|
-
onclick={handleClick}
|
|
330
|
-
onkeydown={handleKeyDown}
|
|
349
|
+
onclick={composeEventHandlers(onClickExternal ?? undefined, handleClick)}
|
|
350
|
+
onkeydown={composeEventHandlers(handleKeyDown, onKeyDownExternal ?? undefined)}
|
|
331
351
|
onkeyup={handleKeyUp}
|
|
332
352
|
onpointerdown={handlePointerDown}
|
|
333
353
|
onmousedown={handlePointerDown}
|
|
@@ -2,6 +2,7 @@ import { type Snippet } from 'svelte';
|
|
|
2
2
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
type CheckboxRootProps = Omit<HTMLAttributes<HTMLSpanElement>, 'children' | 'class' | 'id' | 'role' | 'tabindex' | 'aria-checked' | 'aria-disabled' | 'aria-readonly' | 'aria-required' | 'onclick' | 'onkeydown' | 'value'> & {
|
|
4
4
|
id?: string;
|
|
5
|
+
element?: HTMLSpanElement | null;
|
|
5
6
|
name?: string;
|
|
6
7
|
value?: string;
|
|
7
8
|
isChecked?: boolean;
|
|
@@ -17,7 +18,9 @@ type CheckboxRootProps = Omit<HTMLAttributes<HTMLSpanElement>, 'children' | 'cla
|
|
|
17
18
|
class?: string;
|
|
18
19
|
'aria-label'?: string;
|
|
19
20
|
'aria-labelledby'?: string;
|
|
21
|
+
onclick?: HTMLAttributes<HTMLSpanElement>['onclick'];
|
|
22
|
+
onkeydown?: HTMLAttributes<HTMLSpanElement>['onkeydown'];
|
|
20
23
|
};
|
|
21
|
-
declare const CheckboxRoot: import("svelte").Component<CheckboxRootProps, {}, "isChecked" | "isIndeterminate">;
|
|
24
|
+
declare const CheckboxRoot: import("svelte").Component<CheckboxRootProps, {}, "element" | "isChecked" | "isIndeterminate">;
|
|
22
25
|
type CheckboxRoot = ReturnType<typeof CheckboxRoot>;
|
|
23
26
|
export default CheckboxRoot;
|
|
@@ -225,6 +225,7 @@
|
|
|
225
225
|
|
|
226
226
|
if (selectionMode === 'single') {
|
|
227
227
|
newSelection = new Set([id]);
|
|
228
|
+
shouldFilter = false;
|
|
228
229
|
// Save the label persistently for restore on blur/escape
|
|
229
230
|
selectedLabel = label;
|
|
230
231
|
// Keep the selected label visible in the input without re-triggering
|
|
@@ -159,6 +159,19 @@
|
|
|
159
159
|
isFocusVisible = false;
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
+
$effect(() => {
|
|
163
|
+
if (!isFocusedComputed) {
|
|
164
|
+
if (pressedKey !== null) {
|
|
165
|
+
clearPressedState();
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (listFocusVisible || isFocusVisibleComputed) {
|
|
171
|
+
isHovered = false;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
162
175
|
function clearPressedState() {
|
|
163
176
|
isPressed = false;
|
|
164
177
|
pressedKey = null;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends object = object">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import { onMount } from 'svelte';
|
|
3
4
|
import { createListBoxContext, type ListBoxContext } from './context';
|
|
4
5
|
import { trackInteractionModality } from '../../primitives/input-modality';
|
|
5
6
|
|
|
@@ -118,9 +119,14 @@
|
|
|
118
119
|
|
|
119
120
|
const itemsArray = $derived(items ? Array.from(items) : []);
|
|
120
121
|
const hasItems = $derived(itemsArray.length > 0 || itemCount > 0);
|
|
122
|
+
let hasMounted = $state(false);
|
|
121
123
|
|
|
122
124
|
let focusWithin = $state(false);
|
|
123
125
|
|
|
126
|
+
onMount(() => {
|
|
127
|
+
hasMounted = true;
|
|
128
|
+
});
|
|
129
|
+
|
|
124
130
|
function syncFocusWithin() {
|
|
125
131
|
focusWithin =
|
|
126
132
|
!!listboxElement &&
|
|
@@ -175,7 +181,7 @@
|
|
|
175
181
|
{@render (children as Snippet)()}
|
|
176
182
|
{/if}
|
|
177
183
|
|
|
178
|
-
{#if !hasItems && itemCount === 0}
|
|
184
|
+
{#if hasMounted && !hasItems && itemCount === 0}
|
|
179
185
|
{#if typeof emptyPlaceholder === 'string'}
|
|
180
186
|
<div role="option" aria-selected="false" aria-disabled="true" data-empty-placeholder>
|
|
181
187
|
{emptyPlaceholder}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Open questions
|
|
4
4
|
|
|
5
|
-
- Disabled body rows are currently rendered and
|
|
5
|
+
- Disabled body rows are currently rendered and treated with an all-or-nothing disabled model. The planned `disabledBehavior` API (`'selection' | 'all'`) will require splitting focus/action disabling from selection disabling.
|
|
6
6
|
- `Table.Column` is implemented as a logical wrapper and currently assumes the intended child is a single `Table.ColumnHeaderCell`.
|
|
7
7
|
- `Table.Footer` renders semantic table cells but is intentionally excluded from the roving-focus model in v1.
|
|
8
8
|
- Interactive controls nested inside `Table.Cell` are still intentionally out of scope for v1.
|
|
9
|
+
- `pressRow()` is currently selection-oriented. The planned `onRowAction` feature will require a clearer interaction pipeline so pointer click, double click, `Enter`, and `Space` can route to action and selection independently.
|