@svgrid/grid 1.2.23 → 1.2.24
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/SvAutoComplete.svelte +23 -34
- package/dist/SvCalendar.svelte +74 -334
- package/dist/SvCalendar.svelte.d.ts +5 -23
- package/dist/SvCheckBox.svelte +11 -10
- package/dist/SvColorInput.svelte +31 -58
- package/dist/SvComboBox.svelte +32 -54
- package/dist/SvCountryInput.svelte +31 -29
- package/dist/SvDateTimePicker.svelte +53 -110
- package/dist/SvDateTimePicker.svelte.d.ts +4 -3
- package/dist/SvDropDownList.svelte +31 -54
- package/dist/SvGauge.svelte +21 -23
- package/dist/SvGauge.svelte.d.ts +0 -5
- package/dist/SvListBox.svelte +25 -58
- package/dist/SvListBox.svelte.d.ts +3 -0
- package/dist/SvMaskedInput.svelte +0 -0
- package/dist/SvNumberInput.svelte +0 -0
- package/dist/SvNumberInput.svelte.d.ts +2 -6
- package/dist/SvPasswordInput.svelte +18 -28
- package/dist/SvPasswordInput.svelte.d.ts +0 -4
- package/dist/SvPhoneInput.svelte +0 -0
- package/dist/SvRadioGroup.svelte +14 -37
- package/dist/SvRadioGroup.svelte.d.ts +6 -9
- package/dist/SvRating.svelte +22 -42
- package/dist/SvRating.svelte.d.ts +3 -5
- package/dist/SvSlider.svelte +30 -57
- package/dist/SvSlider.svelte.d.ts +0 -5
- package/dist/SvSwitchButton.svelte +10 -17
- package/dist/SvSwitchButton.svelte.d.ts +0 -5
- package/dist/SvTabs.svelte +26 -39
- package/dist/SvTabs.svelte.d.ts +5 -5
- package/dist/SvTagsInput.svelte +17 -28
- package/dist/SvTagsInput.svelte.d.ts +0 -5
- package/dist/SvTimePicker.svelte +52 -210
- package/dist/SvTimePicker.svelte.d.ts +11 -8
- package/dist/SvToggleButton.svelte +9 -9
- package/dist/SvTree.svelte +30 -109
- package/dist/SvTree.svelte.d.ts +9 -11
- package/dist/cdn/svgrid.js +7488 -5839
- package/dist/cdn/svgrid.svelte-external.js +4691 -3028
- package/dist/createAutocomplete.svelte.d.ts +77 -0
- package/dist/createAutocomplete.svelte.js +100 -0
- package/dist/createCalendar.svelte.d.ts +192 -0
- package/dist/createCalendar.svelte.js +402 -0
- package/dist/createCheckbox.svelte.d.ts +45 -0
- package/dist/createCheckbox.svelte.js +26 -0
- package/dist/createColorInput.svelte.d.ts +67 -0
- package/dist/createColorInput.svelte.js +100 -0
- package/dist/createCombobox.svelte.d.ts +102 -0
- package/dist/createCombobox.svelte.js +171 -0
- package/dist/createCountryInput.svelte.d.ts +86 -0
- package/dist/createCountryInput.svelte.js +126 -0
- package/dist/createDateTimePicker.svelte.d.ts +83 -0
- package/dist/createDateTimePicker.svelte.js +202 -0
- package/dist/createDropdownList.svelte.d.ts +78 -0
- package/dist/createDropdownList.svelte.js +117 -0
- package/dist/createGauge.svelte.d.ts +56 -0
- package/dist/createGauge.svelte.js +49 -0
- package/dist/createListbox.svelte.d.ts +79 -0
- package/dist/createListbox.svelte.js +117 -0
- package/dist/createMaskedInput.svelte.d.ts +30 -0
- package/dist/createMaskedInput.svelte.js +62 -0
- package/dist/createNumberInput.svelte.d.ts +72 -0
- package/dist/createNumberInput.svelte.js +167 -0
- package/dist/createPasswordInput.svelte.d.ts +60 -0
- package/dist/createPasswordInput.svelte.js +72 -0
- package/dist/createPhoneInput.svelte.d.ts +46 -0
- package/dist/createPhoneInput.svelte.js +105 -0
- package/dist/createRadioGroup.svelte.d.ts +64 -0
- package/dist/createRadioGroup.svelte.js +73 -0
- package/dist/createRating.svelte.d.ts +70 -0
- package/dist/createRating.svelte.js +85 -0
- package/dist/createSlider.svelte.d.ts +71 -0
- package/dist/createSlider.svelte.js +123 -0
- package/dist/createSwitch.svelte.d.ts +43 -0
- package/dist/createSwitch.svelte.js +41 -0
- package/dist/createTabs.svelte.d.ts +78 -0
- package/dist/createTabs.svelte.js +92 -0
- package/dist/createTagsInput.svelte.d.ts +65 -0
- package/dist/createTagsInput.svelte.js +93 -0
- package/dist/createTimePicker.svelte.d.ts +106 -0
- package/dist/createTimePicker.svelte.js +248 -0
- package/dist/createToggle.svelte.d.ts +43 -0
- package/dist/createToggle.svelte.js +39 -0
- package/dist/createTree.svelte.d.ts +96 -0
- package/dist/createTree.svelte.js +194 -0
- package/dist/editor-contract.d.ts +48 -0
- package/dist/editor-contract.js +26 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +31 -0
- package/package.json +1 -1
- package/src/SvAutoComplete.svelte +23 -34
- package/src/SvCalendar.svelte +74 -334
- package/src/SvCheckBox.svelte +11 -10
- package/src/SvColorInput.svelte +31 -58
- package/src/SvComboBox.svelte +32 -54
- package/src/SvCountryInput.svelte +31 -29
- package/src/SvDateTimePicker.svelte +53 -110
- package/src/SvDropDownList.svelte +31 -54
- package/src/SvGauge.svelte +21 -23
- package/src/SvListBox.svelte +25 -58
- package/src/SvMaskedInput.svelte +0 -0
- package/src/SvNumberInput.svelte +0 -0
- package/src/SvPasswordInput.svelte +18 -28
- package/src/SvPhoneInput.svelte +0 -0
- package/src/SvRadioGroup.svelte +14 -37
- package/src/SvRating.svelte +22 -42
- package/src/SvSlider.svelte +30 -57
- package/src/SvSwitchButton.svelte +10 -17
- package/src/SvTabs.svelte +26 -39
- package/src/SvTagsInput.svelte +17 -28
- package/src/SvTimePicker.svelte +52 -210
- package/src/SvToggleButton.svelte +9 -9
- package/src/SvTree.svelte +30 -109
- package/src/createAutocomplete.svelte.ts +104 -0
- package/src/createCalendar.svelte.ts +488 -0
- package/src/createCheckbox.svelte.ts +74 -0
- package/src/createColorInput.svelte.ts +115 -0
- package/src/createCombobox.svelte.ts +158 -0
- package/src/createCountryInput.svelte.ts +126 -0
- package/src/createDateTimePicker.svelte.ts +216 -0
- package/src/createDropdownList.svelte.ts +125 -0
- package/src/createGauge.svelte.ts +86 -0
- package/src/createListbox.svelte.ts +186 -0
- package/src/createMaskedInput.svelte.ts +81 -0
- package/src/createNumberInput.svelte.ts +193 -0
- package/src/createPasswordInput.svelte.ts +87 -0
- package/src/createPhoneInput.svelte.ts +119 -0
- package/src/createRadioGroup.svelte.ts +132 -0
- package/src/createRating.svelte.ts +145 -0
- package/src/createSlider.svelte.ts +160 -0
- package/src/createSwitch.svelte.ts +78 -0
- package/src/createTabs.svelte.ts +129 -0
- package/src/createTagsInput.svelte.ts +98 -0
- package/src/createTimePicker.svelte.ts +289 -0
- package/src/createToggle.svelte.ts +69 -0
- package/src/createTree.svelte.ts +216 -0
- package/src/editor-contract.test.ts +32 -0
- package/src/editor-contract.ts +60 -0
- package/src/index.ts +39 -0
- package/src/ui-inputs.test.ts +26 -0
- package/src/ui-selection.test.ts +13 -0
package/dist/SvTree.svelte
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
export type TreeNode
|
|
3
|
-
id: string
|
|
4
|
-
label: string
|
|
5
|
-
children?: TreeNode[]
|
|
6
|
-
disabled?: boolean
|
|
7
|
-
}
|
|
2
|
+
export type { TreeNode } from './createTree.svelte'
|
|
8
3
|
</script>
|
|
9
4
|
|
|
10
5
|
<script lang="ts">
|
|
@@ -12,8 +7,12 @@
|
|
|
12
7
|
* SvTree - a WAI-ARIA tree view. Expand/collapse, single-select highlight, and
|
|
13
8
|
* optional cascading tri-state checkboxes. Parity: Smart `smart-tree`. Keyboard:
|
|
14
9
|
* up/down move, left collapse/parent, right expand/child, Enter/Space select.
|
|
15
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* The behavior (flattening, cascade math, keyboard, ARIA) lives in the headless
|
|
12
|
+
* `createTree` core; this component is just one styled renderer over it.
|
|
16
13
|
*/
|
|
14
|
+
import { createTree, type TreeNode } from './createTree.svelte'
|
|
15
|
+
|
|
17
16
|
type Props = {
|
|
18
17
|
nodes: ReadonlyArray<TreeNode>
|
|
19
18
|
/** Selected node id (single-select highlight). */
|
|
@@ -41,117 +40,39 @@
|
|
|
41
40
|
ariaLabel,
|
|
42
41
|
}: Props = $props()
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
const tree = createTree({
|
|
44
|
+
nodes: () => nodes,
|
|
45
|
+
selected: () => selected,
|
|
46
|
+
onSelect: (id) => onSelect?.(id),
|
|
47
|
+
expandedIds: () => expandedIds,
|
|
48
|
+
onToggle: (id, exp) => onToggle?.(id, exp),
|
|
49
|
+
checkable: () => checkable,
|
|
50
|
+
checked: () => checked,
|
|
51
|
+
onCheck: (ids) => onCheck?.(ids),
|
|
52
|
+
ariaLabel: () => ariaLabel,
|
|
50
53
|
})
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
out.push({ node, depth, hasChildren, open, parentId })
|
|
61
|
-
if (hasChildren && open) walk(node.children!, depth + 1, node.id)
|
|
62
|
-
}
|
|
55
|
+
// DOM focus movement is a render concern: follow the core's roving focus row.
|
|
56
|
+
let treeEl: HTMLDivElement | null = null
|
|
57
|
+
let lastFocusTick = 0
|
|
58
|
+
$effect(() => {
|
|
59
|
+
if (tree.focusTick !== lastFocusTick) {
|
|
60
|
+
lastFocusTick = tree.focusTick
|
|
61
|
+
const i = tree.activeIndex
|
|
62
|
+
queueMicrotask(() => treeEl?.querySelector<HTMLElement>(`[data-row="${i}"]`)?.focus())
|
|
63
63
|
}
|
|
64
|
-
walk(nodes, 0, null)
|
|
65
|
-
return out
|
|
66
64
|
})
|
|
67
|
-
|
|
68
|
-
let active = $state(0)
|
|
69
|
-
$effect(() => { if (active >= flat.length) active = Math.max(0, flat.length - 1) })
|
|
70
|
-
|
|
71
|
-
const checkedSet = $derived(new Set(checked))
|
|
72
|
-
|
|
73
|
-
function descendantIds(node: TreeNode): string[] {
|
|
74
|
-
const ids: string[] = []
|
|
75
|
-
const walk = (n: TreeNode) => { for (const c of n.children ?? []) { ids.push(c.id); walk(c) } }
|
|
76
|
-
walk(node)
|
|
77
|
-
return ids
|
|
78
|
-
}
|
|
79
|
-
function checkState(node: TreeNode): 'checked' | 'indeterminate' | 'unchecked' {
|
|
80
|
-
if (!node.children?.length) return checkedSet.has(node.id) ? 'checked' : 'unchecked'
|
|
81
|
-
const desc = descendantIds(node)
|
|
82
|
-
const on = desc.filter((id) => checkedSet.has(id)).length
|
|
83
|
-
if (on === 0 && !checkedSet.has(node.id)) return 'unchecked'
|
|
84
|
-
if (on === desc.length) return 'checked'
|
|
85
|
-
return 'indeterminate'
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function toggleExpand(node: TreeNode) {
|
|
89
|
-
if (!node.children?.length) return
|
|
90
|
-
const next = new Set(expanded)
|
|
91
|
-
const willOpen = !next.has(node.id)
|
|
92
|
-
willOpen ? next.add(node.id) : next.delete(node.id)
|
|
93
|
-
expanded = next
|
|
94
|
-
onToggle?.(node.id, willOpen)
|
|
95
|
-
}
|
|
96
|
-
function select(node: TreeNode) {
|
|
97
|
-
if (node.disabled) return
|
|
98
|
-
onSelect?.(node.id)
|
|
99
|
-
}
|
|
100
|
-
function toggleCheck(node: TreeNode) {
|
|
101
|
-
if (node.disabled) return
|
|
102
|
-
const next = new Set(checkedSet)
|
|
103
|
-
const ids = [node.id, ...descendantIds(node)]
|
|
104
|
-
const currentlyOn = checkState(node) === 'checked'
|
|
105
|
-
for (const id of ids) currentlyOn ? next.delete(id) : next.add(id)
|
|
106
|
-
onCheck?.([...next])
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function onKeydown(e: KeyboardEvent) {
|
|
110
|
-
const item = flat[active]
|
|
111
|
-
if (!item) return
|
|
112
|
-
switch (e.key) {
|
|
113
|
-
case 'ArrowDown': e.preventDefault(); active = Math.min(active + 1, flat.length - 1); focusActive(); break
|
|
114
|
-
case 'ArrowUp': e.preventDefault(); active = Math.max(active - 1, 0); focusActive(); break
|
|
115
|
-
case 'ArrowRight':
|
|
116
|
-
e.preventDefault()
|
|
117
|
-
if (item.hasChildren && !item.open) toggleExpand(item.node)
|
|
118
|
-
else if (item.hasChildren && item.open) { active = Math.min(active + 1, flat.length - 1); focusActive() }
|
|
119
|
-
break
|
|
120
|
-
case 'ArrowLeft':
|
|
121
|
-
e.preventDefault()
|
|
122
|
-
if (item.hasChildren && item.open) toggleExpand(item.node)
|
|
123
|
-
else if (item.parentId) { const pi = flat.findIndex((f) => f.node.id === item.parentId); if (pi >= 0) { active = pi; focusActive() } }
|
|
124
|
-
break
|
|
125
|
-
case 'Enter': e.preventDefault(); select(item.node); break
|
|
126
|
-
case ' ': e.preventDefault(); checkable ? toggleCheck(item.node) : select(item.node); break
|
|
127
|
-
case 'Home': e.preventDefault(); active = 0; focusActive(); break
|
|
128
|
-
case 'End': e.preventDefault(); active = flat.length - 1; focusActive(); break
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
let treeEl: HTMLDivElement | null = null
|
|
133
|
-
function focusActive() {
|
|
134
|
-
queueMicrotask(() => treeEl?.querySelector<HTMLElement>(`[data-row="${active}"]`)?.focus())
|
|
135
|
-
}
|
|
136
65
|
</script>
|
|
137
66
|
|
|
138
|
-
<div bind:this={treeEl} class="sv-tree"
|
|
139
|
-
{#each
|
|
140
|
-
{@const cs = checkable ?
|
|
67
|
+
<div bind:this={treeEl} class="sv-tree" {...tree.treeProps()}>
|
|
68
|
+
{#each tree.rows as item (item.node.id)}
|
|
69
|
+
{@const cs = checkable ? tree.checkStateOf(item.node) : 'unchecked'}
|
|
141
70
|
<div
|
|
142
71
|
class="sv-tree__row"
|
|
143
72
|
class:is-selected={item.node.id === selected}
|
|
144
73
|
class:is-disabled={item.node.disabled}
|
|
145
|
-
role="treeitem"
|
|
146
|
-
aria-level={item.depth + 1}
|
|
147
|
-
aria-selected={item.node.id === selected}
|
|
148
|
-
aria-expanded={item.hasChildren ? item.open : undefined}
|
|
149
|
-
aria-checked={checkable ? cs === 'checked' ? 'true' : cs === 'indeterminate' ? 'mixed' : 'false' : undefined}
|
|
150
|
-
data-row={i}
|
|
151
|
-
tabindex={i === active ? 0 : -1}
|
|
152
74
|
style:padding-left={`${item.depth * 18 + 6}px`}
|
|
153
|
-
|
|
154
|
-
onkeydown={onKeydown}
|
|
75
|
+
{...tree.itemProps(item)}
|
|
155
76
|
>
|
|
156
77
|
<button
|
|
157
78
|
type="button"
|
|
@@ -160,14 +81,14 @@
|
|
|
160
81
|
class:is-leaf={!item.hasChildren}
|
|
161
82
|
tabindex="-1"
|
|
162
83
|
aria-hidden={!item.hasChildren}
|
|
163
|
-
onclick={(e) => { e.stopPropagation(); toggleExpand(item.node) }}
|
|
84
|
+
onclick={(e) => { e.stopPropagation(); tree.toggleExpand(item.node) }}
|
|
164
85
|
>
|
|
165
86
|
{#if item.hasChildren}
|
|
166
87
|
<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6" /></svg>
|
|
167
88
|
{/if}
|
|
168
89
|
</button>
|
|
169
90
|
{#if checkable}
|
|
170
|
-
<button type="button" class="sv-tree__check is-{cs}" tabindex="-1" aria-hidden="true" onclick={(e) => { e.stopPropagation(); toggleCheck(item.node) }}>
|
|
91
|
+
<button type="button" class="sv-tree__check is-{cs}" tabindex="-1" aria-hidden="true" onclick={(e) => { e.stopPropagation(); tree.toggleCheck(item.node) }}>
|
|
171
92
|
{#if cs === 'checked'}<svg viewBox="0 0 16 16"><path d="M3.5 8.5l3 3 6-6.5" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
|
172
93
|
{:else if cs === 'indeterminate'}<svg viewBox="0 0 16 16"><path d="M4 8h8" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" /></svg>{/if}
|
|
173
94
|
</button>
|
package/dist/SvTree.svelte.d.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
export type TreeNode
|
|
2
|
-
id: string;
|
|
3
|
-
label: string;
|
|
4
|
-
children?: TreeNode[];
|
|
5
|
-
disabled?: boolean;
|
|
6
|
-
};
|
|
1
|
+
export type { TreeNode } from './createTree.svelte';
|
|
7
2
|
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
* SvTree - a WAI-ARIA tree view. Expand/collapse, single-select highlight, and
|
|
4
|
+
* optional cascading tri-state checkboxes. Parity: Smart `smart-tree`. Keyboard:
|
|
5
|
+
* up/down move, left collapse/parent, right expand/child, Enter/Space select.
|
|
6
|
+
*
|
|
7
|
+
* The behavior (flattening, cascade math, keyboard, ARIA) lives in the headless
|
|
8
|
+
* `createTree` core; this component is just one styled renderer over it.
|
|
9
|
+
*/
|
|
10
|
+
import { type TreeNode } from './createTree.svelte';
|
|
13
11
|
type Props = {
|
|
14
12
|
nodes: ReadonlyArray<TreeNode>;
|
|
15
13
|
/** Selected node id (single-select highlight). */
|