@vuu-ui/vuu-ui-controls 0.9.0 → 0.9.2
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/cjs/cycle-state-button/CycleStateButton.js +2 -6
- package/cjs/cycle-state-button/CycleStateButton.js.map +1 -1
- package/cjs/editable/useEditableText.js +69 -50
- package/cjs/editable/useEditableText.js.map +1 -1
- package/cjs/icon-button/ToggleIconButton.css.js +6 -0
- package/cjs/icon-button/ToggleIconButton.css.js.map +1 -0
- package/cjs/icon-button/ToggleIconButton.js +38 -0
- package/cjs/icon-button/ToggleIconButton.js.map +1 -0
- package/cjs/index.js +2 -1
- package/cjs/index.js.map +1 -1
- package/cjs/tree/Tree.js.map +1 -1
- package/cjs/tree/hierarchical-data-utils.js.map +1 -1
- package/cjs/tree/treeTypeUtils.js.map +1 -1
- package/cjs/tree/use-collapsible-groups.js.map +1 -1
- package/cjs/tree/use-hierarchical-data.js.map +1 -1
- package/cjs/tree/use-items-with-ids.js.map +1 -1
- package/cjs/tree/use-keyboard-navigation.js.map +1 -1
- package/cjs/tree/use-selection.js.map +1 -1
- package/cjs/tree/use-tree-keyboard-navigation.js.map +1 -1
- package/cjs/tree/useTree.js +2 -2
- package/cjs/tree/useTree.js.map +1 -1
- package/esm/cycle-state-button/CycleStateButton.js +2 -6
- package/esm/cycle-state-button/CycleStateButton.js.map +1 -1
- package/esm/editable/useEditableText.js +72 -52
- package/esm/editable/useEditableText.js.map +1 -1
- package/esm/icon-button/ToggleIconButton.css.js +4 -0
- package/esm/icon-button/ToggleIconButton.css.js.map +1 -0
- package/esm/icon-button/ToggleIconButton.js +36 -0
- package/esm/icon-button/ToggleIconButton.js.map +1 -0
- package/esm/index.js +2 -1
- package/esm/index.js.map +1 -1
- package/esm/tree/Tree.js.map +1 -1
- package/esm/tree/hierarchical-data-utils.js.map +1 -1
- package/esm/tree/treeTypeUtils.js.map +1 -1
- package/esm/tree/use-collapsible-groups.js.map +1 -1
- package/esm/tree/use-hierarchical-data.js.map +1 -1
- package/esm/tree/use-items-with-ids.js.map +1 -1
- package/esm/tree/use-keyboard-navigation.js.map +1 -1
- package/esm/tree/use-selection.js.map +1 -1
- package/esm/tree/use-tree-keyboard-navigation.js.map +1 -1
- package/esm/tree/useTree.js +2 -2
- package/esm/tree/useTree.js.map +1 -1
- package/package.json +8 -8
- package/types/cycle-state-button/CycleStateButton.d.ts +3 -4
- package/types/editable/useEditableText.d.ts +5 -6
- package/types/icon-button/ToggleIconButton.d.ts +6 -0
- package/types/icon-button/index.d.ts +1 -0
- package/types/tree/Tree.d.ts +1 -1
- package/types/tree/hierarchical-data-utils.d.ts +1 -1
- package/types/tree/index.d.ts +0 -1
- package/types/tree/treeTypeUtils.d.ts +1 -1
- package/types/tree/use-collapsible-groups.d.ts +1 -1
- package/types/tree/use-hierarchical-data.d.ts +1 -1
- package/types/tree/use-items-with-ids.d.ts +1 -1
- package/types/tree/use-keyboard-navigation.d.ts +1 -1
- package/types/tree/use-selection.d.ts +1 -1
- package/types/tree/use-tree-keyboard-navigation.d.ts +1 -1
- package/types/tree/useTree.d.ts +1 -1
- package/types/tree/treeTypes.d.ts +0 -17
|
@@ -23,14 +23,10 @@ const CycleStateButton = React.forwardRef(function CycleStateButton2({
|
|
|
23
23
|
...buttonProps
|
|
24
24
|
}, forwardedRef) {
|
|
25
25
|
const handleClick = React.useCallback(
|
|
26
|
-
(evt) => {
|
|
26
|
+
async (evt) => {
|
|
27
27
|
const nextValue = getNextValue(value, values);
|
|
28
28
|
onChange?.(nextValue);
|
|
29
|
-
onCommit?.(evt, nextValue)
|
|
30
|
-
if (response !== true) {
|
|
31
|
-
console.error(response);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
29
|
+
onCommit?.(evt, nextValue);
|
|
34
30
|
},
|
|
35
31
|
[onChange, onCommit, value, values]
|
|
36
32
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CycleStateButton.js","sources":["../../src/cycle-state-button/CycleStateButton.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport type {
|
|
1
|
+
{"version":3,"file":"CycleStateButton.js","sources":["../../src/cycle-state-button/CycleStateButton.tsx"],"sourcesContent":["import { Button, ButtonProps } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport type {\n VuuColumnDataType,\n VuuRowDataItemType,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport { ForwardedRef, forwardRef, SyntheticEvent, useCallback } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuCycleStateButton\";\n\nexport interface CycleStateButtonProps extends Omit<ButtonProps, \"onChange\"> {\n onChange?: (value: VuuRowDataItemType) => void;\n onCommit?: CommitHandler<HTMLButtonElement>;\n values: string[];\n value: string;\n}\n\nconst getNextValue = (value: string, valueList: string[]) => {\n const index = valueList\n .map((v) => v.toUpperCase())\n .indexOf(value.toUpperCase());\n if (index === valueList.length - 1) {\n return valueList[0];\n } else {\n return valueList[index + 1];\n }\n};\n\nexport const CycleStateButton = forwardRef(function CycleStateButton(\n {\n className,\n onChange,\n onCommit,\n value = \"\",\n values,\n ...buttonProps\n }: CycleStateButtonProps,\n forwardedRef: ForwardedRef<HTMLButtonElement>,\n) {\n const handleClick = useCallback(\n async (evt: SyntheticEvent<HTMLButtonElement>) => {\n const nextValue = getNextValue(value, values);\n onChange?.(nextValue);\n onCommit?.(evt, nextValue as VuuColumnDataType);\n },\n [onChange, onCommit, value, values],\n );\n\n return (\n <Button\n {...buttonProps}\n className={cx(\n classBase,\n className,\n `${classBase}-${value.toLowerCase()}`,\n )}\n onClick={handleClick}\n ref={forwardedRef}\n >\n {value}\n </Button>\n );\n});\n"],"names":["forwardRef","CycleStateButton","useCallback","jsx","Button"],"mappings":";;;;;;;AASA,MAAM,SAAY,GAAA,qBAAA,CAAA;AASlB,MAAM,YAAA,GAAe,CAAC,KAAA,EAAe,SAAwB,KAAA;AAC3D,EAAA,MAAM,KAAQ,GAAA,SAAA,CACX,GAAI,CAAA,CAAC,CAAM,KAAA,CAAA,CAAE,WAAY,EAAC,CAC1B,CAAA,OAAA,CAAQ,KAAM,CAAA,WAAA,EAAa,CAAA,CAAA;AAC9B,EAAI,IAAA,KAAA,KAAU,SAAU,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,IAAA,OAAO,UAAU,CAAC,CAAA,CAAA;AAAA,GACb,MAAA;AACL,IAAO,OAAA,SAAA,CAAU,QAAQ,CAAC,CAAA,CAAA;AAAA,GAC5B;AACF,CAAA,CAAA;AAEa,MAAA,gBAAA,GAAmBA,gBAAW,CAAA,SAASC,iBAClD,CAAA;AAAA,EACE,SAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAQ,GAAA,EAAA;AAAA,EACR,MAAA;AAAA,EACA,GAAG,WAAA;AACL,CAAA,EACA,YACA,EAAA;AACA,EAAA,MAAM,WAAc,GAAAC,iBAAA;AAAA,IAClB,OAAO,GAA2C,KAAA;AAChD,MAAM,MAAA,SAAA,GAAY,YAAa,CAAA,KAAA,EAAO,MAAM,CAAA,CAAA;AAC5C,MAAA,QAAA,GAAW,SAAS,CAAA,CAAA;AACpB,MAAA,QAAA,GAAW,KAAK,SAA8B,CAAA,CAAA;AAAA,KAChD;AAAA,IACA,CAAC,QAAA,EAAU,QAAU,EAAA,KAAA,EAAO,MAAM,CAAA;AAAA,GACpC,CAAA;AAEA,EACE,uBAAAC,cAAA;AAAA,IAACC,WAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,SAAW,EAAA,EAAA;AAAA,QACT,SAAA;AAAA,QACA,SAAA;AAAA,QACA,CAAG,EAAA,SAAS,CAAI,CAAA,EAAA,KAAA,CAAM,aAAa,CAAA,CAAA;AAAA,OACrC;AAAA,MACA,OAAS,EAAA,WAAA;AAAA,MACT,GAAK,EAAA,YAAA;AAAA,MAEJ,QAAA,EAAA,KAAA;AAAA,KAAA;AAAA,GACH,CAAA;AAEJ,CAAC;;;;"}
|
|
@@ -3,51 +3,54 @@
|
|
|
3
3
|
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
console.warn(
|
|
8
|
-
"onCommit handler has not been provided to InputCell cell renderer"
|
|
9
|
-
);
|
|
10
|
-
return Promise.resolve(true);
|
|
11
|
-
};
|
|
6
|
+
const stringValueOf = (value) => value?.toString() ?? "";
|
|
12
7
|
const useEditableText = ({
|
|
13
8
|
clientSideEditValidationCheck,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
type
|
|
9
|
+
value,
|
|
10
|
+
onEdit,
|
|
11
|
+
type = "string"
|
|
17
12
|
}) => {
|
|
18
|
-
const [
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const [editState, setEditState] = React.useState({
|
|
14
|
+
value: stringValueOf(value)
|
|
15
|
+
});
|
|
16
|
+
const initialValueRef = React.useRef(value?.toString() ?? "");
|
|
21
17
|
const isDirtyRef = React.useRef(false);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
React.useMemo(() => {
|
|
19
|
+
if (initialValueRef.current !== value?.toString()) {
|
|
20
|
+
initialValueRef.current = stringValueOf(value);
|
|
21
|
+
setEditState({ message: "", value: stringValueOf(value) });
|
|
22
|
+
console.log("initial value changed to: ", value);
|
|
23
|
+
}
|
|
24
|
+
}, [value]);
|
|
26
25
|
const commit = React.useCallback(
|
|
27
|
-
(target) => {
|
|
26
|
+
async (target) => {
|
|
27
|
+
const { value: value2 } = editState;
|
|
28
28
|
if (isDirtyRef.current) {
|
|
29
|
-
|
|
30
|
-
const result = clientSideEditValidationCheck?.(value);
|
|
29
|
+
const result = clientSideEditValidationCheck?.(value2, "*");
|
|
31
30
|
if (result?.ok === false) {
|
|
32
|
-
|
|
31
|
+
setEditState((state) => ({
|
|
32
|
+
...state,
|
|
33
|
+
message: result?.messages?.join(",")
|
|
34
|
+
}));
|
|
33
35
|
} else {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
36
|
+
setEditState((state) => ({ ...state, message: void 0 }));
|
|
37
|
+
const response = await onEdit?.(
|
|
38
|
+
{ editType: "commit", value: value2, isValid: true },
|
|
39
|
+
"commit"
|
|
40
|
+
);
|
|
41
|
+
if (response === true) {
|
|
42
|
+
isDirtyRef.current = false;
|
|
43
|
+
initialValueRef.current = value2;
|
|
44
|
+
vuuUtils.dispatchCustomEvent(target, "vuu-commit");
|
|
45
|
+
} else if (typeof response === "string") {
|
|
46
|
+
setEditState((state) => ({ ...state, message: response }));
|
|
47
|
+
}
|
|
44
48
|
}
|
|
45
49
|
} else {
|
|
46
50
|
vuuUtils.dispatchCustomEvent(target, "vuu-commit");
|
|
47
|
-
hasCommittedRef.current = false;
|
|
48
51
|
}
|
|
49
52
|
},
|
|
50
|
-
[clientSideEditValidationCheck,
|
|
53
|
+
[clientSideEditValidationCheck, editState, onEdit]
|
|
51
54
|
);
|
|
52
55
|
const handleKeyDown = React.useCallback(
|
|
53
56
|
(evt) => {
|
|
@@ -57,13 +60,22 @@ const useEditableText = ({
|
|
|
57
60
|
evt.stopPropagation();
|
|
58
61
|
} else if (evt.key === "Escape") {
|
|
59
62
|
if (isDirtyRef.current) {
|
|
63
|
+
const { value: previousValue } = editState;
|
|
60
64
|
isDirtyRef.current = false;
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
setEditState({ value: initialValueRef.current, message: void 0 });
|
|
66
|
+
onEdit?.(
|
|
67
|
+
{
|
|
68
|
+
editType: "cancel",
|
|
69
|
+
isValid: true,
|
|
70
|
+
previousValue,
|
|
71
|
+
value: initialValueRef.current
|
|
72
|
+
},
|
|
73
|
+
"cancel"
|
|
74
|
+
);
|
|
63
75
|
}
|
|
64
76
|
}
|
|
65
77
|
},
|
|
66
|
-
[commit]
|
|
78
|
+
[commit, editState, onEdit]
|
|
67
79
|
);
|
|
68
80
|
const handleBlur = React.useCallback(
|
|
69
81
|
(evt) => {
|
|
@@ -75,32 +87,39 @@ const useEditableText = ({
|
|
|
75
87
|
);
|
|
76
88
|
const handleChange = React.useCallback(
|
|
77
89
|
(evt) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
const { value: value2 } = evt.target;
|
|
91
|
+
const typedValue = vuuUtils.getTypedValue(value2, type);
|
|
92
|
+
console.log(
|
|
93
|
+
`[useEditableText] handleChange '${value2}' typedValue ${typedValue}
|
|
94
|
+
initial value ${initialValueRef.current}
|
|
95
|
+
`
|
|
96
|
+
);
|
|
97
|
+
isDirtyRef.current = value2 !== initialValueRef.current;
|
|
98
|
+
const result = clientSideEditValidationCheck?.(value2, "change");
|
|
99
|
+
console.log({ result, value: value2 });
|
|
100
|
+
setEditState({ value: value2 });
|
|
101
|
+
onEdit?.(
|
|
102
|
+
{ editType: "change", isValid: result?.ok !== false, value: value2 },
|
|
103
|
+
"change"
|
|
104
|
+
);
|
|
105
|
+
if (result?.ok === false) {
|
|
106
|
+
console.log("cell fails validation");
|
|
107
|
+
setEditState({ value: value2, message: result.messages?.join(",") });
|
|
89
108
|
}
|
|
90
109
|
},
|
|
91
|
-
[clientSideEditValidationCheck,
|
|
110
|
+
[clientSideEditValidationCheck, onEdit, type]
|
|
92
111
|
);
|
|
93
112
|
return {
|
|
113
|
+
//TODO why are we detecting commit here, why not use VuuInput ?
|
|
94
114
|
inputProps: {
|
|
95
115
|
onBlur: handleBlur,
|
|
96
116
|
onKeyDown: handleKeyDown
|
|
97
117
|
},
|
|
98
118
|
onChange: handleChange,
|
|
99
|
-
value: value
|
|
100
|
-
warningMessage: message
|
|
119
|
+
value: editState.value,
|
|
120
|
+
warningMessage: editState.message
|
|
101
121
|
};
|
|
102
122
|
};
|
|
103
123
|
|
|
104
|
-
exports.WarnCommit = WarnCommit;
|
|
105
124
|
exports.useEditableText = useEditableText;
|
|
106
125
|
//# sourceMappingURL=useEditableText.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport {
|
|
1
|
+
{"version":3,"file":"useEditableText.js","sources":["../../src/editable/useEditableText.ts"],"sourcesContent":["import { DataValueValidationChecker } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { DataItemEditHandler } from \"@vuu-ui/vuu-table-types\";\nimport { dispatchCustomEvent, getTypedValue } from \"@vuu-ui/vuu-utils\";\nimport {\n FocusEventHandler,\n FormEventHandler,\n KeyboardEvent,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nexport interface EditableTextHookProps<\n T extends VuuRowDataItemType = VuuRowDataItemType,\n> {\n clientSideEditValidationCheck?: DataValueValidationChecker;\n value?: T;\n onEdit?: DataItemEditHandler;\n type?: \"string\" | \"number\" | \"boolean\";\n}\n\ntype EditState = {\n message?: string;\n value: string;\n};\n\nconst stringValueOf = (value?: VuuRowDataItemType) => value?.toString() ?? \"\";\n\nexport const useEditableText = <T extends string | number | boolean = string>({\n clientSideEditValidationCheck,\n value,\n onEdit,\n type = \"string\",\n}: EditableTextHookProps<T>) => {\n // console.log(\"initial value: \", initialValue);\n const [editState, setEditState] = useState<EditState>({\n value: stringValueOf(value),\n });\n // console.log(\"edit state: \", editState);\n const initialValueRef = useRef<string>(value?.toString() ?? \"\");\n const isDirtyRef = useRef(false);\n\n useMemo(() => {\n if (initialValueRef.current !== value?.toString()) {\n initialValueRef.current = stringValueOf(value);\n setEditState({ message: \"\", value: stringValueOf(value) });\n console.log(\"initial value changed to: \", value);\n }\n }, [value]);\n\n const commit = useCallback(\n async (target: HTMLElement) => {\n const { value } = editState;\n if (isDirtyRef.current) {\n const result = clientSideEditValidationCheck?.(value, \"*\");\n if (result?.ok === false) {\n setEditState((state) => ({\n ...state,\n message: result?.messages?.join(\",\"),\n }));\n } else {\n setEditState((state) => ({ ...state, message: undefined }));\n const response = await onEdit?.(\n { editType: \"commit\", value, isValid: true },\n \"commit\",\n );\n if (response === true) {\n isDirtyRef.current = false;\n initialValueRef.current = value;\n dispatchCustomEvent(target, \"vuu-commit\");\n } else if (typeof response === \"string\") {\n setEditState((state) => ({ ...state, message: response }));\n }\n }\n } else {\n // why, if not dirty ?\n dispatchCustomEvent(target, \"vuu-commit\");\n }\n },\n [clientSideEditValidationCheck, editState, onEdit],\n );\n\n const handleKeyDown = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => {\n if (evt.key === \"Enter\") {\n commit(evt.target as HTMLElement);\n } else if (\n evt.key === \"ArrowRight\" ||\n evt.key === \"ArrowLeft\" ||\n evt.key === \"ArrowUp\" ||\n evt.key === \"ArrowDown\"\n ) {\n evt.stopPropagation();\n } else if (evt.key === \"Escape\") {\n if (isDirtyRef.current) {\n const { value: previousValue } = editState;\n isDirtyRef.current = false;\n setEditState({ value: initialValueRef.current, message: undefined });\n // this assumes the original value was valid, is that safe ?\n onEdit?.(\n {\n editType: \"cancel\",\n isValid: true,\n previousValue,\n value: initialValueRef.current,\n },\n \"cancel\",\n );\n }\n }\n },\n [commit, editState, onEdit],\n );\n\n const handleBlur = useCallback<FocusEventHandler<HTMLElement>>(\n (evt) => {\n if (isDirtyRef.current) {\n commit(evt.target as HTMLElement);\n }\n },\n [commit],\n );\n\n const handleChange = useCallback<FormEventHandler>(\n (evt) => {\n const { value } = evt.target as HTMLInputElement;\n const typedValue = getTypedValue(value, type);\n console.log(\n `[useEditableText] handleChange '${value}' typedValue ${typedValue}\n initial value ${initialValueRef.current}\n `,\n );\n isDirtyRef.current = value !== initialValueRef.current;\n const result = clientSideEditValidationCheck?.(value, \"change\");\n console.log({ result, value });\n setEditState({ value });\n\n onEdit?.(\n { editType: \"change\", isValid: result?.ok !== false, value },\n \"change\",\n );\n if (result?.ok === false) {\n console.log(\"cell fails validation\");\n setEditState({ value, message: result.messages?.join(\",\") });\n }\n },\n [clientSideEditValidationCheck, onEdit, type],\n );\n\n return {\n //TODO why are we detecting commit here, why not use VuuInput ?\n inputProps: {\n onBlur: handleBlur,\n onKeyDown: handleKeyDown,\n },\n onChange: handleChange,\n value: editState.value,\n warningMessage: editState.message,\n };\n};\n"],"names":["useState","useRef","useMemo","useCallback","value","dispatchCustomEvent","getTypedValue"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var toggleIconCss = ".vuuToggleIconButton {\n &.saltButton {\n &:active {\n --saltButton-background-active: transparent;\n }\n &:hover {\n --saltButton-background-hover: transparent;\n }\n .vuuIcon {\n --vuu-icon-height: 18px;\n --vuu-icon-left: -3px;\n --vuu-icon-width: 18px;\n &:after {\n transition: transform 0.1s linear;\n }\n &[data-icon=\"triangle-down\"]:after {\n --vuu-icon-left: -1px;\n --vuu-icon-top: -3px;\n }\n }\n border: none;\n border-radius: 0;\n height: 18px;\n left: 0;\n min-width: 16px;\n padding: 0;\n width: 18px;\n }\n}\n\n.vuuTableGroupCell:hover {\n .vuuToggleIconButton {\n .vuuIcon:after {\n --vuu-icon-color: var(--salt-palette-interact-cta-background-hover);\n }\n }\n}\n";
|
|
4
|
+
|
|
5
|
+
module.exports = toggleIconCss;
|
|
6
|
+
//# sourceMappingURL=ToggleIconButton.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleIconButton.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var styles = require('@salt-ds/styles');
|
|
5
|
+
var window = require('@salt-ds/window');
|
|
6
|
+
var cx = require('clsx');
|
|
7
|
+
var IconButton = require('./IconButton.js');
|
|
8
|
+
var ToggleIconButton$1 = require('./ToggleIconButton.css.js');
|
|
9
|
+
|
|
10
|
+
const classBase = "vuuToggleIconButton";
|
|
11
|
+
const ToggleIconButton = ({
|
|
12
|
+
className,
|
|
13
|
+
isExpanded,
|
|
14
|
+
size = 7,
|
|
15
|
+
variant = "secondary",
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
const targetWindow = window.useWindow();
|
|
19
|
+
styles.useComponentCssInjection({
|
|
20
|
+
testId: "vuu-toggle-icon-button",
|
|
21
|
+
css: ToggleIconButton$1,
|
|
22
|
+
window: targetWindow
|
|
23
|
+
});
|
|
24
|
+
const icon = isExpanded ? "triangle-down" : "triangle-right";
|
|
25
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
26
|
+
IconButton.IconButton,
|
|
27
|
+
{
|
|
28
|
+
...props,
|
|
29
|
+
className: cx(classBase, className),
|
|
30
|
+
icon,
|
|
31
|
+
size,
|
|
32
|
+
variant
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
exports.ToggleIconButton = ToggleIconButton;
|
|
38
|
+
//# sourceMappingURL=ToggleIconButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToggleIconButton.js","sources":["../../src/icon-button/ToggleIconButton.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { IconButton, IconButtonProps } from \"./IconButton\";\n\nimport toggleIconCss from \"./ToggleIconButton.css\";\n\nconst classBase = \"vuuToggleIconButton\";\n\nexport interface ToggleIconButtonProps extends Omit<IconButtonProps, \"icon\"> {\n isExpanded: boolean;\n}\n\nexport const ToggleIconButton = ({\n className,\n isExpanded,\n size = 7,\n variant = \"secondary\",\n ...props\n}: ToggleIconButtonProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toggle-icon-button\",\n css: toggleIconCss,\n window: targetWindow,\n });\n\n const icon = isExpanded ? \"triangle-down\" : \"triangle-right\";\n return (\n <IconButton\n {...props}\n className={cx(classBase, className)}\n icon={icon}\n size={size}\n variant={variant}\n />\n );\n};\n"],"names":["useWindow","useComponentCssInjection","toggleIconCss","jsx","IconButton"],"mappings":";;;;;;;;;AAOA,MAAM,SAAY,GAAA,qBAAA,CAAA;AAMX,MAAM,mBAAmB,CAAC;AAAA,EAC/B,SAAA;AAAA,EACA,UAAA;AAAA,EACA,IAAO,GAAA,CAAA;AAAA,EACP,OAAU,GAAA,WAAA;AAAA,EACV,GAAG,KAAA;AACL,CAA6B,KAAA;AAC3B,EAAA,MAAM,eAAeA,gBAAU,EAAA,CAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,kBAAA;AAAA,IACL,MAAQ,EAAA,YAAA;AAAA,GACT,CAAA,CAAA;AAED,EAAM,MAAA,IAAA,GAAO,aAAa,eAAkB,GAAA,gBAAA,CAAA;AAC5C,EACE,uBAAAC,cAAA;AAAA,IAACC,qBAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,IAAA;AAAA,MACA,IAAA;AAAA,MACA,OAAA;AAAA,KAAA;AAAA,GACF,CAAA;AAEJ;;;;"}
|
package/cjs/index.js
CHANGED
|
@@ -26,6 +26,7 @@ var EditableLabel = require('./editable-label/EditableLabel.js');
|
|
|
26
26
|
var ExpandoInput = require('./expando-input/ExpandoInput.js');
|
|
27
27
|
var Icon = require('./icon-button/Icon.js');
|
|
28
28
|
var IconButton = require('./icon-button/IconButton.js');
|
|
29
|
+
var ToggleIconButton = require('./icon-button/ToggleIconButton.js');
|
|
29
30
|
var TablePicker = require('./instrument-picker/TablePicker.js');
|
|
30
31
|
var TableSearch = require('./table-search/TableSearch.js');
|
|
31
32
|
var keyUtils = require('./list/common-hooks/keyUtils.js');
|
|
@@ -121,13 +122,13 @@ exports.measureElementSizeAndPosition = dropTargetUtils.measureElementSizeAndPos
|
|
|
121
122
|
exports.mutateDropTargetsSwitchDropTargetPosition = dropTargetUtils.mutateDropTargetsSwitchDropTargetPosition;
|
|
122
123
|
exports.removeDraggedItem = dropTargetUtils.removeDraggedItem;
|
|
123
124
|
exports.useGlobalDragDrop = useGlobalDragDrop.useGlobalDragDrop;
|
|
124
|
-
exports.WarnCommit = useEditableText.WarnCommit;
|
|
125
125
|
exports.useEditableText = useEditableText.useEditableText;
|
|
126
126
|
exports.EditableLabel = EditableLabel.EditableLabel;
|
|
127
127
|
exports.NullEditAPI = EditableLabel.NullEditAPI;
|
|
128
128
|
exports.ExpandoInput = ExpandoInput.ExpandoInput;
|
|
129
129
|
exports.Icon = Icon.Icon;
|
|
130
130
|
exports.IconButton = IconButton.IconButton;
|
|
131
|
+
exports.ToggleIconButton = ToggleIconButton.ToggleIconButton;
|
|
131
132
|
exports.TablePicker = TablePicker.TablePicker;
|
|
132
133
|
exports.TableSearch = TableSearch.TableSearch;
|
|
133
134
|
exports.ArrowDown = keyUtils.ArrowDown;
|
package/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/cjs/tree/Tree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tree.js","sources":["../../src/tree/Tree.tsx"],"sourcesContent":["import { useForkRef, useIdMemo as useId } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n ForwardedRef,\n HTMLAttributes,\n MouseEvent,\n forwardRef,\n useRef,\n} from \"react\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport type { NormalisedTreeSourceNode, TreeSourceNode } from \"./treeTypes\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n groupSelectionEnabled,\n} from \"./use-selection\";\nimport { useViewportTracking } from \"./use-viewport-tracking\";\nimport { useTree } from \"./useTree\";\n\nimport treeCss from \"./Tree.css\";\n\nconst classBase = \"vuuTree\";\n\ntype Indexer = {\n value: number;\n};\n\nexport interface TreeNodeProps extends HTMLAttributes<HTMLLIElement> {\n idx?: number;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport const TreeNode = ({ children, idx, ...props }: TreeNodeProps) => {\n return <li {...props}>{children}</li>;\n};\n\nexport interface TreeProps extends HTMLAttributes<HTMLUListElement> {\n allowDragDrop?: boolean;\n defaultSelected?: any;\n groupSelection?: GroupSelection;\n onHighlight?: (index: number) => void;\n onSelectionChange?: (selected: TreeSourceNode[]) => void;\n revealSelected?: boolean;\n selected?: string[];\n selection?: TreeSelection;\n source: TreeSourceNode[];\n}\n\nexport const Tree = forwardRef(function Tree(\n {\n allowDragDrop,\n className,\n defaultSelected,\n groupSelection = \"none\",\n id: idProp,\n onHighlight,\n onSelectionChange,\n revealSelected,\n selected: selectedProp,\n selection = \"single\",\n source,\n ...htmlAttributes\n }: TreeProps,\n forwardedRef: ForwardedRef<HTMLUListElement>\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tree\",\n css: treeCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const rootRef = useRef<HTMLUListElement>(null);\n // returns the full source data\n const [, sourceWithIds, sourceItemById] = useItemsWithIds(source, id, {\n revealSelected: revealSelected\n ? selectedProp ?? defaultSelected ?? false\n : undefined,\n });\n\n const handleSelectionChange: TreeNodeSelectionHandler = (evt, selected) => {\n if (onSelectionChange) {\n const sourceItems = selected\n .map((id) => sourceItemById(id))\n .filter((sourceItem) => sourceItem !== undefined) as TreeSourceNode[];\n onSelectionChange(sourceItems);\n }\n };\n\n const {\n focusVisible,\n highlightedIdx,\n hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected,\n visibleData,\n } = useTree({\n defaultSelected,\n groupSelection,\n onChange: handleSelectionChange,\n onHighlight,\n selected: selectedProp,\n selection,\n sourceWithIds,\n });\n\n // const isScrolling = useViewportTracking(root, highlightedIdx);\n useViewportTracking(rootRef, highlightedIdx);\n\n const defaultItemHandlers = {\n onMouseEnter: (evt: MouseEvent) => {\n // if (!isScrolling.current) {\n const targetEl = evt.target as HTMLElement;\n const idx = closestListItemIndex(targetEl);\n hiliteItemAtIndex(idx);\n // onMouseEnterListItem && onMouseEnterListItem(evt, idx);\n // }\n },\n };\n\n const propsCommonToAllListItems = {\n ...defaultItemHandlers,\n ...listItemHandlers,\n role: \"treeitem\",\n };\n const allowGroupSelect = groupSelectionEnabled(groupSelection);\n\n /**\n * Add a ListItem from source item\n */\n function addLeafNode(\n list: JSX.Element[],\n item: NormalisedTreeSourceNode,\n idx: Indexer\n ) {\n list.push(\n <TreeNode\n {...propsCommonToAllListItems}\n {...getListItemProps(item, idx, highlightedIdx, selected, focusVisible)}\n >\n {item.icon ? (\n <span className={`${classBase}Node-icon`} data-icon={item.icon} />\n ) : null}\n <span>{item.label}</span>\n </TreeNode>\n );\n idx.value += 1;\n }\n\n function addGroupNode(\n list: JSX.Element[],\n child: NormalisedTreeSourceNode,\n idx: Indexer,\n id: string,\n title: string\n ) {\n const { value: i } = idx;\n idx.value += 1;\n list.push(\n <TreeNode\n {...listItemHandlers}\n aria-expanded={child.expanded}\n aria-level={child.level}\n aria-selected={selected.includes(id) || undefined}\n className={cx(`${classBase}Node`, {\n focusVisible: focusVisible === i,\n [`${classBase}Node-toggle`]: !allowGroupSelect,\n })}\n data-idx={i}\n data-highlighted={i === highlightedIdx || undefined}\n data-selectable\n id={id}\n key={`header-${i}`}\n >\n {allowGroupSelect ? (\n <div className={`${classBase}Node-label`}>\n <span className={`${classBase}Node-toggle`} />\n {title}\n </div>\n ) : (\n <div className={`${classBase}Node-label`}>\n {child.icon ? (\n <span\n className={`${classBase}Node-icon`}\n data-icon={child.icon}\n />\n ) : null}\n <span>{title}</span>\n </div>\n )}\n <ul role=\"group\">\n {isExpanded(child) ? renderSourceContent(child.childNodes, idx) : \"\"}\n </ul>\n </TreeNode>\n );\n }\n\n function renderSourceContent(\n items: NormalisedTreeSourceNode[],\n idx = { value: 0 }\n ) {\n if (items?.length > 0) {\n const listItems: JSX.Element[] = [];\n for (const item of items) {\n if (item.childNodes) {\n addGroupNode(listItems, item, idx, item.id, item.label);\n } else {\n addLeafNode(listItems, item, idx);\n }\n }\n return listItems;\n }\n }\n\n return (\n <ul\n {...htmlAttributes}\n {...listProps}\n className={cx(classBase, className)}\n id={`Tree-${id}`}\n ref={useForkRef<HTMLUListElement>(rootRef, forwardedRef)}\n role=\"tree\"\n tabIndex={0}\n >\n {renderSourceContent(visibleData)}\n </ul>\n );\n});\n\nconst getListItemProps = (\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n highlightedIdx: number,\n selected: string[],\n focusVisible: number,\n className?: string\n) => ({\n id: item.id,\n key: item.id,\n \"aria-level\": item.level,\n \"aria-selected\": selected.includes(item.id) || undefined,\n \"data-idx\": idx.value,\n \"data-highlighted\": idx.value === highlightedIdx || undefined,\n className: cx(\"vuuTreeNode\", className, {\n focusVisible: focusVisible === idx.value,\n }),\n});\n\nTree.displayName = \"Tree\";\n"],"names":["jsx","forwardRef","Tree","useWindow","useComponentCssInjection","treeCss","useId","useRef","useItemsWithIds","selected","id","useTree","useViewportTracking","closestListItemIndex","groupSelectionEnabled","jsxs","createElement","isExpanded","useForkRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Tree.js","sources":["../../src/tree/Tree.tsx"],"sourcesContent":["import { useForkRef, useIdMemo as useId } from \"@salt-ds/core\";\nimport cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n ForwardedRef,\n HTMLAttributes,\n MouseEvent,\n forwardRef,\n useRef,\n} from \"react\";\nimport { closestListItemIndex } from \"./list-dom-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport { useItemsWithIds } from \"./use-items-with-ids\";\nimport {\n GroupSelection,\n TreeNodeSelectionHandler,\n TreeSelection,\n groupSelectionEnabled,\n} from \"./use-selection\";\nimport { useViewportTracking } from \"./use-viewport-tracking\";\nimport { useTree } from \"./useTree\";\n\nimport treeCss from \"./Tree.css\";\nimport { NormalisedTreeSourceNode, TreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst classBase = \"vuuTree\";\n\ntype Indexer = {\n value: number;\n};\n\nexport interface TreeNodeProps extends HTMLAttributes<HTMLLIElement> {\n idx?: number;\n}\n\n// eslint-disable-next-line no-unused-vars\nexport const TreeNode = ({ children, idx, ...props }: TreeNodeProps) => {\n return <li {...props}>{children}</li>;\n};\n\nexport interface TreeProps extends HTMLAttributes<HTMLUListElement> {\n allowDragDrop?: boolean;\n defaultSelected?: any;\n groupSelection?: GroupSelection;\n onHighlight?: (index: number) => void;\n onSelectionChange?: (selected: TreeSourceNode[]) => void;\n revealSelected?: boolean;\n selected?: string[];\n selection?: TreeSelection;\n source: TreeSourceNode[];\n}\n\nexport const Tree = forwardRef(function Tree(\n {\n allowDragDrop,\n className,\n defaultSelected,\n groupSelection = \"none\",\n id: idProp,\n onHighlight,\n onSelectionChange,\n revealSelected,\n selected: selectedProp,\n selection = \"single\",\n source,\n ...htmlAttributes\n }: TreeProps,\n forwardedRef: ForwardedRef<HTMLUListElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-tree\",\n css: treeCss,\n window: targetWindow,\n });\n\n const id = useId(idProp);\n const rootRef = useRef<HTMLUListElement>(null);\n // returns the full source data\n const [, sourceWithIds, sourceItemById] = useItemsWithIds(source, id, {\n revealSelected: revealSelected\n ? (selectedProp ?? defaultSelected ?? false)\n : undefined,\n });\n\n const handleSelectionChange: TreeNodeSelectionHandler = (evt, selected) => {\n if (onSelectionChange) {\n const sourceItems = selected\n .map((id) => sourceItemById(id))\n .filter((sourceItem) => sourceItem !== undefined) as TreeSourceNode[];\n onSelectionChange(sourceItems);\n }\n };\n\n const {\n focusVisible,\n highlightedIdx,\n hiliteItemAtIndex,\n listProps,\n listItemHandlers,\n selected,\n visibleData,\n } = useTree({\n defaultSelected,\n groupSelection,\n onChange: handleSelectionChange,\n onHighlight,\n selected: selectedProp,\n selection,\n sourceWithIds,\n });\n\n // const isScrolling = useViewportTracking(root, highlightedIdx);\n useViewportTracking(rootRef, highlightedIdx);\n\n const defaultItemHandlers = {\n onMouseEnter: (evt: MouseEvent) => {\n // if (!isScrolling.current) {\n const targetEl = evt.target as HTMLElement;\n const idx = closestListItemIndex(targetEl);\n hiliteItemAtIndex(idx);\n // onMouseEnterListItem && onMouseEnterListItem(evt, idx);\n // }\n },\n };\n\n const propsCommonToAllListItems = {\n ...defaultItemHandlers,\n ...listItemHandlers,\n role: \"treeitem\",\n };\n const allowGroupSelect = groupSelectionEnabled(groupSelection);\n\n /**\n * Add a ListItem from source item\n */\n function addLeafNode(\n list: JSX.Element[],\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n ) {\n list.push(\n <TreeNode\n {...propsCommonToAllListItems}\n {...getListItemProps(item, idx, highlightedIdx, selected, focusVisible)}\n >\n {item.icon ? (\n <span className={`${classBase}Node-icon`} data-icon={item.icon} />\n ) : null}\n <span>{item.label}</span>\n </TreeNode>,\n );\n idx.value += 1;\n }\n\n function addGroupNode(\n list: JSX.Element[],\n child: NormalisedTreeSourceNode,\n idx: Indexer,\n id: string,\n title: string,\n ) {\n const { value: i } = idx;\n idx.value += 1;\n list.push(\n <TreeNode\n {...listItemHandlers}\n aria-expanded={child.expanded}\n aria-level={child.level}\n aria-selected={selected.includes(id) || undefined}\n className={cx(`${classBase}Node`, {\n focusVisible: focusVisible === i,\n [`${classBase}Node-toggle`]: !allowGroupSelect,\n })}\n data-idx={i}\n data-highlighted={i === highlightedIdx || undefined}\n data-selectable\n id={id}\n key={`header-${i}`}\n >\n {allowGroupSelect ? (\n <div className={`${classBase}Node-label`}>\n <span className={`${classBase}Node-toggle`} />\n {title}\n </div>\n ) : (\n <div className={`${classBase}Node-label`}>\n {child.icon ? (\n <span\n className={`${classBase}Node-icon`}\n data-icon={child.icon}\n />\n ) : null}\n <span>{title}</span>\n </div>\n )}\n <ul role=\"group\">\n {isExpanded(child) ? renderSourceContent(child.childNodes, idx) : \"\"}\n </ul>\n </TreeNode>,\n );\n }\n\n function renderSourceContent(\n items: NormalisedTreeSourceNode[],\n idx = { value: 0 },\n ) {\n if (items?.length > 0) {\n const listItems: JSX.Element[] = [];\n for (const item of items) {\n if (item.childNodes) {\n addGroupNode(listItems, item, idx, item.id, item.label);\n } else {\n addLeafNode(listItems, item, idx);\n }\n }\n return listItems;\n }\n }\n\n return (\n <ul\n {...htmlAttributes}\n {...listProps}\n className={cx(classBase, className)}\n id={`Tree-${id}`}\n ref={useForkRef<HTMLUListElement>(rootRef, forwardedRef)}\n role=\"tree\"\n tabIndex={0}\n >\n {renderSourceContent(visibleData)}\n </ul>\n );\n});\n\nconst getListItemProps = (\n item: NormalisedTreeSourceNode,\n idx: Indexer,\n highlightedIdx: number,\n selected: string[],\n focusVisible: number,\n className?: string,\n) => ({\n id: item.id,\n key: item.id,\n \"aria-level\": item.level,\n \"aria-selected\": selected.includes(item.id) || undefined,\n \"data-idx\": idx.value,\n \"data-highlighted\": idx.value === highlightedIdx || undefined,\n className: cx(\"vuuTreeNode\", className, {\n focusVisible: focusVisible === idx.value,\n }),\n});\n\nTree.displayName = \"Tree\";\n"],"names":["jsx","forwardRef","Tree","useWindow","useComponentCssInjection","treeCss","useId","useRef","useItemsWithIds","selected","id","useTree","useViewportTracking","closestListItemIndex","groupSelectionEnabled","jsxs","createElement","isExpanded","useForkRef"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hierarchical-data-utils.js","sources":["../../src/tree/hierarchical-data-utils.ts"],"sourcesContent":["import { NonLeafNode, NormalisedTreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"hierarchical-data-utils.js","sources":["../../src/tree/hierarchical-data-utils.ts"],"sourcesContent":["import { NonLeafNode, NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport const getNodeParentPath = ({ id }: NormalisedTreeSourceNode) => {\n let pos = id.lastIndexOf(\"-\");\n if (pos !== -1) {\n // using the built-in hierarchical id scheme\n // rootId-n-n.n\n const path = id.slice(pos + 1);\n const steps = path.split(\".\");\n if (steps.length === 1) {\n return null;\n } else {\n steps.pop();\n return `${id.slice(0, pos)}-${steps.join(\".\")}`;\n }\n } else if ((pos = id.lastIndexOf(\"/\")) !== -1) {\n // using a path scheme step/step/step\n return id.slice(0, pos);\n }\n};\n\nexport const isGroupNode = (node: NormalisedTreeSourceNode) =>\n node.childNodes !== undefined;\nexport const isCollapsibleGroupNode = (node: NormalisedTreeSourceNode) =>\n isGroupNode(node) && node.expanded !== undefined;\nexport const isHeader = (node: NormalisedTreeSourceNode) =>\n node.header === true;\n\nconst PATH_SEPARATORS = new Set([\".\", \"/\"]);\n\nconst isDescendantOf = (\n node: NormalisedTreeSourceNode,\n targetPath: string,\n): node is NonLeafNode => {\n if (!targetPath.startsWith(node.id)) {\n return false;\n } else {\n return PATH_SEPARATORS.has(targetPath.charAt(node.id.length));\n }\n};\n\nexport const getNodeById = (\n nodes: NormalisedTreeSourceNode[],\n id: string,\n): NormalisedTreeSourceNode | undefined => {\n for (const node of nodes) {\n if (node.id === id) {\n return node;\n } else if (isDescendantOf(node, id)) {\n return getNodeById(node.childNodes, id);\n }\n }\n};\n\nexport const getIndexOfNode = (\n treeNodes: NormalisedTreeSourceNode[],\n node: NormalisedTreeSourceNode,\n) => {\n const id = typeof node === \"string\" ? node : node.id;\n for (let i = 0; i < treeNodes.length; i++) {\n if (treeNodes[i].id === id) {\n return i;\n }\n }\n};\n\nexport const replaceNode = (\n nodes: NormalisedTreeSourceNode[],\n id: string,\n props: Partial<NormalisedTreeSourceNode>,\n): NormalisedTreeSourceNode[] => {\n let childNodes;\n const newNodes = nodes.map((node) => {\n if (node.id === id) {\n return {\n ...node,\n ...props,\n };\n } else if (isDescendantOf(node, id)) {\n childNodes = replaceNode(node.childNodes, id, props);\n return {\n ...node,\n childNodes,\n };\n } else {\n return node;\n }\n });\n\n return newNodes;\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"treeTypeUtils.js","sources":["../../src/tree/treeTypeUtils.ts"],"sourcesContent":["import type { NonLeafNode, NormalisedTreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"treeTypeUtils.js","sources":["../../src/tree/treeTypeUtils.ts"],"sourcesContent":["import type { NonLeafNode, NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nexport const isExpanded = (\n node: NormalisedTreeSourceNode,\n): node is NonLeafNode => node.expanded === true;\n"],"names":[],"mappings":";;AAEO,MAAM,UAAa,GAAA,CACxB,IACwB,KAAA,IAAA,CAAK,QAAa,KAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-collapsible-groups.js","sources":["../../src/tree/use-collapsible-groups.ts"],"sourcesContent":["import { KeyboardEvent, MouseEvent, useCallback, useRef } from \"react\";\nimport { closestListItem } from \"./list-dom-utils\";\nimport { ArrowLeft, ArrowRight, Enter } from \"./key-code\";\nimport { getNodeById, replaceNode } from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"use-collapsible-groups.js","sources":["../../src/tree/use-collapsible-groups.ts"],"sourcesContent":["import { KeyboardEvent, MouseEvent, useCallback, useRef } from \"react\";\nimport { closestListItem } from \"./list-dom-utils\";\nimport { ArrowLeft, ArrowRight, Enter } from \"./key-code\";\nimport { getNodeById, replaceNode } from \"./hierarchical-data-utils\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst NO_HANDLERS: CollapsibleHookResult[\"listHandlers\"] = {};\nconst isToggleElement = (element: HTMLElement) =>\n element && element.hasAttribute(\"aria-expanded\");\n\nexport interface CollapsibleGroupsHookProps {\n collapsibleHeaders?: boolean;\n highlightedIdx: number;\n treeNodes: NormalisedTreeSourceNode[];\n setVisibleData: (nodes: NormalisedTreeSourceNode[]) => void;\n source: NormalisedTreeSourceNode[];\n}\n\nexport interface CollapsibleHookResult {\n listHandlers: {\n onKeyDown?: (e: KeyboardEvent) => void;\n };\n listItemHandlers: {\n onClick: (e: MouseEvent) => void;\n };\n}\n\nexport const useCollapsibleGroups = ({\n collapsibleHeaders,\n highlightedIdx,\n treeNodes,\n setVisibleData,\n source,\n}: CollapsibleGroupsHookProps): CollapsibleHookResult => {\n const fullSource = useRef<NormalisedTreeSourceNode[]>(source);\n const stateSource = useRef<NormalisedTreeSourceNode[]>(fullSource.current);\n\n const setSource = useCallback(\n (value) => {\n setVisibleData((stateSource.current = value));\n },\n [setVisibleData],\n );\n\n const expandNode = useCallback(\n (nodeList: NormalisedTreeSourceNode[], { id }: NormalisedTreeSourceNode) =>\n replaceNode(nodeList, id, { expanded: true }),\n [],\n );\n\n const collapseNode = useCallback(\n (nodeList, { id }) => replaceNode(nodeList, id, { expanded: false }),\n [],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === ArrowRight || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded === false) {\n e.preventDefault();\n setSource(expandNode(stateSource.current, node));\n }\n }\n }\n\n if (e.key === ArrowLeft || e.key === Enter) {\n const node = treeNodes[highlightedIdx];\n if (node) {\n if (node.expanded) {\n e.preventDefault();\n setSource(collapseNode(stateSource.current, node));\n }\n }\n }\n },\n [collapseNode, expandNode, highlightedIdx, treeNodes, setSource],\n );\n\n /**\n * These are List handlers, so we will not have reference to the actual node\n * element. We must rely on highlightedIdx to tell us which node is interactive.\n */\n const listHandlers = collapsibleHeaders\n ? {\n onKeyDown: handleKeyDown,\n }\n : NO_HANDLERS;\n\n const handleClick = useCallback(\n (evt) => {\n const el = closestListItem(evt.target);\n if (isToggleElement(el)) {\n evt.stopPropagation();\n evt.preventDefault();\n const node = getNodeById(source, el.id);\n if (node?.expanded === false) {\n setSource(expandNode(source, node));\n } else if (node?.expanded === true) {\n setSource(collapseNode(source, node));\n }\n }\n },\n [collapseNode, expandNode, setSource, source],\n );\n\n const listItemHandlers = {\n onClick: handleClick,\n };\n\n return {\n listHandlers,\n listItemHandlers,\n };\n};\n"],"names":["useRef","useCallback","replaceNode","ArrowRight","Enter","ArrowLeft","closestListItem","getNodeById"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-hierarchical-data.js","sources":["../../src/tree/use-hierarchical-data.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { isGroupNode, isHeader } from \"./hierarchical-data-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport { NormalisedTreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"use-hierarchical-data.js","sources":["../../src/tree/use-hierarchical-data.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { isGroupNode, isHeader } from \"./hierarchical-data-utils\";\nimport { isExpanded } from \"./treeTypeUtils\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst populateIndices = (\n nodes: NormalisedTreeSourceNode[],\n results: NormalisedTreeSourceNode[] = [],\n idx = { value: 0 },\n) => {\n let skipToNextHeader = false;\n for (const node of nodes) {\n if (skipToNextHeader && !isHeader(node)) {\n continue;\n } else {\n results[idx.value] = node;\n idx.value += 1;\n skipToNextHeader = false;\n if (isHeader(node) && node.expanded === false) {\n skipToNextHeader = true;\n } else if (isGroupNode(node)) {\n if (isExpanded(node)) {\n populateIndices(node.childNodes, results, idx);\n }\n }\n }\n }\n return results;\n};\n\n//TODO return a read-only data structure\n// Question: is source changes at runtime, do we lose any current state ?\nexport const useHierarchicalData = (source: NormalisedTreeSourceNode[]) => {\n // console.log(`%c[useHierarchicalData<${label}>] entry`, 'color: green; font-weight: bold;');\n\n const externalSource = useRef(source);\n const statefulSource = useRef(source);\n const indexPositions = useRef(populateIndices(source));\n const [, forceUpdate] = useState({});\n\n // Maintain a mapping between nodes and their current index position within the rendered list.\n // This index position is liable to change with every expand/collapse operation. We require this\n // when handling keyboard events - these are List level, not listItem level, so we depend on the\n\n // Client needs to be careful source is not recreated inadvertently on each render\n if (source !== externalSource.current) {\n // console.log(\n // `%cuseHierarchicalData source has changed`,\n // 'color:red;font-weight: bold;',\n // externalSource.current,\n // source\n // );\n externalSource.current = source;\n // we might want to try and merge existing state here ?\n statefulSource.current = source;\n indexPositions.current = populateIndices(source);\n }\n\n const setData = (value: NormalisedTreeSourceNode[]) => {\n statefulSource.current = value;\n indexPositions.current = populateIndices(value);\n // console.log(\n // `data set in ${label} (${indexPositions.current.length} visible items)`,\n // indexPositions.current.map((i) => ({ index: i.index, label: i.label }))\n // );\n forceUpdate({});\n };\n\n return {\n // data, // do we actually use the data anywhere\n data: statefulSource.current,\n indexPositions: indexPositions.current,\n setData,\n };\n};\n"],"names":["isHeader","isGroupNode","isExpanded","useRef","useState"],"mappings":";;;;;;AAKA,MAAM,eAAA,GAAkB,CACtB,KAAA,EACA,OAAsC,GAAA,IACtC,GAAM,GAAA,EAAE,KAAO,EAAA,CAAA,EACZ,KAAA;AACH,EAAA,IAAI,gBAAmB,GAAA,KAAA,CAAA;AACvB,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAA,IAAI,gBAAoB,IAAA,CAACA,8BAAS,CAAA,IAAI,CAAG,EAAA;AACvC,MAAA,SAAA;AAAA,KACK,MAAA;AACL,MAAQ,OAAA,CAAA,GAAA,CAAI,KAAK,CAAI,GAAA,IAAA,CAAA;AACrB,MAAA,GAAA,CAAI,KAAS,IAAA,CAAA,CAAA;AACb,MAAmB,gBAAA,GAAA,KAAA,CAAA;AACnB,MAAA,IAAIA,8BAAS,CAAA,IAAI,CAAK,IAAA,IAAA,CAAK,aAAa,KAAO,EAAA;AAC7C,QAAmB,gBAAA,GAAA,IAAA,CAAA;AAAA,OACrB,MAAA,IAAWC,iCAAY,CAAA,IAAI,CAAG,EAAA;AAC5B,QAAI,IAAAC,wBAAA,CAAW,IAAI,CAAG,EAAA;AACpB,UAAgB,eAAA,CAAA,IAAA,CAAK,UAAY,EAAA,OAAA,EAAS,GAAG,CAAA,CAAA;AAAA,SAC/C;AAAA,OACF;AAAA,KACF;AAAA,GACF;AACA,EAAO,OAAA,OAAA,CAAA;AACT,CAAA,CAAA;AAIa,MAAA,mBAAA,GAAsB,CAAC,MAAuC,KAAA;AAGzE,EAAM,MAAA,cAAA,GAAiBC,aAAO,MAAM,CAAA,CAAA;AACpC,EAAM,MAAA,cAAA,GAAiBA,aAAO,MAAM,CAAA,CAAA;AACpC,EAAA,MAAM,cAAiB,GAAAA,YAAA,CAAO,eAAgB,CAAA,MAAM,CAAC,CAAA,CAAA;AACrD,EAAA,MAAM,GAAG,WAAW,CAAI,GAAAC,cAAA,CAAS,EAAE,CAAA,CAAA;AAOnC,EAAI,IAAA,MAAA,KAAW,eAAe,OAAS,EAAA;AAOrC,IAAA,cAAA,CAAe,OAAU,GAAA,MAAA,CAAA;AAEzB,IAAA,cAAA,CAAe,OAAU,GAAA,MAAA,CAAA;AACzB,IAAe,cAAA,CAAA,OAAA,GAAU,gBAAgB,MAAM,CAAA,CAAA;AAAA,GACjD;AAEA,EAAM,MAAA,OAAA,GAAU,CAAC,KAAsC,KAAA;AACrD,IAAA,cAAA,CAAe,OAAU,GAAA,KAAA,CAAA;AACzB,IAAe,cAAA,CAAA,OAAA,GAAU,gBAAgB,KAAK,CAAA,CAAA;AAK9C,IAAA,WAAA,CAAY,EAAE,CAAA,CAAA;AAAA,GAChB,CAAA;AAEA,EAAO,OAAA;AAAA;AAAA,IAEL,MAAM,cAAe,CAAA,OAAA;AAAA,IACrB,gBAAgB,cAAe,CAAA,OAAA;AAAA,IAC/B,OAAA;AAAA,GACF,CAAA;AACF;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-items-with-ids.js","sources":["../../src/tree/use-items-with-ids.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { NormalisedTreeSourceNode, TreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"use-items-with-ids.js","sources":["../../src/tree/use-items-with-ids.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport { NormalisedTreeSourceNode, TreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nconst PathSeparators = new Set([\"/\", \"-\", \".\"]);\n// TODO where do we define or identify separators\nconst isPathSeparator = (char: string) => PathSeparators.has(char);\n\nconst isParentPath = (parentPath: string, childPath: string) =>\n childPath.startsWith(parentPath) &&\n isPathSeparator(childPath[parentPath.length]);\n\ntype Indexer = {\n index: number;\n};\n\ntype SourceItemById = (\n id: string,\n target?: NormalisedTreeSourceNode[],\n) => TreeSourceNode | undefined;\n\nexport const useItemsWithIds = (\n sourceProp: TreeSourceNode[],\n idRoot = \"root\",\n {\n collapsibleHeaders = undefined,\n defaultExpanded = false,\n revealSelected = false,\n } = {},\n): [number, NormalisedTreeSourceNode[], SourceItemById] => {\n const countChildItems = (\n item: TreeSourceNode,\n items: TreeSourceNode[],\n idx: number,\n ) => {\n if (item.childNodes) {\n return item.childNodes.length;\n } else if (item.header) {\n let i = idx + 1;\n let count = 0;\n while (i < items.length && !items[i].header) {\n count++;\n i++;\n }\n return count;\n } else {\n return 0;\n }\n };\n\n const isExpanded = useCallback(\n (path) => {\n if (Array.isArray(revealSelected)) {\n return revealSelected.some((id) => isParentPath(path, id));\n }\n return defaultExpanded;\n },\n [defaultExpanded, revealSelected],\n );\n\n const normalizeItems = useCallback(\n (\n items: TreeSourceNode[],\n indexer: Indexer,\n level = 1,\n path = \"\",\n results: NormalisedTreeSourceNode[] = [],\n flattenedSource: TreeSourceNode[] = [],\n ): [number, NormalisedTreeSourceNode[], TreeSourceNode[]] => {\n let count = 0;\n // TODO get rid of the Proxy\n items.forEach((item, i, all) => {\n const isCollapsibleHeader = item.header && collapsibleHeaders;\n const isNonCollapsibleGroupNode =\n item.childNodes && collapsibleHeaders === false;\n const isLeaf = !item.childNodes || item.childNodes.length === 0;\n const nonCollapsible =\n isNonCollapsibleGroupNode || (isLeaf && !isCollapsibleHeader);\n const childPath = path ? `${path}.${i}` : `${i}`;\n const id = item.id ?? `${idRoot}-${childPath}`;\n\n const expanded = nonCollapsible ? undefined : isExpanded(id);\n //TODO dev time check - if id is provided by user, make sure\n // hierarchical pattern is consistent\n const normalisedItem: NormalisedTreeSourceNode = {\n ...item,\n childNodes: undefined,\n id,\n count:\n !isNonCollapsibleGroupNode && expanded === undefined\n ? 0\n : countChildItems(item, all, i),\n expanded,\n index: indexer.index,\n level,\n };\n results.push(normalisedItem);\n flattenedSource.push(items[i]);\n\n count += 1;\n indexer.index += 1;\n\n // if ((isNonCollapsibleGroupNode || expanded !== undefined) && !isCollapsibleHeader) {\n if (item.childNodes) {\n const [childCount, children] = normalizeItems(\n item.childNodes,\n indexer,\n level + 1,\n childPath,\n [],\n flattenedSource,\n );\n normalisedItem.childNodes = children;\n if (expanded === true || isNonCollapsibleGroupNode) {\n count += childCount;\n }\n }\n });\n return [count, results, flattenedSource];\n },\n [collapsibleHeaders, idRoot, isExpanded],\n );\n\n const [count, sourceWithIds, flattenedSource] = useMemo<\n [number, NormalisedTreeSourceNode[], TreeSourceNode[]]\n >(() => {\n return normalizeItems(sourceProp, { index: 0 });\n }, [normalizeItems, sourceProp]);\n\n const sourceItemById = useCallback<SourceItemById>(\n (id, target = sourceWithIds): TreeSourceNode | undefined => {\n const sourceWithId = target.find(\n (i) => i.id === id || (i?.childNodes?.length && isParentPath(i.id, id)),\n );\n if (sourceWithId?.id === id) {\n return flattenedSource[sourceWithId.index];\n } else if (sourceWithId) {\n return sourceItemById(id, sourceWithId.childNodes);\n }\n },\n [flattenedSource, sourceWithIds],\n );\n\n return [count, sourceWithIds, sourceItemById];\n};\n"],"names":["count","useCallback","flattenedSource","useMemo"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-keyboard-navigation.js","sources":["../../src/tree/use-keyboard-navigation.ts"],"sourcesContent":["import { KeyboardEvent, useCallback, useMemo, useRef } from \"react\";\nimport { getIndexOfNode, getNodeById } from \"./hierarchical-data-utils\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { ArrowDown, ArrowLeft, ArrowUp, isNavigationKey } from \"./key-code\";\nimport { NormalisedTreeSourceNode } from \"
|
|
1
|
+
{"version":3,"file":"use-keyboard-navigation.js","sources":["../../src/tree/use-keyboard-navigation.ts"],"sourcesContent":["import { KeyboardEvent, useCallback, useMemo, useRef } from \"react\";\nimport { getIndexOfNode, getNodeById } from \"./hierarchical-data-utils\";\nimport { useControlled } from \"@salt-ds/core\";\nimport { ArrowDown, ArrowLeft, ArrowUp, isNavigationKey } from \"./key-code\";\nimport { NormalisedTreeSourceNode } from \"@vuu-ui/vuu-utils\";\n\nfunction nextItemIdx(count: number, key: string, idx: number) {\n if (key === ArrowUp || key === ArrowLeft) {\n if (idx > 0) {\n return idx - 1;\n } else {\n return idx;\n }\n } else {\n if (idx === null) {\n return 0;\n } else if (idx === count - 1) {\n return idx;\n } else {\n return idx + 1;\n }\n }\n}\n\nconst isLeaf = (item: NormalisedTreeSourceNode) =>\n !item.header && !item.childNodes;\nconst isFocusable = (item: NormalisedTreeSourceNode) =>\n isLeaf(item) || item.expanded !== undefined;\n\nexport interface KeyboardNavigationHookProps {\n defaultHighlightedIdx?: number;\n highlightedIdx?: number;\n onHighlight?: (highlightedIdx: number) => void;\n onKeyboardNavigation?: (evt: KeyboardEvent, nextIdx: number) => void;\n selected: string[];\n treeNodes: NormalisedTreeSourceNode[];\n}\n\n// we need a way to set highlightedIdx when selection changes\nexport const useKeyboardNavigation = ({\n defaultHighlightedIdx = -1,\n highlightedIdx: highlightedIdxProp,\n treeNodes,\n onHighlight,\n onKeyboardNavigation,\n selected = [],\n}: KeyboardNavigationHookProps) => {\n const { bwd: ArrowBwd, fwd: ArrowFwd } = useMemo(\n () => ({\n bwd: ArrowUp,\n fwd: ArrowDown,\n }),\n [],\n );\n\n const [highlightedIdx, setHighlightedIdx, isControlledHighlighting] =\n useControlled({\n controlled: highlightedIdxProp,\n default: defaultHighlightedIdx,\n name: \"highlightedIdx\",\n });\n\n const setHighlightedIndex = useCallback(\n (idx) => {\n onHighlight?.(idx);\n setHighlightedIdx(idx);\n },\n [onHighlight, setHighlightedIdx],\n );\n\n const nextFocusableItemIdx = useCallback(\n (key = ArrowFwd, idx = key === ArrowFwd ? -1 : treeNodes.length) => {\n let nextIdx = nextItemIdx(treeNodes.length, key, idx);\n while (\n nextIdx !== -1 &&\n ((key === ArrowFwd && nextIdx < treeNodes.length) ||\n (key === ArrowBwd && nextIdx > 0)) &&\n !isFocusable(treeNodes[nextIdx])\n ) {\n nextIdx = nextItemIdx(treeNodes.length, key, nextIdx);\n }\n return nextIdx;\n },\n [ArrowBwd, ArrowFwd, treeNodes],\n );\n\n // does this belong here or should it be a method passed in?\n const keyBoardNavigation = useRef(true);\n const ignoreFocus = useRef(false);\n const setIgnoreFocus = (value: boolean) => (ignoreFocus.current = value);\n\n const handleFocus = useCallback(() => {\n if (ignoreFocus.current) {\n ignoreFocus.current = false;\n } else if (selected.length > 0) {\n const node = getNodeById(treeNodes, selected[0]);\n if (node) {\n const idx = getIndexOfNode(treeNodes, node);\n setHighlightedIndex(idx);\n }\n } else {\n setHighlightedIndex(nextFocusableItemIdx());\n }\n }, [treeNodes, nextFocusableItemIdx, selected, setHighlightedIndex]);\n\n const navigateChildItems = useCallback(\n (e) => {\n const nextIdx = nextFocusableItemIdx(e.key, highlightedIdx);\n if (nextIdx !== highlightedIdx) {\n setHighlightedIndex(nextIdx);\n // What exactly is the point of this ?\n onKeyboardNavigation?.(e, nextIdx);\n }\n },\n [\n highlightedIdx,\n nextFocusableItemIdx,\n onKeyboardNavigation,\n setHighlightedIndex,\n ],\n );\n\n const handleKeyDown = useCallback(\n (e) => {\n if (treeNodes.length > 0 && isNavigationKey(e, \"vertical\")) {\n e.preventDefault();\n e.stopPropagation();\n keyBoardNavigation.current = true;\n navigateChildItems(e);\n }\n },\n [treeNodes, navigateChildItems],\n );\n\n const listProps = useMemo(\n () => ({\n onBlur: () => {\n setHighlightedIndex(-1);\n },\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n onMouseDownCapture: () => {\n keyBoardNavigation.current = false;\n setIgnoreFocus(true);\n },\n\n // onMouseEnter would seem less expensive but it misses some cases\n // SHould this be here - this is not strictly keyboard nav\n onMouseMove: () => {\n if (keyBoardNavigation.current) {\n keyBoardNavigation.current = false;\n }\n },\n onMouseLeave: () => {\n keyBoardNavigation.current = true;\n setIgnoreFocus(false);\n setHighlightedIndex(-1);\n },\n }),\n [handleFocus, handleKeyDown, setHighlightedIndex],\n );\n\n return {\n focusVisible: keyBoardNavigation.current ? highlightedIdx : -1,\n controlledHighlighting: isControlledHighlighting,\n highlightedIdx,\n hiliteItemAtIndex: setHighlightedIndex,\n keyBoardNavigation,\n listProps,\n setIgnoreFocus,\n };\n};\n"],"names":["ArrowUp","ArrowLeft","useMemo","ArrowDown","useControlled","useCallback","useRef","getNodeById","getIndexOfNode","isNavigationKey"],"mappings":"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"}
|