@salt-ds/lab 1.0.0-alpha.86 → 1.0.0-alpha.88
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/CHANGELOG.md +126 -0
- package/css/salt-lab.css +145 -212
- package/dist-cjs/calendar/internal/CalendarDay.css.js +1 -1
- package/dist-cjs/common-hooks/useSelection.js +0 -2
- package/dist-cjs/common-hooks/useSelection.js.map +1 -1
- package/dist-cjs/contact-details/ContactDetails.css.js +1 -1
- package/dist-cjs/date-input/DateInput.css.js +1 -1
- package/dist-cjs/date-input/DateInputRange.js +2 -8
- package/dist-cjs/date-input/DateInputRange.js.map +1 -1
- package/dist-cjs/date-input/DateInputSingle.js +1 -1
- package/dist-cjs/date-input/DateInputSingle.js.map +1 -1
- package/dist-cjs/index.js +6 -2
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/list-deprecated/ListItem.js.map +1 -1
- package/dist-cjs/rating/Rating.css.js +1 -1
- package/dist-cjs/rating/Rating.js +8 -7
- package/dist-cjs/rating/Rating.js.map +1 -1
- package/dist-cjs/tabs-next/TabListNext.js +1 -1
- package/dist-cjs/tabs-next/TabListNext.js.map +1 -1
- package/dist-cjs/tokenized-input-next/TokenizedInputNext.js +2 -2
- package/dist-cjs/tokenized-input-next/TokenizedInputNext.js.map +1 -1
- package/dist-cjs/tree/Tree.css.js +1 -1
- package/dist-cjs/tree/Tree.js +274 -207
- package/dist-cjs/tree/Tree.js.map +1 -1
- package/dist-cjs/tree/TreeContext.js +31 -0
- package/dist-cjs/tree/TreeContext.js.map +1 -0
- package/dist-cjs/tree/TreeNode.css.js +1 -1
- package/dist-cjs/tree/TreeNode.js +86 -42
- package/dist-cjs/tree/TreeNode.js.map +1 -1
- package/dist-cjs/tree/TreeNodeExpansionIcon.css.js +6 -0
- package/dist-cjs/tree/TreeNodeExpansionIcon.css.js.map +1 -0
- package/dist-cjs/tree/TreeNodeExpansionIcon.js +62 -0
- package/dist-cjs/tree/TreeNodeExpansionIcon.js.map +1 -0
- package/dist-cjs/tree/TreeNodeLabel.css.js +6 -0
- package/dist-cjs/tree/TreeNodeLabel.css.js.map +1 -0
- package/dist-cjs/tree/TreeNodeLabel.js +26 -0
- package/dist-cjs/tree/TreeNodeLabel.js.map +1 -0
- package/dist-cjs/tree/TreeNodeTrigger.css.js +6 -0
- package/dist-cjs/tree/TreeNodeTrigger.css.js.map +1 -0
- package/dist-cjs/tree/TreeNodeTrigger.js +152 -0
- package/dist-cjs/tree/TreeNodeTrigger.js.map +1 -0
- package/dist-cjs/tree/useTree.js +305 -133
- package/dist-cjs/tree/useTree.js.map +1 -1
- package/dist-es/calendar/internal/CalendarDay.css.js +1 -1
- package/dist-es/combo-box-deprecated/internal/DefaultComboBox.js +1 -1
- package/dist-es/combo-box-deprecated/internal/MultiSelectComboBox.js +1 -1
- package/dist-es/combo-box-deprecated/internal/useComboBox.js +1 -1
- package/dist-es/combo-box-deprecated/internal/useMultiSelectComboBox.js +1 -1
- package/dist-es/common-hooks/useCollectionItems.js +1 -1
- package/dist-es/common-hooks/useSelection.js +1 -2
- package/dist-es/common-hooks/useSelection.js.map +1 -1
- package/dist-es/contact-details/ContactDetails.css.js +1 -1
- package/dist-es/date-input/DateInput.css.js +1 -1
- package/dist-es/date-input/DateInputRange.js +2 -8
- package/dist-es/date-input/DateInputRange.js.map +1 -1
- package/dist-es/date-input/DateInputSingle.js +1 -1
- package/dist-es/date-input/DateInputSingle.js.map +1 -1
- package/dist-es/dropdown/DropdownBase.js +1 -1
- package/dist-es/index.js +3 -1
- package/dist-es/index.js.map +1 -1
- package/dist-es/list-deprecated/ListItem.js.map +1 -1
- package/dist-es/rating/Rating.css.js +1 -1
- package/dist-es/rating/Rating.js +8 -7
- package/dist-es/rating/Rating.js.map +1 -1
- package/dist-es/tabs/drag-drop/useDragDropNaturalMovement.js +1 -1
- package/dist-es/tabs-next/TabListNext.js +1 -1
- package/dist-es/tabs-next/TabListNext.js.map +1 -1
- package/dist-es/tokenized-input/TokenizedInputBase.js +1 -1
- package/dist-es/tokenized-input-next/TokenizedInputNext.js +2 -2
- package/dist-es/tokenized-input-next/TokenizedInputNext.js.map +1 -1
- package/dist-es/tree/Tree.css.js +1 -1
- package/dist-es/tree/Tree.js +275 -208
- package/dist-es/tree/Tree.js.map +1 -1
- package/dist-es/tree/TreeContext.js +26 -0
- package/dist-es/tree/TreeContext.js.map +1 -0
- package/dist-es/tree/TreeNode.css.js +1 -1
- package/dist-es/tree/TreeNode.js +87 -43
- package/dist-es/tree/TreeNode.js.map +1 -1
- package/dist-es/tree/TreeNodeExpansionIcon.css.js +4 -0
- package/dist-es/tree/TreeNodeExpansionIcon.css.js.map +1 -0
- package/dist-es/tree/TreeNodeExpansionIcon.js +60 -0
- package/dist-es/tree/TreeNodeExpansionIcon.js.map +1 -0
- package/dist-es/tree/TreeNodeLabel.css.js +4 -0
- package/dist-es/tree/TreeNodeLabel.css.js.map +1 -0
- package/dist-es/tree/TreeNodeLabel.js +24 -0
- package/dist-es/tree/TreeNodeLabel.js.map +1 -0
- package/dist-es/tree/TreeNodeTrigger.css.js +4 -0
- package/dist-es/tree/TreeNodeTrigger.css.js.map +1 -0
- package/dist-es/tree/TreeNodeTrigger.js +150 -0
- package/dist-es/tree/TreeNodeTrigger.js.map +1 -0
- package/dist-es/tree/useTree.js +306 -134
- package/dist-es/tree/useTree.js.map +1 -1
- package/dist-types/date-input/DateInputRange.d.ts +1 -1
- package/dist-types/date-input/DateInputSingle.d.ts +1 -1
- package/dist-types/index.d.ts +0 -1
- package/dist-types/list-deprecated/ListItem.d.ts +1 -0
- package/dist-types/rating/Rating.d.ts +5 -6
- package/dist-types/tokenized-input/internal/InputPill.d.ts +1 -1
- package/dist-types/tokenized-input-next/internal/InputPill.d.ts +1 -1
- package/dist-types/tree/Tree.d.ts +36 -3
- package/dist-types/tree/TreeContext.d.ts +71 -0
- package/dist-types/tree/TreeNode.d.ts +23 -10
- package/dist-types/tree/TreeNodeExpansionIcon.d.ts +4 -0
- package/dist-types/tree/TreeNodeLabel.d.ts +4 -0
- package/dist-types/tree/TreeNodeTrigger.d.ts +8 -0
- package/dist-types/tree/index.d.ts +3 -0
- package/dist-types/tree/useTree.d.ts +79 -3
- package/package.json +3 -3
- package/dist-cjs/common-hooks/calcPreferredHeight.js +0 -27
- package/dist-cjs/common-hooks/calcPreferredHeight.js.map +0 -1
- package/dist-cjs/common-hooks/useAutoSizer.js +0 -33
- package/dist-cjs/common-hooks/useAutoSizer.js.map +0 -1
- package/dist-cjs/kbd/Kbd.css.js +0 -6
- package/dist-cjs/kbd/Kbd.css.js.map +0 -1
- package/dist-cjs/kbd/Kbd.js +0 -34
- package/dist-cjs/kbd/Kbd.js.map +0 -1
- package/dist-cjs/tree/use-tree-keyboard-navigation.js +0 -51
- package/dist-cjs/tree/use-tree-keyboard-navigation.js.map +0 -1
- package/dist-es/common-hooks/calcPreferredHeight.js +0 -25
- package/dist-es/common-hooks/calcPreferredHeight.js.map +0 -1
- package/dist-es/common-hooks/useAutoSizer.js +0 -31
- package/dist-es/common-hooks/useAutoSizer.js.map +0 -1
- package/dist-es/kbd/Kbd.css.js +0 -4
- package/dist-es/kbd/Kbd.css.js.map +0 -1
- package/dist-es/kbd/Kbd.js +0 -32
- package/dist-es/kbd/Kbd.js.map +0 -1
- package/dist-es/tree/use-tree-keyboard-navigation.js +0 -48
- package/dist-es/tree/use-tree-keyboard-navigation.js.map +0 -1
- package/dist-types/kbd/Kbd.d.ts +0 -8
- package/dist-types/kbd/index.d.ts +0 -1
- package/dist-types/tree/treeTypes.d.ts +0 -42
- package/dist-types/tree/use-tree-keyboard-navigation.d.ts +0 -15
package/dist-es/tree/useTree.js
CHANGED
|
@@ -1,157 +1,329 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import '
|
|
3
|
-
import '../common-hooks/keyUtils.js';
|
|
4
|
-
import { closestListItemIndex } from '../common-hooks/list-dom-utils.js';
|
|
5
|
-
import '@salt-ds/core';
|
|
6
|
-
import { useCollapsibleGroups } from '../common-hooks/useCollapsibleGroups.js';
|
|
7
|
-
import { useKeyboardNavigation } from '../common-hooks/useKeyboardNavigation.js';
|
|
8
|
-
import { useSelection } from '../common-hooks/useSelection.js';
|
|
9
|
-
import { useViewportTracking } from '../common-hooks/useViewportTracking.js';
|
|
10
|
-
import { useKeyboardNavigation as useKeyboardNavigation$1 } from './use-tree-keyboard-navigation.js';
|
|
1
|
+
import { useControlled } from '@salt-ds/core';
|
|
2
|
+
import { useMemo, useState, useRef, useCallback, Children, isValidElement } from 'react';
|
|
11
3
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
4
|
+
function buildTreeModel(children) {
|
|
5
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
6
|
+
const rootValues = [];
|
|
7
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
8
|
+
function traverse(reactChildren, parentValue, parentDisabled = false) {
|
|
9
|
+
const siblingValues = [];
|
|
10
|
+
Children.forEach(reactChildren, (child) => {
|
|
11
|
+
if (isValidElement(child) && typeof child.props.value === "string") {
|
|
12
|
+
const value = child.props.value;
|
|
13
|
+
const nodeChildren = child.props.children;
|
|
14
|
+
const hasChildren = Children.count(nodeChildren) > 0;
|
|
15
|
+
const disabled = parentDisabled || Boolean(child.props.disabled);
|
|
16
|
+
nodes.set(value, {
|
|
17
|
+
value,
|
|
18
|
+
parentValue,
|
|
19
|
+
hasChildren,
|
|
20
|
+
disabled
|
|
21
|
+
});
|
|
22
|
+
siblingValues.push(value);
|
|
23
|
+
if (hasChildren) {
|
|
24
|
+
traverse(nodeChildren, value, disabled);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (parentValue !== void 0) {
|
|
29
|
+
childrenOf.set(parentValue, siblingValues);
|
|
30
|
+
} else {
|
|
31
|
+
rootValues.push(...siblingValues);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
traverse(children);
|
|
35
|
+
return { nodes, rootValues, childrenOf };
|
|
36
|
+
}
|
|
37
|
+
function expandSelectionWithDescendants(selection, model, disabledIds) {
|
|
38
|
+
const expanded = new Set(selection);
|
|
39
|
+
function addDescendants(parentValue) {
|
|
40
|
+
const children = model.childrenOf.get(parentValue) ?? [];
|
|
41
|
+
for (const child of children) {
|
|
42
|
+
if (!disabledIds.has(child)) {
|
|
43
|
+
expanded.add(child);
|
|
44
|
+
addDescendants(child);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
for (const value of selection) {
|
|
49
|
+
addDescendants(value);
|
|
50
|
+
}
|
|
51
|
+
return Array.from(expanded);
|
|
52
|
+
}
|
|
53
|
+
function expandSelectionUpwards(selection, model, disabledIds) {
|
|
54
|
+
const selectedSet = new Set(selection);
|
|
55
|
+
for (const [value, meta] of model.nodes) {
|
|
56
|
+
if (meta.hasChildren && !selectedSet.has(value) && !disabledIds.has(value)) {
|
|
57
|
+
const children = model.childrenOf.get(value) ?? [];
|
|
58
|
+
const enabledChildren = children.filter((c) => !disabledIds.has(c));
|
|
59
|
+
if (enabledChildren.length > 0 && enabledChildren.every((c) => selectedSet.has(c))) {
|
|
60
|
+
selectedSet.add(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return Array.from(selectedSet);
|
|
65
|
+
}
|
|
66
|
+
function useTree(props) {
|
|
67
|
+
const {
|
|
68
|
+
defaultExpanded = [],
|
|
69
|
+
expanded: expandedProp,
|
|
70
|
+
onExpandedChange,
|
|
71
|
+
defaultSelected = [],
|
|
50
72
|
selected: selectedProp,
|
|
51
|
-
|
|
73
|
+
onSelectionChange,
|
|
74
|
+
multiselect = false,
|
|
75
|
+
disabled = false,
|
|
76
|
+
children
|
|
77
|
+
} = props;
|
|
78
|
+
const clampedDefaultSelected = multiselect ? defaultSelected : defaultSelected.slice(0, 1);
|
|
79
|
+
const clampedSelectedProp = selectedProp && !multiselect ? selectedProp.slice(0, 1) : selectedProp;
|
|
80
|
+
const treeModel = useMemo(() => buildTreeModel(children), [children]);
|
|
81
|
+
const disabledIdsSet = useMemo(() => {
|
|
82
|
+
const set = /* @__PURE__ */ new Set();
|
|
83
|
+
for (const [value, meta] of treeModel.nodes) {
|
|
84
|
+
if (meta.disabled) set.add(value);
|
|
85
|
+
}
|
|
86
|
+
return set;
|
|
87
|
+
}, [treeModel]);
|
|
88
|
+
const [expandedArray, setExpandedArray] = useControlled({
|
|
89
|
+
controlled: expandedProp,
|
|
90
|
+
default: defaultExpanded,
|
|
91
|
+
name: "Tree",
|
|
92
|
+
state: "expanded"
|
|
52
93
|
});
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
94
|
+
const expandedState = useMemo(() => new Set(expandedArray), [expandedArray]);
|
|
95
|
+
const expandedDefaultSelected = useMemo(() => {
|
|
96
|
+
if (!multiselect || clampedDefaultSelected.length === 0) {
|
|
97
|
+
return clampedDefaultSelected;
|
|
98
|
+
}
|
|
99
|
+
let expanded = expandSelectionWithDescendants(
|
|
100
|
+
clampedDefaultSelected,
|
|
101
|
+
treeModel,
|
|
102
|
+
disabledIdsSet
|
|
103
|
+
);
|
|
104
|
+
expanded = expandSelectionUpwards(expanded, treeModel, disabledIdsSet);
|
|
105
|
+
return expanded;
|
|
106
|
+
}, [clampedDefaultSelected, treeModel, disabledIdsSet, multiselect]);
|
|
107
|
+
const [selectedState, setSelectedState] = useControlled({
|
|
108
|
+
controlled: clampedSelectedProp,
|
|
109
|
+
default: expandedDefaultSelected,
|
|
110
|
+
name: "Tree",
|
|
111
|
+
state: "selected"
|
|
57
112
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
113
|
+
const selectedSet = useMemo(() => new Set(selectedState), [selectedState]);
|
|
114
|
+
const [activeNode, setActiveNode] = useState(void 0);
|
|
115
|
+
const elementsRef = useRef(/* @__PURE__ */ new Map());
|
|
116
|
+
const registerElement = (value, element) => {
|
|
117
|
+
elementsRef.current.set(value, element);
|
|
118
|
+
return () => {
|
|
119
|
+
elementsRef.current.delete(value);
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
const getElement = (value) => {
|
|
123
|
+
return elementsRef.current.get(value);
|
|
124
|
+
};
|
|
125
|
+
const getNodeMeta = useCallback(
|
|
126
|
+
(value) => {
|
|
127
|
+
return treeModel.nodes.get(value);
|
|
65
128
|
},
|
|
66
|
-
[
|
|
129
|
+
[treeModel]
|
|
67
130
|
);
|
|
68
|
-
const
|
|
69
|
-
(
|
|
70
|
-
var _a
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
131
|
+
const getParent = useCallback(
|
|
132
|
+
(value) => {
|
|
133
|
+
var _a;
|
|
134
|
+
return (_a = treeModel.nodes.get(value)) == null ? void 0 : _a.parentValue;
|
|
135
|
+
},
|
|
136
|
+
[treeModel]
|
|
137
|
+
);
|
|
138
|
+
const getChildren = useCallback(
|
|
139
|
+
(parentValue) => {
|
|
140
|
+
return treeModel.childrenOf.get(parentValue) ?? [];
|
|
141
|
+
},
|
|
142
|
+
[treeModel]
|
|
143
|
+
);
|
|
144
|
+
const getDescendants = useCallback(
|
|
145
|
+
(value) => {
|
|
146
|
+
const descendants = [];
|
|
147
|
+
function traverse(parentValue) {
|
|
148
|
+
const children2 = treeModel.childrenOf.get(parentValue) ?? [];
|
|
149
|
+
for (const child of children2) {
|
|
150
|
+
if (!disabledIdsSet.has(child)) {
|
|
151
|
+
descendants.push(child);
|
|
152
|
+
traverse(child);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
77
155
|
}
|
|
78
|
-
|
|
79
|
-
|
|
156
|
+
traverse(value);
|
|
157
|
+
return descendants;
|
|
158
|
+
},
|
|
159
|
+
[treeModel, disabledIdsSet]
|
|
160
|
+
);
|
|
161
|
+
const getAncestors = useCallback(
|
|
162
|
+
(value) => {
|
|
163
|
+
var _a, _b;
|
|
164
|
+
const ancestors = [];
|
|
165
|
+
let current = (_a = treeModel.nodes.get(value)) == null ? void 0 : _a.parentValue;
|
|
166
|
+
while (current) {
|
|
167
|
+
ancestors.push(current);
|
|
168
|
+
current = (_b = treeModel.nodes.get(current)) == null ? void 0 : _b.parentValue;
|
|
80
169
|
}
|
|
170
|
+
return ancestors;
|
|
81
171
|
},
|
|
82
|
-
[
|
|
83
|
-
collapsibleHook.onKeyDown,
|
|
84
|
-
keyboardHook.listProps,
|
|
85
|
-
selectionHook.listHandlers,
|
|
86
|
-
treeNavigationHook.listHandlers
|
|
87
|
-
]
|
|
172
|
+
[treeModel]
|
|
88
173
|
);
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
174
|
+
const toggleExpanded = useCallback(
|
|
175
|
+
(event, value) => {
|
|
176
|
+
const isExpanding = !expandedState.has(value);
|
|
177
|
+
const newExpanded = isExpanding ? [...expandedArray, value] : expandedArray.filter((v) => v !== value);
|
|
178
|
+
setExpandedArray(newExpanded);
|
|
179
|
+
onExpandedChange == null ? void 0 : onExpandedChange(event, newExpanded);
|
|
180
|
+
},
|
|
181
|
+
[expandedArray, expandedState, onExpandedChange]
|
|
182
|
+
);
|
|
183
|
+
const calculateIndeterminateState = useCallback(
|
|
184
|
+
(selected) => {
|
|
185
|
+
const indeterminate = /* @__PURE__ */ new Set();
|
|
186
|
+
const selectedSet2 = new Set(selected);
|
|
187
|
+
for (const selectedValue of selected) {
|
|
188
|
+
let current = getParent(selectedValue);
|
|
189
|
+
while (current) {
|
|
190
|
+
const children2 = getChildren(current);
|
|
191
|
+
const enabledChildren = children2.filter(
|
|
192
|
+
(child) => !disabledIdsSet.has(child)
|
|
193
|
+
);
|
|
194
|
+
if (enabledChildren.length === 0) {
|
|
195
|
+
current = getParent(current);
|
|
196
|
+
continue;
|
|
106
197
|
}
|
|
198
|
+
const selectedChildren = enabledChildren.filter(
|
|
199
|
+
(child) => selectedSet2.has(child)
|
|
200
|
+
);
|
|
201
|
+
const allChildrenSelected = selectedChildren.length === enabledChildren.length;
|
|
202
|
+
const someChildrenSelected = selectedChildren.length > 0;
|
|
203
|
+
const someChildrenIndeterminate = enabledChildren.some(
|
|
204
|
+
(child) => indeterminate.has(child)
|
|
205
|
+
);
|
|
206
|
+
if (someChildrenIndeterminate || someChildrenSelected && !allChildrenSelected) {
|
|
207
|
+
indeterminate.add(current);
|
|
208
|
+
}
|
|
209
|
+
current = getParent(current);
|
|
107
210
|
}
|
|
108
211
|
}
|
|
212
|
+
return indeterminate;
|
|
109
213
|
},
|
|
110
|
-
[
|
|
111
|
-
collectionHook.data,
|
|
112
|
-
disabled,
|
|
113
|
-
keyboardHook.setHighlightedIndex,
|
|
114
|
-
highlightedIdx,
|
|
115
|
-
isScrolling
|
|
116
|
-
]
|
|
214
|
+
[getParent, getChildren, disabledIdsSet]
|
|
117
215
|
);
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
216
|
+
const indeterminateState = useMemo(
|
|
217
|
+
() => multiselect ? calculateIndeterminateState(selectedState) : /* @__PURE__ */ new Set(),
|
|
218
|
+
[multiselect, selectedState, calculateIndeterminateState]
|
|
219
|
+
);
|
|
220
|
+
const updateAncestors = (currentSet, value) => {
|
|
221
|
+
const ancestors = getAncestors(value);
|
|
222
|
+
for (const ancestor of ancestors) {
|
|
223
|
+
const children2 = treeModel.childrenOf.get(ancestor) ?? [];
|
|
224
|
+
const enabledChildren = children2.filter(
|
|
225
|
+
(child) => !disabledIdsSet.has(child)
|
|
226
|
+
);
|
|
227
|
+
if (enabledChildren.length === 0) continue;
|
|
228
|
+
const allSelected = enabledChildren.every(
|
|
229
|
+
(child) => currentSet.has(child)
|
|
230
|
+
);
|
|
231
|
+
if (allSelected) {
|
|
232
|
+
currentSet.add(ancestor);
|
|
233
|
+
} else {
|
|
234
|
+
currentSet.delete(ancestor);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return Array.from(currentSet);
|
|
130
238
|
};
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
239
|
+
const getMultiSelectState = (value) => {
|
|
240
|
+
const currentSet = new Set(selectedState);
|
|
241
|
+
const descendants = getDescendants(value);
|
|
242
|
+
if (currentSet.has(value)) {
|
|
243
|
+
currentSet.delete(value);
|
|
244
|
+
const descendantSet = new Set(descendants);
|
|
245
|
+
for (const d of descendantSet) {
|
|
246
|
+
currentSet.delete(d);
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
currentSet.add(value);
|
|
250
|
+
for (const d of descendants) {
|
|
251
|
+
if (!currentSet.has(d)) {
|
|
252
|
+
currentSet.add(d);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
139
255
|
}
|
|
140
|
-
|
|
141
|
-
const listItemHandlers = {
|
|
142
|
-
onClick: handleClick
|
|
256
|
+
return updateAncestors(currentSet, value);
|
|
143
257
|
};
|
|
258
|
+
const select = useCallback(
|
|
259
|
+
(event, value) => {
|
|
260
|
+
if (disabled || disabledIdsSet.has(value)) return;
|
|
261
|
+
let newSelected;
|
|
262
|
+
if (multiselect) {
|
|
263
|
+
newSelected = getMultiSelectState(value);
|
|
264
|
+
} else {
|
|
265
|
+
const isCurrentlySelected = selectedSet.has(value);
|
|
266
|
+
newSelected = isCurrentlySelected ? [] : [value];
|
|
267
|
+
}
|
|
268
|
+
setSelectedState(newSelected);
|
|
269
|
+
onSelectionChange == null ? void 0 : onSelectionChange(event, newSelected);
|
|
270
|
+
},
|
|
271
|
+
[disabled, disabledIdsSet, multiselect, selectedState, onSelectionChange]
|
|
272
|
+
);
|
|
273
|
+
const visibleNodes = useMemo(() => {
|
|
274
|
+
const visible = [];
|
|
275
|
+
function traverse(values) {
|
|
276
|
+
for (const value of values) {
|
|
277
|
+
visible.push(value);
|
|
278
|
+
const nodeMeta = treeModel.nodes.get(value);
|
|
279
|
+
if ((nodeMeta == null ? void 0 : nodeMeta.hasChildren) && expandedState.has(value)) {
|
|
280
|
+
const children2 = treeModel.childrenOf.get(value) ?? [];
|
|
281
|
+
traverse(children2);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
traverse(treeModel.rootValues);
|
|
286
|
+
return visible;
|
|
287
|
+
}, [treeModel, expandedState]);
|
|
288
|
+
const tabbableNodeId = useMemo(() => {
|
|
289
|
+
if (activeNode) {
|
|
290
|
+
return activeNode;
|
|
291
|
+
}
|
|
292
|
+
const firstSelectedVisible = visibleNodes.find(
|
|
293
|
+
(node) => selectedSet.has(node)
|
|
294
|
+
);
|
|
295
|
+
if (firstSelectedVisible !== void 0) {
|
|
296
|
+
return firstSelectedVisible;
|
|
297
|
+
}
|
|
298
|
+
return visibleNodes[0];
|
|
299
|
+
}, [activeNode, selectedSet, visibleNodes]);
|
|
144
300
|
return {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
301
|
+
expandedArray,
|
|
302
|
+
setExpandedArray,
|
|
303
|
+
expandedState,
|
|
304
|
+
toggleExpanded,
|
|
305
|
+
selectedState,
|
|
306
|
+
selectedSet,
|
|
307
|
+
setSelectedState,
|
|
308
|
+
select,
|
|
309
|
+
multiselect,
|
|
310
|
+
disabled,
|
|
311
|
+
disabledIdsSet,
|
|
312
|
+
treeModel,
|
|
313
|
+
getNodeMeta,
|
|
314
|
+
getParent,
|
|
315
|
+
getChildren,
|
|
316
|
+
getDescendants,
|
|
317
|
+
getAncestors,
|
|
318
|
+
visibleNodes,
|
|
319
|
+
tabbableNodeId,
|
|
320
|
+
registerElement,
|
|
321
|
+
getElement,
|
|
322
|
+
activeNode,
|
|
323
|
+
setActiveNode,
|
|
324
|
+
indeterminateState
|
|
153
325
|
};
|
|
154
|
-
}
|
|
326
|
+
}
|
|
155
327
|
|
|
156
328
|
export { useTree };
|
|
157
329
|
//# sourceMappingURL=useTree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTree.js","sources":["../src/tree/useTree.ts"],"sourcesContent":["import {\n type KeyboardEvent,\n type MouseEvent,\n useCallback,\n useRef,\n} from \"react\";\nimport {\n closestListItemIndex,\n type ListHandlers,\n type SelectionStrategy,\n useCollapsibleGroups,\n useKeyboardNavigation,\n useSelection,\n useViewportTracking,\n} from \"../common-hooks\";\nimport type { ListControlProps } from \"../list/listTypes\";\nimport type { TreeHookProps, TreeHookResult } from \"./treeTypes\";\nimport { useKeyboardNavigation as useTreeNavigation } from \"./use-tree-keyboard-navigation\";\n\nexport const useTree = <Item, Selection extends SelectionStrategy = \"default\">({\n collectionHook,\n containerRef,\n contentRef = containerRef,\n defaultSelected,\n disabled,\n onSelect,\n onSelectionChange,\n onToggle,\n onHighlight: onHighlightProp,\n selected: selectedProp,\n selectionStrategy,\n}: // totalItemCount,\nTreeHookProps<Item, Selection>): TreeHookResult<Item, Selection> => {\n const lastSelection = useRef(selectedProp || defaultSelected);\n\n const handleKeyboardNavigation = (\n evt: KeyboardEvent<HTMLElement>,\n nextIdx: number,\n ) => {\n selectionHook.listHandlers.onKeyboardNavigation?.(evt, nextIdx);\n };\n\n const { highlightedIndex: highlightedIdx, ...keyboardHook } =\n useKeyboardNavigation<Item, Selection>({\n containerRef,\n indexPositions: collectionHook.data,\n onHighlight: onHighlightProp,\n onKeyboardNavigation: handleKeyboardNavigation,\n selected: lastSelection.current,\n });\n\n const collapsibleHook = useCollapsibleGroups<Item>({\n collapsibleHeaders: true,\n collectionHook,\n highlightedIdx,\n onToggle,\n });\n\n const selectionHook = useSelection({\n defaultSelected,\n // groupSelection,\n highlightedIdx,\n indexPositions: collectionHook.data,\n onSelect,\n onSelectionChange,\n selected: selectedProp,\n selectionStrategy: selectionStrategy,\n });\n\n const treeNavigationHook = useTreeNavigation<Item>({\n collectionHook,\n highlightedIdx,\n highlightItemAtIndex: keyboardHook.setHighlightedIndex,\n });\n\n const handleClick = useCallback(\n (evt: MouseEvent<HTMLElement>) => {\n collapsibleHook?.onClick?.(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onClick?.(evt);\n }\n },\n [collapsibleHook, selectionHook],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n keyboardHook.listProps.onKeyDown?.(evt);\n if (!evt.defaultPrevented) {\n selectionHook.listHandlers.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n collapsibleHook?.onKeyDown?.(evt);\n }\n if (!evt.defaultPrevented) {\n treeNavigationHook.listHandlers.onKeyDown?.(evt);\n }\n },\n [\n collapsibleHook.onKeyDown,\n keyboardHook.listProps,\n selectionHook.listHandlers,\n treeNavigationHook.listHandlers,\n ],\n );\n\n // This is only appropriate when we are directly controlling a List,\n // not when a control is manipulating the list\n const { isScrolling } = useViewportTracking({\n containerRef,\n contentRef,\n highlightedIdx,\n indexPositions: collectionHook.data,\n });\n\n const handleMouseMove = useCallback(\n (evt: MouseEvent) => {\n if (!isScrolling.current && !disabled) {\n keyboardHook.listProps.onMouseMove();\n const idx = closestListItemIndex(evt.target as HTMLElement);\n if (idx !== undefined && idx !== highlightedIdx) {\n const item = collectionHook.data[idx];\n if (item.disabled) {\n keyboardHook.setHighlightedIndex(-1);\n } else {\n keyboardHook.setHighlightedIndex(idx);\n }\n }\n }\n },\n [\n collectionHook.data,\n disabled,\n keyboardHook.setHighlightedIndex,\n highlightedIdx,\n isScrolling,\n ],\n );\n\n const getActiveDescendant = () =>\n highlightedIdx === undefined || highlightedIdx === -1\n ? undefined\n : collectionHook.data[highlightedIdx]?.id;\n\n // We need this on reEntry for navigation hook to handle focus\n lastSelection.current = selectionHook.selected;\n\n const listProps: ListControlProps = {\n \"aria-activedescendant\": getActiveDescendant(),\n onBlur: keyboardHook.listProps.onBlur,\n onFocus: keyboardHook.listProps.onFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: keyboardHook.listProps.onMouseDownCapture,\n onMouseLeave: keyboardHook.listProps.onMouseLeave,\n };\n\n const listHandlers: ListHandlers = /*listHandlersProp || */ {\n onClick: handleClick,\n // MouseEnter would be much better for this. There is a bug in Cypress\n // wheby it emits spurious MouseEnter (and MouseOver) events around\n // keypress events, which break many tests.\n onMouseMove: handleMouseMove,\n };\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n focusVisible: keyboardHook.focusVisible,\n highlightedIdx,\n highlightItemAtIndex: keyboardHook.setHighlightedIndex,\n listHandlers,\n listProps,\n listItemHandlers,\n selected: selectionHook.selected,\n setSelected: selectionHook.setSelected,\n };\n};\n"],"names":["useTreeNavigation"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useTree.js","sources":["../src/tree/useTree.ts"],"sourcesContent":["import { useControlled } from \"@salt-ds/core\";\nimport {\n Children,\n isValidElement,\n type ReactNode,\n type SyntheticEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface UseTreeProps {\n /**\n * Default expanded nodes (uncontrolled)\n */\n defaultExpanded?: string[];\n /**\n * Expanded nodes (controlled)\n */\n expanded?: string[];\n /**\n * Callback on expanded nodes change\n */\n onExpandedChange?: (event: SyntheticEvent, expanded: string[]) => void;\n /**\n * Default selected nodes (uncontrolled)\n */\n defaultSelected?: string[];\n /**\n * Selected nodes\n */\n selected?: string[];\n /**\n * Callback on selected nodes change\n */\n onSelectionChange?: (event: SyntheticEvent, selected: string[]) => void;\n /**\n * Sets multiselect mode with checkboxes and allows for multiple node selection\n */\n multiselect?: boolean;\n /**\n * Sets tree to disabled state, preventing all interaction\n */\n disabled?: boolean;\n /**\n * Tree children used to build the tree model for traversal an state management\n */\n children?: ReactNode;\n}\n\nexport interface TreeNodeMeta {\n value: string;\n parentValue: string | undefined;\n hasChildren: boolean;\n disabled: boolean;\n}\n\nexport interface TreeModel {\n /** All nodes indexed by value */\n nodes: Map<string, TreeNodeMeta>;\n /** Ordered list of root node values */\n rootValues: string[];\n /** Maps parent value to ordered list of child values */\n childrenOf: Map<string, string[]>;\n}\n\nfunction buildTreeModel(children: ReactNode): TreeModel {\n const nodes = new Map<string, TreeNodeMeta>();\n const rootValues: string[] = [];\n const childrenOf = new Map<string, string[]>();\n\n function traverse(\n reactChildren: ReactNode,\n parentValue?: string,\n parentDisabled = false,\n ): void {\n const siblingValues: string[] = [];\n\n Children.forEach(reactChildren, (child) => {\n if (isValidElement(child) && typeof child.props.value === \"string\") {\n const value = child.props.value;\n const nodeChildren = child.props.children;\n const hasChildren = Children.count(nodeChildren) > 0;\n const disabled = parentDisabled || Boolean(child.props.disabled);\n\n nodes.set(value, {\n value,\n parentValue,\n hasChildren,\n disabled,\n });\n\n siblingValues.push(value);\n\n // Process children recursively and pass down disabled state\n if (hasChildren) {\n traverse(nodeChildren, value, disabled);\n }\n }\n });\n\n // Ordered children of parent\n if (parentValue !== undefined) {\n childrenOf.set(parentValue, siblingValues);\n } else {\n // ...and the root nodes\n rootValues.push(...siblingValues);\n }\n }\n\n traverse(children);\n\n return { nodes, rootValues, childrenOf };\n}\n\nfunction expandSelectionWithDescendants(\n selection: string[],\n model: TreeModel,\n disabledIds: Set<string>,\n): string[] {\n const expanded = new Set(selection);\n\n function addDescendants(parentValue: string): void {\n const children = model.childrenOf.get(parentValue) ?? [];\n for (const child of children) {\n if (!disabledIds.has(child)) {\n expanded.add(child);\n addDescendants(child);\n }\n }\n }\n\n for (const value of selection) {\n addDescendants(value);\n }\n\n return Array.from(expanded);\n}\n\nfunction expandSelectionUpwards(\n selection: string[],\n model: TreeModel,\n disabledIds: Set<string>,\n): string[] {\n const selectedSet = new Set(selection);\n\n for (const [value, meta] of model.nodes) {\n if (\n meta.hasChildren &&\n !selectedSet.has(value) &&\n !disabledIds.has(value)\n ) {\n const children = model.childrenOf.get(value) ?? [];\n const enabledChildren = children.filter((c) => !disabledIds.has(c));\n\n if (\n enabledChildren.length > 0 &&\n enabledChildren.every((c) => selectedSet.has(c))\n ) {\n selectedSet.add(value);\n }\n }\n }\n\n return Array.from(selectedSet);\n}\n\nexport function useTree(props: UseTreeProps) {\n const {\n defaultExpanded = [],\n expanded: expandedProp,\n onExpandedChange,\n defaultSelected = [],\n selected: selectedProp,\n onSelectionChange,\n multiselect = false,\n disabled = false,\n children,\n } = props;\n\n const clampedDefaultSelected = multiselect\n ? defaultSelected\n : defaultSelected.slice(0, 1);\n\n const clampedSelectedProp =\n selectedProp && !multiselect ? selectedProp.slice(0, 1) : selectedProp;\n\n const treeModel = useMemo(() => buildTreeModel(children), [children]);\n\n const disabledIdsSet = useMemo(() => {\n const set = new Set<string>();\n for (const [value, meta] of treeModel.nodes) {\n if (meta.disabled) set.add(value);\n }\n return set;\n }, [treeModel]);\n\n const [expandedArray, setExpandedArray] = useControlled({\n controlled: expandedProp,\n default: defaultExpanded,\n name: \"Tree\",\n state: \"expanded\",\n });\n\n // Convert array to Set for more efficient lookups during rendering and nav\n const expandedState = useMemo(() => new Set(expandedArray), [expandedArray]);\n\n const expandedDefaultSelected = useMemo(() => {\n if (!multiselect || clampedDefaultSelected.length === 0) {\n return clampedDefaultSelected;\n }\n\n let expanded = expandSelectionWithDescendants(\n clampedDefaultSelected,\n treeModel,\n disabledIdsSet,\n );\n\n expanded = expandSelectionUpwards(expanded, treeModel, disabledIdsSet);\n\n return expanded;\n }, [clampedDefaultSelected, treeModel, disabledIdsSet, multiselect]);\n\n const [selectedState, setSelectedState] = useControlled({\n controlled: clampedSelectedProp,\n default: expandedDefaultSelected,\n name: \"Tree\",\n state: \"selected\",\n });\n\n const selectedSet = useMemo(() => new Set(selectedState), [selectedState]);\n\n const [activeNode, setActiveNode] = useState<string | undefined>(undefined);\n\n const elementsRef = useRef<Map<string, HTMLElement>>(new Map());\n\n const registerElement = (value: string, element: HTMLElement) => {\n elementsRef.current.set(value, element);\n return () => {\n elementsRef.current.delete(value);\n };\n };\n\n const getElement = (value: string): HTMLElement | undefined => {\n return elementsRef.current.get(value);\n };\n\n const getNodeMeta = useCallback(\n (value: string): TreeNodeMeta | undefined => {\n return treeModel.nodes.get(value);\n },\n [treeModel],\n );\n\n const getParent = useCallback(\n (value: string): string | undefined => {\n return treeModel.nodes.get(value)?.parentValue;\n },\n [treeModel],\n );\n\n const getChildren = useCallback(\n (parentValue: string): string[] => {\n return treeModel.childrenOf.get(parentValue) ?? [];\n },\n [treeModel],\n );\n\n // Depth-first search (with pre-order traversal)\n const getDescendants = useCallback(\n (value: string): string[] => {\n const descendants: string[] = [];\n\n function traverse(parentValue: string): void {\n const children = treeModel.childrenOf.get(parentValue) ?? [];\n for (const child of children) {\n if (!disabledIdsSet.has(child)) {\n descendants.push(child);\n traverse(child);\n }\n }\n }\n\n traverse(value);\n return descendants;\n },\n [treeModel, disabledIdsSet],\n );\n\n const getAncestors = useCallback(\n (value: string): string[] => {\n const ancestors: string[] = [];\n let current = treeModel.nodes.get(value)?.parentValue;\n\n while (current) {\n ancestors.push(current);\n current = treeModel.nodes.get(current)?.parentValue;\n }\n\n return ancestors;\n },\n [treeModel],\n );\n\n const toggleExpanded = useCallback(\n (event: SyntheticEvent, value: string) => {\n const isExpanding = !expandedState.has(value);\n const newExpanded = isExpanding\n ? [...expandedArray, value]\n : expandedArray.filter((v) => v !== value);\n\n setExpandedArray(newExpanded);\n onExpandedChange?.(event, newExpanded);\n },\n [expandedArray, expandedState, onExpandedChange],\n );\n\n const calculateIndeterminateState = useCallback(\n (selected: string[]): Set<string> => {\n const indeterminate = new Set<string>();\n const selectedSet = new Set(selected);\n\n for (const selectedValue of selected) {\n let current = getParent(selectedValue);\n\n while (current) {\n const children = getChildren(current);\n const enabledChildren = children.filter(\n (child) => !disabledIdsSet.has(child),\n );\n\n if (enabledChildren.length === 0) {\n current = getParent(current);\n continue;\n }\n\n const selectedChildren = enabledChildren.filter((child) =>\n selectedSet.has(child),\n );\n const allChildrenSelected =\n selectedChildren.length === enabledChildren.length;\n const someChildrenSelected = selectedChildren.length > 0;\n\n const someChildrenIndeterminate = enabledChildren.some((child) =>\n indeterminate.has(child),\n );\n\n if (\n someChildrenIndeterminate ||\n (someChildrenSelected && !allChildrenSelected)\n ) {\n indeterminate.add(current);\n }\n\n current = getParent(current);\n }\n }\n\n return indeterminate;\n },\n [getParent, getChildren, disabledIdsSet],\n );\n\n const indeterminateState = useMemo(\n () =>\n multiselect\n ? calculateIndeterminateState(selectedState)\n : new Set<string>(),\n [multiselect, selectedState, calculateIndeterminateState],\n );\n\n const updateAncestors = (\n currentSet: Set<string>,\n value: string,\n ): string[] => {\n const ancestors = getAncestors(value);\n\n for (const ancestor of ancestors) {\n const children = treeModel.childrenOf.get(ancestor) ?? [];\n const enabledChildren = children.filter(\n (child) => !disabledIdsSet.has(child),\n );\n\n if (enabledChildren.length === 0) continue;\n\n const allSelected = enabledChildren.every((child) =>\n currentSet.has(child),\n );\n\n if (allSelected) {\n currentSet.add(ancestor);\n } else {\n currentSet.delete(ancestor);\n }\n }\n\n return Array.from(currentSet);\n };\n\n const getMultiSelectState = (value: string) => {\n const currentSet = new Set(selectedState);\n const descendants = getDescendants(value);\n\n if (currentSet.has(value)) {\n currentSet.delete(value);\n const descendantSet = new Set(descendants);\n for (const d of descendantSet) {\n currentSet.delete(d);\n }\n } else {\n currentSet.add(value);\n for (const d of descendants) {\n if (!currentSet.has(d)) {\n currentSet.add(d);\n }\n }\n }\n\n return updateAncestors(currentSet, value);\n };\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: getMultiSelectState/updateAncestors are intentionally not memoized - their captured values (selectedState, treeModel, etc.) are already in deps\n const select = useCallback(\n (event: SyntheticEvent, value: string) => {\n if (disabled || disabledIdsSet.has(value)) return;\n\n let newSelected: string[];\n\n if (multiselect) {\n newSelected = getMultiSelectState(value);\n } else {\n const isCurrentlySelected = selectedSet.has(value);\n newSelected = isCurrentlySelected ? [] : [value];\n }\n\n setSelectedState(newSelected);\n onSelectionChange?.(event, newSelected);\n },\n [disabled, disabledIdsSet, multiselect, selectedState, onSelectionChange],\n );\n\n // Visible nodes in depth-first order matching visual tree order\n const visibleNodes = useMemo((): string[] => {\n const visible: string[] = [];\n\n function traverse(values: string[]): void {\n for (const value of values) {\n visible.push(value);\n\n const nodeMeta = treeModel.nodes.get(value);\n if (nodeMeta?.hasChildren && expandedState.has(value)) {\n const children = treeModel.childrenOf.get(value) ?? [];\n traverse(children);\n }\n }\n }\n\n traverse(treeModel.rootValues);\n return visible;\n }, [treeModel, expandedState]);\n\n const tabbableNodeId = useMemo((): string | undefined => {\n if (activeNode) {\n return activeNode;\n }\n\n const firstSelectedVisible = visibleNodes.find((node) =>\n selectedSet.has(node),\n );\n\n if (firstSelectedVisible !== undefined) {\n return firstSelectedVisible;\n }\n\n return visibleNodes[0];\n }, [activeNode, selectedSet, visibleNodes]);\n\n return {\n expandedArray,\n setExpandedArray,\n expandedState,\n toggleExpanded,\n selectedState,\n selectedSet,\n setSelectedState,\n select,\n multiselect,\n disabled,\n disabledIdsSet,\n treeModel,\n getNodeMeta,\n getParent,\n getChildren,\n getDescendants,\n getAncestors,\n visibleNodes,\n tabbableNodeId,\n registerElement,\n getElement,\n activeNode,\n setActiveNode,\n indeterminateState,\n };\n}\n"],"names":["children","selectedSet"],"mappings":"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"}
|
|
@@ -68,7 +68,7 @@ export interface DateInputRangeProps<TDate extends DateFrameworkType> extends Om
|
|
|
68
68
|
/**
|
|
69
69
|
* Styling variant. Defaults to "primary".
|
|
70
70
|
*/
|
|
71
|
-
variant?: "primary" | "secondary";
|
|
71
|
+
variant?: "primary" | "secondary" | "tertiary";
|
|
72
72
|
/**
|
|
73
73
|
* Format string for date.
|
|
74
74
|
*/
|
|
@@ -47,7 +47,7 @@ export interface DateInputSingleProps<TDate extends DateFrameworkType> extends O
|
|
|
47
47
|
/**
|
|
48
48
|
* Styling variant. Defaults to "primary".
|
|
49
49
|
*/
|
|
50
|
-
variant?: "primary" | "secondary";
|
|
50
|
+
variant?: "primary" | "secondary" | "tertiary";
|
|
51
51
|
/**
|
|
52
52
|
* Format string for date.
|
|
53
53
|
*/
|
package/dist-types/index.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export { FormFieldLegacy as FormField, type FormFieldLegacyProps as FormFieldPro
|
|
|
20
20
|
export * from "./form-group";
|
|
21
21
|
export * from "./formatted-input";
|
|
22
22
|
export { InputLegacy as Input, type InputLegacyProps as InputProps, StaticInputAdornment, } from "./input-legacy";
|
|
23
|
-
export * from "./kbd";
|
|
24
23
|
export * from "./layer-layout";
|
|
25
24
|
export * from "./list";
|
|
26
25
|
export type { ListChangeHandler as ListChangeHandlerDeprecated, ListSelectHandler as ListSelectHandlerDeprecated, } from "./list-deprecated";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** biome-ignore-all lint/correctness/useHookAtTopLevel: biome doesn't recognise the component correctly */
|
|
1
2
|
import { type ForwardedRef, type ReactElement } from "react";
|
|
2
3
|
import { type ListItemBaseProps } from "./ListItemBase";
|
|
3
4
|
export interface ListItemProps<Item = string> extends Omit<ListItemBaseProps, "focusVisible" | "highlighted" | "selected" | "tooltipText"> {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
3
|
-
export interface RatingProps extends Omit<FlexLayoutProps<"div">, "onChange"> {
|
|
1
|
+
import { type ChangeEvent, type ComponentPropsWithoutRef } from "react";
|
|
2
|
+
export interface RatingProps extends Omit<ComponentPropsWithoutRef<"div">, "onChange"> {
|
|
4
3
|
/**
|
|
5
4
|
* When provided, the component is controlled.
|
|
6
5
|
*/
|
|
@@ -29,11 +28,11 @@ export interface RatingProps extends Omit<FlexLayoutProps<"div">, "onChange"> {
|
|
|
29
28
|
*/
|
|
30
29
|
max?: number;
|
|
31
30
|
/**
|
|
32
|
-
* Function used to
|
|
31
|
+
* Function used to provide a user-friendly name for the current value of the rating. Primarily used by screen readers.
|
|
33
32
|
*/
|
|
34
33
|
getLabel?: (value: number) => string;
|
|
35
34
|
/**
|
|
36
|
-
* Function used to
|
|
35
|
+
* Function used to provide a visible label for the rating.
|
|
37
36
|
*/
|
|
38
37
|
getVisibleLabel?: (value: number, max: number) => string;
|
|
39
38
|
/**
|
|
@@ -47,4 +46,4 @@ export interface RatingProps extends Omit<FlexLayoutProps<"div">, "onChange"> {
|
|
|
47
46
|
*/
|
|
48
47
|
name?: string;
|
|
49
48
|
}
|
|
50
|
-
export declare const Rating: import("react").ForwardRefExoticComponent<
|
|
49
|
+
export declare const Rating: import("react").ForwardRefExoticComponent<RatingProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -30,4 +30,4 @@ export type InputPillProps = PillProps & {
|
|
|
30
30
|
*/
|
|
31
31
|
onDelete?: (index: number) => void;
|
|
32
32
|
};
|
|
33
|
-
export declare const InputPill: import("react").
|
|
33
|
+
export declare const InputPill: import("react").MemoExoticComponent<(props: InputPillProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -26,4 +26,4 @@ export type InputPillProps = PillProps & {
|
|
|
26
26
|
*/
|
|
27
27
|
onClose?: (event: SyntheticEvent, index: number) => void;
|
|
28
28
|
};
|
|
29
|
-
export declare const InputPill: import("react").
|
|
29
|
+
export declare const InputPill: import("react").MemoExoticComponent<(props: InputPillProps) => import("react/jsx-runtime").JSX.Element>;
|