@uipath/apollo-react 3.54.0-pr354.c980c37 → 3.54.0-pr354.f47b811
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas/components/Toolbox/ListView.cjs +54 -34
- package/dist/canvas/components/Toolbox/ListView.d.ts +12 -2
- package/dist/canvas/components/Toolbox/ListView.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/ListView.js +51 -34
- package/dist/canvas/components/Toolbox/ListView.styles.cjs +7 -1
- package/dist/canvas/components/Toolbox/ListView.styles.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/ListView.styles.js +7 -1
- package/dist/canvas/components/Toolbox/SearchBox.cjs +12 -4
- package/dist/canvas/components/Toolbox/SearchBox.d.ts +3 -0
- package/dist/canvas/components/Toolbox/SearchBox.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/SearchBox.js +12 -4
- package/dist/canvas/components/Toolbox/Toolbox.cjs +141 -4
- package/dist/canvas/components/Toolbox/Toolbox.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/Toolbox.js +141 -4
- package/package.json +2 -2
|
@@ -24,7 +24,8 @@ var __webpack_require__ = {};
|
|
|
24
24
|
var __webpack_exports__ = {};
|
|
25
25
|
__webpack_require__.r(__webpack_exports__);
|
|
26
26
|
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
-
ListView: ()=>ListView_ListView
|
|
27
|
+
ListView: ()=>ListView_ListView,
|
|
28
|
+
buildRenderedItems: ()=>buildRenderedItems
|
|
28
29
|
});
|
|
29
30
|
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
30
31
|
const apollo_core_namespaceObject = require("@uipath/apollo-core");
|
|
@@ -35,8 +36,37 @@ const components_index_cjs_namespaceObject = require("../../../material/componen
|
|
|
35
36
|
const external_react_namespaceObject = require("react");
|
|
36
37
|
const CanvasThemeContext_cjs_namespaceObject = require("../BaseCanvas/CanvasThemeContext.cjs");
|
|
37
38
|
const external_ListView_styles_cjs_namespaceObject = require("./ListView.styles.cjs");
|
|
39
|
+
function buildRenderedItems(items, enableSections) {
|
|
40
|
+
const result = [];
|
|
41
|
+
if (0 === items.length) return result;
|
|
42
|
+
if (!enableSections) {
|
|
43
|
+
for (const item of items)result.push({
|
|
44
|
+
type: 'item',
|
|
45
|
+
item
|
|
46
|
+
});
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
const [itemsWithSection, itemsWithoutSection] = (0, external_utils_index_cjs_namespaceObject.partition)(items, (item)=>!!item.section);
|
|
50
|
+
for (const item of itemsWithoutSection)result.push({
|
|
51
|
+
type: 'item',
|
|
52
|
+
item
|
|
53
|
+
});
|
|
54
|
+
if (0 === itemsWithSection.length) return result;
|
|
55
|
+
const sections = Array.from(new Set(itemsWithSection.map((item)=>item.section)));
|
|
56
|
+
for (const section of sections){
|
|
57
|
+
result.push({
|
|
58
|
+
type: 'section',
|
|
59
|
+
sectionName: section
|
|
60
|
+
});
|
|
61
|
+
for (const item of itemsWithSection.filter((item)=>item.section === section))result.push({
|
|
62
|
+
type: 'item',
|
|
63
|
+
item
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
38
68
|
const IconContainerMemoized = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(external_ListView_styles_cjs_namespaceObject.IconContainer);
|
|
39
|
-
const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ index, style, ariaAttributes, renderedItems, isLoading, isDarkMode, onItemClick, onItemHover })=>{
|
|
69
|
+
const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ index, style, ariaAttributes, renderedItems, activeIndex, isLoading, isDarkMode, onItemClick, onItemHover })=>{
|
|
40
70
|
const renderItem = renderedItems[index];
|
|
41
71
|
const buttonStyle = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
42
72
|
...style,
|
|
@@ -74,12 +104,17 @@ const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ in
|
|
|
74
104
|
});
|
|
75
105
|
const item = renderItem.item;
|
|
76
106
|
const bgColor = isDarkMode ? item.colorDark ?? item.color : item.color;
|
|
107
|
+
const isActive = index === activeIndex;
|
|
77
108
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_ListView_styles_cjs_namespaceObject.ListItemButton, {
|
|
78
109
|
...ariaAttributes,
|
|
110
|
+
tabIndex: -1,
|
|
111
|
+
id: `toolbox-item-${item.id}`,
|
|
112
|
+
role: "option",
|
|
113
|
+
"aria-selected": isActive,
|
|
79
114
|
style: buttonStyle,
|
|
80
115
|
onClick: handleButtonClick,
|
|
81
116
|
onHoverStart: handleButtonHover,
|
|
82
|
-
className: isLoading ? 'loading' : ''
|
|
117
|
+
className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
|
|
83
118
|
disabled: isLoading,
|
|
84
119
|
children: [
|
|
85
120
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(IconContainerMemoized, {
|
|
@@ -134,48 +169,27 @@ const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ in
|
|
|
134
169
|
]
|
|
135
170
|
});
|
|
136
171
|
});
|
|
137
|
-
const
|
|
172
|
+
const ListViewInner = /*#__PURE__*/ (0, external_react_namespaceObject.forwardRef)(function({ items, activeIndex = -1, listRef, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }, ref) {
|
|
138
173
|
const { isDarkMode } = (0, CanvasThemeContext_cjs_namespaceObject.useCanvasTheme)();
|
|
139
|
-
const renderedItems = (0, external_react_namespaceObject.useMemo)(()=>
|
|
140
|
-
const result = [];
|
|
141
|
-
if (0 === items.length) return result;
|
|
142
|
-
if (!enableSections) {
|
|
143
|
-
for (const item of items)result.push({
|
|
144
|
-
type: 'item',
|
|
145
|
-
item
|
|
146
|
-
});
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
|
-
const [itemsWithSection, itemsWithoutSection] = (0, external_utils_index_cjs_namespaceObject.partition)(items, (item)=>!!item.section);
|
|
150
|
-
for (const item of itemsWithoutSection)result.push({
|
|
151
|
-
type: 'item',
|
|
152
|
-
item
|
|
153
|
-
});
|
|
154
|
-
if (0 === itemsWithSection.length) return result;
|
|
155
|
-
const sections = Array.from(new Set(itemsWithSection.map((item)=>item.section)));
|
|
156
|
-
for (const section of sections){
|
|
157
|
-
result.push({
|
|
158
|
-
type: 'section',
|
|
159
|
-
sectionName: section
|
|
160
|
-
});
|
|
161
|
-
for (const item of itemsWithSection.filter((item)=>item.section === section))result.push({
|
|
162
|
-
type: 'item',
|
|
163
|
-
item
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
return result;
|
|
167
|
-
}, [
|
|
174
|
+
const renderedItems = (0, external_react_namespaceObject.useMemo)(()=>buildRenderedItems(items, enableSections), [
|
|
168
175
|
items,
|
|
169
176
|
enableSections
|
|
170
177
|
]);
|
|
178
|
+
(0, external_react_namespaceObject.useImperativeHandle)(ref, ()=>({
|
|
179
|
+
renderedItems
|
|
180
|
+
}), [
|
|
181
|
+
renderedItems
|
|
182
|
+
]);
|
|
171
183
|
const rowProps = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
172
184
|
renderedItems,
|
|
185
|
+
activeIndex,
|
|
173
186
|
isLoading,
|
|
174
187
|
isDarkMode,
|
|
175
188
|
onItemClick,
|
|
176
189
|
onItemHover
|
|
177
190
|
}), [
|
|
178
191
|
renderedItems,
|
|
192
|
+
activeIndex,
|
|
179
193
|
isLoading,
|
|
180
194
|
isDarkMode,
|
|
181
195
|
onItemClick,
|
|
@@ -215,6 +229,9 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
|
|
|
215
229
|
]
|
|
216
230
|
});
|
|
217
231
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_styles_cjs_namespaceObject.StyledList, {
|
|
232
|
+
id: "toolbox-listbox",
|
|
233
|
+
role: "listbox",
|
|
234
|
+
listRef: listRef,
|
|
218
235
|
rowProps: rowProps,
|
|
219
236
|
rowComponent: ListViewRow,
|
|
220
237
|
rowCount: renderedItems.length,
|
|
@@ -222,9 +239,12 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
|
|
|
222
239
|
overscanCount: 20
|
|
223
240
|
});
|
|
224
241
|
});
|
|
242
|
+
const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(ListViewInner);
|
|
225
243
|
exports.ListView = __webpack_exports__.ListView;
|
|
244
|
+
exports.buildRenderedItems = __webpack_exports__.buildRenderedItems;
|
|
226
245
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
227
|
-
"ListView"
|
|
246
|
+
"ListView",
|
|
247
|
+
"buildRenderedItems"
|
|
228
248
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
229
249
|
Object.defineProperty(exports, '__esModule', {
|
|
230
250
|
value: true
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ListImperativeAPI } from 'react-window';
|
|
1
2
|
export interface ListItemIcon {
|
|
2
3
|
name?: string;
|
|
3
4
|
url?: string;
|
|
@@ -14,22 +15,29 @@ export type ListItem<T = any> = {
|
|
|
14
15
|
colorDark?: string;
|
|
15
16
|
children?: ListItem<T>[] | ((id: string, name: string) => Promise<ListItem<T>[]>);
|
|
16
17
|
};
|
|
17
|
-
type RenderItem<T extends ListItem> = {
|
|
18
|
+
export type RenderItem<T extends ListItem> = {
|
|
18
19
|
type: 'section';
|
|
19
20
|
sectionName: string;
|
|
20
21
|
} | {
|
|
21
22
|
type: 'item';
|
|
22
23
|
item: T;
|
|
23
24
|
};
|
|
25
|
+
export declare function buildRenderedItems<T extends ListItem>(items: T[], enableSections: boolean): RenderItem<T>[];
|
|
24
26
|
export interface ListViewRowProps<T extends ListItem> {
|
|
25
27
|
renderedItems: RenderItem<T>[];
|
|
28
|
+
activeIndex: number;
|
|
26
29
|
isLoading?: boolean;
|
|
27
30
|
isDarkMode?: boolean;
|
|
28
31
|
onItemClick: (item: T) => void;
|
|
29
32
|
onItemHover?: (item: T) => void;
|
|
30
33
|
}
|
|
34
|
+
export interface ListViewHandle<T extends ListItem = ListItem> {
|
|
35
|
+
renderedItems: RenderItem<T>[];
|
|
36
|
+
}
|
|
31
37
|
interface ListViewProps<T extends ListItem> {
|
|
32
38
|
items: T[];
|
|
39
|
+
activeIndex?: number;
|
|
40
|
+
listRef?: React.RefObject<ListImperativeAPI | null>;
|
|
33
41
|
onItemClick: (item: T) => void;
|
|
34
42
|
onItemHover?: (item: T) => void;
|
|
35
43
|
emptyStateMessage?: string;
|
|
@@ -37,6 +45,8 @@ interface ListViewProps<T extends ListItem> {
|
|
|
37
45
|
isLoading?: boolean;
|
|
38
46
|
enableSections?: boolean;
|
|
39
47
|
}
|
|
40
|
-
export declare const ListView:
|
|
48
|
+
export declare const ListView: <T extends ListItem>(props: ListViewProps<T> & {
|
|
49
|
+
ref?: React.Ref<ListViewHandle<T>>;
|
|
50
|
+
}) => React.ReactElement | null;
|
|
41
51
|
export {};
|
|
42
52
|
//# sourceMappingURL=ListView.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/ListView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/ListView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,cAAc,CAAC;AAIzE,MAAM,WAAW,YAAY;IAI3B,IAAI,CAAC,EAAE,MAAM,CAAC;IAId,GAAG,CAAC,EAAE,MAAM,CAAC;IAIb,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CACjC;AAED,MAAM,MAAM,QAAQ,CAAC,CAAC,GAAG,GAAG,IAAI;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CACnF,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,QAAQ,IACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC;AAE9B,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EACnD,KAAK,EAAE,CAAC,EAAE,EACV,cAAc,EAAE,OAAO,GACtB,UAAU,CAAC,CAAC,CAAC,EAAE,CAqCjB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,QAAQ;IAClD,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;CACjC;AAgHD,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ;IAC3D,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;CAChC;AAED,UAAU,aAAa,CAAC,CAAC,SAAS,QAAQ;IACxC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACpD,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAsED,eAAO,MAAM,QAAQ,EAA0B,CAAC,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;CAAE,KAC7D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
|
|
@@ -4,11 +4,40 @@ import { Column } from "../../layouts/index.js";
|
|
|
4
4
|
import { NodeIcon, partition } from "../../utils/index.js";
|
|
5
5
|
import { ApSkeleton, ApTypography } from "../../../material/index.js";
|
|
6
6
|
import { ApIcon, ApTooltip } from "../../../material/components/index.js";
|
|
7
|
-
import { memo, useCallback, useMemo } from "react";
|
|
7
|
+
import { forwardRef, memo, useCallback, useImperativeHandle, useMemo } from "react";
|
|
8
8
|
import { useCanvasTheme } from "../BaseCanvas/CanvasThemeContext.js";
|
|
9
9
|
import { IconContainer, ListItemButton, SectionHeader, StyledList } from "./ListView.styles.js";
|
|
10
|
+
function buildRenderedItems(items, enableSections) {
|
|
11
|
+
const result = [];
|
|
12
|
+
if (0 === items.length) return result;
|
|
13
|
+
if (!enableSections) {
|
|
14
|
+
for (const item of items)result.push({
|
|
15
|
+
type: 'item',
|
|
16
|
+
item
|
|
17
|
+
});
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
const [itemsWithSection, itemsWithoutSection] = partition(items, (item)=>!!item.section);
|
|
21
|
+
for (const item of itemsWithoutSection)result.push({
|
|
22
|
+
type: 'item',
|
|
23
|
+
item
|
|
24
|
+
});
|
|
25
|
+
if (0 === itemsWithSection.length) return result;
|
|
26
|
+
const sections = Array.from(new Set(itemsWithSection.map((item)=>item.section)));
|
|
27
|
+
for (const section of sections){
|
|
28
|
+
result.push({
|
|
29
|
+
type: 'section',
|
|
30
|
+
sectionName: section
|
|
31
|
+
});
|
|
32
|
+
for (const item of itemsWithSection.filter((item)=>item.section === section))result.push({
|
|
33
|
+
type: 'item',
|
|
34
|
+
item
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
10
39
|
const IconContainerMemoized = /*#__PURE__*/ memo(IconContainer);
|
|
11
|
-
const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, renderedItems, isLoading, isDarkMode, onItemClick, onItemHover })=>{
|
|
40
|
+
const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, renderedItems, activeIndex, isLoading, isDarkMode, onItemClick, onItemHover })=>{
|
|
12
41
|
const renderItem = renderedItems[index];
|
|
13
42
|
const buttonStyle = useMemo(()=>({
|
|
14
43
|
...style,
|
|
@@ -46,12 +75,17 @@ const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, rendered
|
|
|
46
75
|
});
|
|
47
76
|
const item = renderItem.item;
|
|
48
77
|
const bgColor = isDarkMode ? item.colorDark ?? item.color : item.color;
|
|
78
|
+
const isActive = index === activeIndex;
|
|
49
79
|
return /*#__PURE__*/ jsxs(ListItemButton, {
|
|
50
80
|
...ariaAttributes,
|
|
81
|
+
tabIndex: -1,
|
|
82
|
+
id: `toolbox-item-${item.id}`,
|
|
83
|
+
role: "option",
|
|
84
|
+
"aria-selected": isActive,
|
|
51
85
|
style: buttonStyle,
|
|
52
86
|
onClick: handleButtonClick,
|
|
53
87
|
onHoverStart: handleButtonHover,
|
|
54
|
-
className: isLoading ? 'loading' : ''
|
|
88
|
+
className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
|
|
55
89
|
disabled: isLoading,
|
|
56
90
|
children: [
|
|
57
91
|
/*#__PURE__*/ jsxs(IconContainerMemoized, {
|
|
@@ -106,48 +140,27 @@ const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, rendered
|
|
|
106
140
|
]
|
|
107
141
|
});
|
|
108
142
|
});
|
|
109
|
-
const
|
|
143
|
+
const ListViewInner = /*#__PURE__*/ forwardRef(function({ items, activeIndex = -1, listRef, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }, ref) {
|
|
110
144
|
const { isDarkMode } = useCanvasTheme();
|
|
111
|
-
const renderedItems = useMemo(()=>
|
|
112
|
-
const result = [];
|
|
113
|
-
if (0 === items.length) return result;
|
|
114
|
-
if (!enableSections) {
|
|
115
|
-
for (const item of items)result.push({
|
|
116
|
-
type: 'item',
|
|
117
|
-
item
|
|
118
|
-
});
|
|
119
|
-
return result;
|
|
120
|
-
}
|
|
121
|
-
const [itemsWithSection, itemsWithoutSection] = partition(items, (item)=>!!item.section);
|
|
122
|
-
for (const item of itemsWithoutSection)result.push({
|
|
123
|
-
type: 'item',
|
|
124
|
-
item
|
|
125
|
-
});
|
|
126
|
-
if (0 === itemsWithSection.length) return result;
|
|
127
|
-
const sections = Array.from(new Set(itemsWithSection.map((item)=>item.section)));
|
|
128
|
-
for (const section of sections){
|
|
129
|
-
result.push({
|
|
130
|
-
type: 'section',
|
|
131
|
-
sectionName: section
|
|
132
|
-
});
|
|
133
|
-
for (const item of itemsWithSection.filter((item)=>item.section === section))result.push({
|
|
134
|
-
type: 'item',
|
|
135
|
-
item
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
}, [
|
|
145
|
+
const renderedItems = useMemo(()=>buildRenderedItems(items, enableSections), [
|
|
140
146
|
items,
|
|
141
147
|
enableSections
|
|
142
148
|
]);
|
|
149
|
+
useImperativeHandle(ref, ()=>({
|
|
150
|
+
renderedItems
|
|
151
|
+
}), [
|
|
152
|
+
renderedItems
|
|
153
|
+
]);
|
|
143
154
|
const rowProps = useMemo(()=>({
|
|
144
155
|
renderedItems,
|
|
156
|
+
activeIndex,
|
|
145
157
|
isLoading,
|
|
146
158
|
isDarkMode,
|
|
147
159
|
onItemClick,
|
|
148
160
|
onItemHover
|
|
149
161
|
}), [
|
|
150
162
|
renderedItems,
|
|
163
|
+
activeIndex,
|
|
151
164
|
isLoading,
|
|
152
165
|
isDarkMode,
|
|
153
166
|
onItemClick,
|
|
@@ -187,6 +200,9 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
|
|
|
187
200
|
]
|
|
188
201
|
});
|
|
189
202
|
return /*#__PURE__*/ jsx(StyledList, {
|
|
203
|
+
id: "toolbox-listbox",
|
|
204
|
+
role: "listbox",
|
|
205
|
+
listRef: listRef,
|
|
190
206
|
rowProps: rowProps,
|
|
191
207
|
rowComponent: ListViewRow,
|
|
192
208
|
rowCount: renderedItems.length,
|
|
@@ -194,4 +210,5 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
|
|
|
194
210
|
overscanCount: 20
|
|
195
211
|
});
|
|
196
212
|
});
|
|
197
|
-
|
|
213
|
+
const ListView_ListView = /*#__PURE__*/ memo(ListViewInner);
|
|
214
|
+
export { ListView_ListView as ListView, buildRenderedItems };
|
|
@@ -68,9 +68,15 @@ const ListItemButton = styled_default()(react_namespaceObject.motion.button)`
|
|
|
68
68
|
width: 100%;
|
|
69
69
|
transition: all 0.15s ease;
|
|
70
70
|
|
|
71
|
-
&:hover
|
|
71
|
+
&:hover,
|
|
72
|
+
&.active {
|
|
72
73
|
background: var(--uix-canvas-background-hover);
|
|
73
74
|
}
|
|
75
|
+
|
|
76
|
+
&.active {
|
|
77
|
+
outline: 1px solid var(--uix-canvas-primary);
|
|
78
|
+
outline-offset: -1px;
|
|
79
|
+
}
|
|
74
80
|
`;
|
|
75
81
|
const IconContainer = styled_default().div`
|
|
76
82
|
width: 32px;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListView.styles.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/ListView.styles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,eAAO,MAAM,aAAa;;;yGAazB,CAAC;AAEF,eAAO,MAAM,cAAc;;
|
|
1
|
+
{"version":3,"file":"ListView.styles.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/ListView.styles.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,eAAO,MAAM,aAAa;;;yGAazB,CAAC;AAEF,eAAO,MAAM,cAAc;;UAqB1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;cAA0B,MAAM;yGAazD,CAAC;AAEF,eAAO,MAAM,UAAU,EAkClB,OAAO,IAAI,CAAC"}
|
|
@@ -27,9 +27,15 @@ const ListItemButton = styled(motion.button)`
|
|
|
27
27
|
width: 100%;
|
|
28
28
|
transition: all 0.15s ease;
|
|
29
29
|
|
|
30
|
-
&:hover
|
|
30
|
+
&:hover,
|
|
31
|
+
&.active {
|
|
31
32
|
background: var(--uix-canvas-background-hover);
|
|
32
33
|
}
|
|
34
|
+
|
|
35
|
+
&.active {
|
|
36
|
+
outline: 1px solid var(--uix-canvas-primary);
|
|
37
|
+
outline-offset: -1px;
|
|
38
|
+
}
|
|
33
39
|
`;
|
|
34
40
|
const IconContainer = styled.div`
|
|
35
41
|
width: 32px;
|
|
@@ -31,11 +31,14 @@ const index_cjs_namespaceObject = require("../../utils/index.cjs");
|
|
|
31
31
|
const components_index_cjs_namespaceObject = require("../../../material/components/index.cjs");
|
|
32
32
|
const external_react_namespaceObject = require("react");
|
|
33
33
|
const external_SearchBox_styles_cjs_namespaceObject = require("./SearchBox.styles.cjs");
|
|
34
|
-
const SearchBox_SearchBox = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(function({ value, onChange, clear, placeholder = 'Search...' }) {
|
|
35
|
-
const
|
|
34
|
+
const SearchBox_SearchBox = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(function({ value, onChange, clear, placeholder = 'Search...', inputRef: externalInputRef, onNavigationKeyDown, activeDescendantId }) {
|
|
35
|
+
const internalRef = (0, external_react_namespaceObject.useRef)(null);
|
|
36
|
+
const inputRef = externalInputRef ?? internalRef;
|
|
36
37
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
37
38
|
inputRef.current?.focus();
|
|
38
|
-
}, [
|
|
39
|
+
}, [
|
|
40
|
+
inputRef
|
|
41
|
+
]);
|
|
39
42
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_SearchBox_styles_cjs_namespaceObject.StyledSearchForm, {
|
|
40
43
|
autoComplete: "off",
|
|
41
44
|
className: "searchbox-form",
|
|
@@ -56,10 +59,15 @@ const SearchBox_SearchBox = /*#__PURE__*/ (0, external_react_namespaceObject.mem
|
|
|
56
59
|
ref: inputRef,
|
|
57
60
|
autoComplete: "off",
|
|
58
61
|
type: "text",
|
|
62
|
+
role: "combobox",
|
|
63
|
+
"aria-controls": "toolbox-listbox",
|
|
64
|
+
"aria-expanded": true,
|
|
59
65
|
className: "searchbox-input",
|
|
60
66
|
placeholder: placeholder,
|
|
61
67
|
value: value,
|
|
62
|
-
onChange: (e)=>onChange(e.target.value)
|
|
68
|
+
onChange: (e)=>onChange(e.target.value),
|
|
69
|
+
onKeyDown: onNavigationKeyDown,
|
|
70
|
+
"aria-activedescendant": activeDescendantId
|
|
63
71
|
}),
|
|
64
72
|
value && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
|
|
65
73
|
type: "button",
|
|
@@ -3,6 +3,9 @@ interface SearchBoxProps {
|
|
|
3
3
|
onChange: (value: string) => void;
|
|
4
4
|
clear: () => void;
|
|
5
5
|
placeholder?: string;
|
|
6
|
+
inputRef?: React.RefObject<HTMLInputElement | null>;
|
|
7
|
+
onNavigationKeyDown?: (e: React.KeyboardEvent) => void;
|
|
8
|
+
activeDescendantId?: string;
|
|
6
9
|
}
|
|
7
10
|
export declare const SearchBox: import("react").NamedExoticComponent<SearchBoxProps>;
|
|
8
11
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchBox.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/SearchBox.tsx"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchBox.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/SearchBox.tsx"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACpD,mBAAmB,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,eAAO,MAAM,SAAS,sDAgDpB,CAAC"}
|
|
@@ -3,11 +3,14 @@ import { cx } from "../../utils/index.js";
|
|
|
3
3
|
import { ApIcon } from "../../../material/components/index.js";
|
|
4
4
|
import { memo, useEffect, useRef } from "react";
|
|
5
5
|
import { StyledSearchForm } from "./SearchBox.styles.js";
|
|
6
|
-
const SearchBox_SearchBox = /*#__PURE__*/ memo(function({ value, onChange, clear, placeholder = 'Search...' }) {
|
|
7
|
-
const
|
|
6
|
+
const SearchBox_SearchBox = /*#__PURE__*/ memo(function({ value, onChange, clear, placeholder = 'Search...', inputRef: externalInputRef, onNavigationKeyDown, activeDescendantId }) {
|
|
7
|
+
const internalRef = useRef(null);
|
|
8
|
+
const inputRef = externalInputRef ?? internalRef;
|
|
8
9
|
useEffect(()=>{
|
|
9
10
|
inputRef.current?.focus();
|
|
10
|
-
}, [
|
|
11
|
+
}, [
|
|
12
|
+
inputRef
|
|
13
|
+
]);
|
|
11
14
|
return /*#__PURE__*/ jsx(StyledSearchForm, {
|
|
12
15
|
autoComplete: "off",
|
|
13
16
|
className: "searchbox-form",
|
|
@@ -28,10 +31,15 @@ const SearchBox_SearchBox = /*#__PURE__*/ memo(function({ value, onChange, clear
|
|
|
28
31
|
ref: inputRef,
|
|
29
32
|
autoComplete: "off",
|
|
30
33
|
type: "text",
|
|
34
|
+
role: "combobox",
|
|
35
|
+
"aria-controls": "toolbox-listbox",
|
|
36
|
+
"aria-expanded": true,
|
|
31
37
|
className: "searchbox-input",
|
|
32
38
|
placeholder: placeholder,
|
|
33
39
|
value: value,
|
|
34
|
-
onChange: (e)=>onChange(e.target.value)
|
|
40
|
+
onChange: (e)=>onChange(e.target.value),
|
|
41
|
+
onKeyDown: onNavigationKeyDown,
|
|
42
|
+
"aria-activedescendant": activeDescendantId
|
|
35
43
|
}),
|
|
36
44
|
value && /*#__PURE__*/ jsx("button", {
|
|
37
45
|
type: "button",
|
|
@@ -30,6 +30,7 @@ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
|
30
30
|
const index_cjs_namespaceObject = require("../../hooks/index.cjs");
|
|
31
31
|
const external_layouts_index_cjs_namespaceObject = require("../../layouts/index.cjs");
|
|
32
32
|
const external_react_namespaceObject = require("react");
|
|
33
|
+
const external_react_window_namespaceObject = require("react-window");
|
|
33
34
|
const external_Header_cjs_namespaceObject = require("./Header.cjs");
|
|
34
35
|
const external_ListView_cjs_namespaceObject = require("./ListView.cjs");
|
|
35
36
|
const external_SearchBox_cjs_namespaceObject = require("./SearchBox.cjs");
|
|
@@ -52,6 +53,22 @@ function findItemById(items, id) {
|
|
|
52
53
|
}
|
|
53
54
|
return null;
|
|
54
55
|
}
|
|
56
|
+
function getNextSelectableIndex(renderedItems, currentIndex, direction) {
|
|
57
|
+
let next = currentIndex + direction;
|
|
58
|
+
while(next >= 0 && next < renderedItems.length){
|
|
59
|
+
if (renderedItems[next]?.type === 'item') return next;
|
|
60
|
+
next += direction;
|
|
61
|
+
}
|
|
62
|
+
return -1;
|
|
63
|
+
}
|
|
64
|
+
function getFirstSelectableIndex(renderedItems) {
|
|
65
|
+
for(let i = 0; i < renderedItems.length; i++)if (renderedItems[i]?.type === 'item') return i;
|
|
66
|
+
return -1;
|
|
67
|
+
}
|
|
68
|
+
function getLastSelectableIndex(renderedItems) {
|
|
69
|
+
for(let i = renderedItems.length - 1; i >= 0; i--)if (renderedItems[i]?.type === 'item') return i;
|
|
70
|
+
return -1;
|
|
71
|
+
}
|
|
55
72
|
function searchLeafItems(items, query) {
|
|
56
73
|
const results = [];
|
|
57
74
|
for (const item of items)if ('function' != typeof item.children) {
|
|
@@ -71,13 +88,23 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
71
88
|
const [isTransitioning, setIsTransitioning] = (0, external_react_namespaceObject.useState)(false);
|
|
72
89
|
const [animationDirection, setAnimationDirection] = (0, external_react_namespaceObject.useState)('forward');
|
|
73
90
|
const navigationStack = (0, index_cjs_namespaceObject.useNavigationStack)();
|
|
91
|
+
const [activeIndex, setActiveIndex] = (0, external_react_namespaceObject.useState)(-1);
|
|
74
92
|
const containerRef = (0, external_react_namespaceObject.useRef)(null);
|
|
75
93
|
const transitionTimeoutRef = (0, external_react_namespaceObject.useRef)(void 0);
|
|
76
94
|
const searchIdRef = (0, external_react_namespaceObject.useRef)(0);
|
|
77
95
|
const initialItemsRef = (0, external_react_namespaceObject.useRef)(initialItems);
|
|
96
|
+
const listRef = (0, external_react_window_namespaceObject.useListRef)(null);
|
|
97
|
+
const listViewRef = (0, external_react_namespaceObject.useRef)(null);
|
|
98
|
+
const searchInputRef = (0, external_react_namespaceObject.useRef)(null);
|
|
78
99
|
const isSearching = (0, external_react_namespaceObject.useMemo)(()=>search.length > 0, [
|
|
79
100
|
search
|
|
80
101
|
]);
|
|
102
|
+
const displayedItems = (0, external_react_namespaceObject.useMemo)(()=>isSearching && !isSearchingInitialItems ? searchedItems : items, [
|
|
103
|
+
isSearching,
|
|
104
|
+
isSearchingInitialItems,
|
|
105
|
+
searchedItems,
|
|
106
|
+
items
|
|
107
|
+
]);
|
|
81
108
|
const startTransition = (0, external_react_namespaceObject.useCallback)((direction)=>{
|
|
82
109
|
if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
|
|
83
110
|
setIsTransitioning(true);
|
|
@@ -86,11 +113,22 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
86
113
|
setIsTransitioning(false);
|
|
87
114
|
}, TRANSITION_DURATION);
|
|
88
115
|
}, []);
|
|
116
|
+
const navigateToIndex = (0, external_react_namespaceObject.useCallback)((index)=>{
|
|
117
|
+
setActiveIndex(index);
|
|
118
|
+
if (-1 === index) return void searchInputRef.current?.focus();
|
|
119
|
+
listRef.current?.scrollToRow({
|
|
120
|
+
index,
|
|
121
|
+
align: 'auto'
|
|
122
|
+
});
|
|
123
|
+
}, [
|
|
124
|
+
listRef
|
|
125
|
+
]);
|
|
89
126
|
const clearSearch = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
90
127
|
setSearch('');
|
|
91
128
|
setSearchedItems([]);
|
|
92
129
|
setSearchLoading(false);
|
|
93
130
|
setIsSearchingInitialItems(true);
|
|
131
|
+
setActiveIndex(-1);
|
|
94
132
|
}, []);
|
|
95
133
|
const handleSearch = (0, external_react_namespaceObject.useCallback)(async (query)=>{
|
|
96
134
|
if (!query.trim()) {
|
|
@@ -101,6 +139,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
101
139
|
return;
|
|
102
140
|
}
|
|
103
141
|
setSearch(query);
|
|
142
|
+
setActiveIndex(-1);
|
|
104
143
|
searchIdRef.current += 1;
|
|
105
144
|
const currentRequestId = searchIdRef.current;
|
|
106
145
|
setSearchLoading(true);
|
|
@@ -121,6 +160,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
121
160
|
]);
|
|
122
161
|
const handleBackTransition = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
123
162
|
startTransition('back');
|
|
163
|
+
setActiveIndex(-1);
|
|
124
164
|
const previousState = navigationStack.pop();
|
|
125
165
|
if (previousState) {
|
|
126
166
|
setItems(previousState.data.items);
|
|
@@ -149,6 +189,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
149
189
|
setItems(nestedItems);
|
|
150
190
|
setCurrentParentItem(item);
|
|
151
191
|
clearSearch();
|
|
192
|
+
setActiveIndex(-1);
|
|
152
193
|
startTransition('forward');
|
|
153
194
|
setChildrenLoading(false);
|
|
154
195
|
}, [
|
|
@@ -206,6 +247,96 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
206
247
|
}, [
|
|
207
248
|
items
|
|
208
249
|
]);
|
|
250
|
+
const activeDescendantId = (0, external_react_namespaceObject.useMemo)(()=>{
|
|
251
|
+
if (activeIndex < 0) return;
|
|
252
|
+
const renderItem = listViewRef.current?.renderedItems[activeIndex];
|
|
253
|
+
if (renderItem?.type === 'item') return `toolbox-item-${renderItem.item.id}`;
|
|
254
|
+
}, [
|
|
255
|
+
activeIndex
|
|
256
|
+
]);
|
|
257
|
+
const handleNavigationKeyDown = (0, external_react_namespaceObject.useCallback)((e)=>{
|
|
258
|
+
if (isTransitioning) return;
|
|
259
|
+
const renderedItems = listViewRef.current?.renderedItems ?? [];
|
|
260
|
+
const navigateDown = ()=>{
|
|
261
|
+
if (-1 === activeIndex) {
|
|
262
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
263
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
264
|
+
} else {
|
|
265
|
+
const nextIndex = getNextSelectableIndex(renderedItems, activeIndex, 1);
|
|
266
|
+
if (-1 !== nextIndex) navigateToIndex(nextIndex);
|
|
267
|
+
else {
|
|
268
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
269
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
const navigateUp = ()=>{
|
|
274
|
+
activeIndex <= 0 || -1 === getNextSelectableIndex(renderedItems, activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(renderedItems, activeIndex, -1));
|
|
275
|
+
};
|
|
276
|
+
switch(e.key){
|
|
277
|
+
case 'ArrowDown':
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
navigateDown();
|
|
280
|
+
break;
|
|
281
|
+
case 'ArrowUp':
|
|
282
|
+
e.preventDefault();
|
|
283
|
+
navigateUp();
|
|
284
|
+
break;
|
|
285
|
+
case 'Space':
|
|
286
|
+
case 'Enter':
|
|
287
|
+
if (activeIndex >= 0) {
|
|
288
|
+
const renderItem = renderedItems[activeIndex];
|
|
289
|
+
if (renderItem?.type === 'item') {
|
|
290
|
+
e.preventDefault();
|
|
291
|
+
handleItemSelect(renderItem.item);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
break;
|
|
295
|
+
case 'ArrowRight':
|
|
296
|
+
if (activeIndex >= 0) {
|
|
297
|
+
const renderItem = renderedItems[activeIndex];
|
|
298
|
+
if (renderItem?.type === 'item' && renderItem.item.children) {
|
|
299
|
+
e.preventDefault();
|
|
300
|
+
handleItemSelect(renderItem.item);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
break;
|
|
304
|
+
case 'ArrowLeft':
|
|
305
|
+
if (activeIndex >= 0 && navigationStack.canGoBack) {
|
|
306
|
+
e.preventDefault();
|
|
307
|
+
handleBackTransition();
|
|
308
|
+
}
|
|
309
|
+
break;
|
|
310
|
+
case 'Tab':
|
|
311
|
+
e.preventDefault();
|
|
312
|
+
if (e.shiftKey) navigateUp();
|
|
313
|
+
else navigateDown();
|
|
314
|
+
break;
|
|
315
|
+
case 'Home':
|
|
316
|
+
{
|
|
317
|
+
if (-1 === activeIndex) break;
|
|
318
|
+
e.preventDefault();
|
|
319
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
320
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
case 'End':
|
|
324
|
+
{
|
|
325
|
+
if (-1 === activeIndex) break;
|
|
326
|
+
e.preventDefault();
|
|
327
|
+
const lastIndex = getLastSelectableIndex(renderedItems);
|
|
328
|
+
if (-1 !== lastIndex) navigateToIndex(lastIndex);
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}, [
|
|
333
|
+
isTransitioning,
|
|
334
|
+
activeIndex,
|
|
335
|
+
navigationStack.canGoBack,
|
|
336
|
+
navigateToIndex,
|
|
337
|
+
handleItemSelect,
|
|
338
|
+
handleBackTransition
|
|
339
|
+
]);
|
|
209
340
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
210
341
|
const handleKeyDown = (e)=>{
|
|
211
342
|
if ('Escape' === e.key) if (isSearching) {
|
|
@@ -251,19 +382,25 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
251
382
|
value: search,
|
|
252
383
|
onChange: handleSearch,
|
|
253
384
|
clear: clearSearch,
|
|
254
|
-
placeholder: "Search"
|
|
385
|
+
placeholder: "Search",
|
|
386
|
+
inputRef: searchInputRef,
|
|
387
|
+
onNavigationKeyDown: handleNavigationKeyDown,
|
|
388
|
+
activeDescendantId: activeDescendantId
|
|
255
389
|
}),
|
|
256
390
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContainer, {
|
|
257
391
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContent, {
|
|
258
392
|
entering: isTransitioning,
|
|
259
393
|
direction: animationDirection,
|
|
260
394
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_cjs_namespaceObject.ListView, {
|
|
395
|
+
ref: listViewRef,
|
|
261
396
|
isLoading: childrenLoading || searchLoading || loading,
|
|
262
|
-
items:
|
|
397
|
+
items: displayedItems,
|
|
398
|
+
activeIndex: activeIndex,
|
|
399
|
+
listRef: listRef,
|
|
263
400
|
emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
|
|
264
|
-
enableSections: !isSearching,
|
|
265
401
|
onItemClick: handleItemSelect,
|
|
266
|
-
onItemHover: onItemHover
|
|
402
|
+
onItemHover: onItemHover,
|
|
403
|
+
enableSections: !isSearching
|
|
267
404
|
})
|
|
268
405
|
})
|
|
269
406
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toolbox.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/Toolbox.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toolbox.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/Toolbox.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,QAAQ,EAAkD,MAAM,YAAY,CAAC;AAuC3F,MAAM,MAAM,oBAAoB,CAAC,CAAC,GAAG,GAAG,IAAI,CAC1C,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,OAAO,EACzB,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE;IAAE,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,KAC5E,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE5B,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CACpC;AA+CD,wBAAgB,OAAO,CAAC,CAAC,EAAE,EACzB,OAAO,EACP,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,KAAK,EACL,YAAY,EACZ,OAAO,GACR,EAAE,YAAY,CAAC,CAAC,CAAC,2CA2ZjB"}
|
|
@@ -2,6 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useNavigationStack } from "../../hooks/index.js";
|
|
3
3
|
import { Column } from "../../layouts/index.js";
|
|
4
4
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { useListRef } from "react-window";
|
|
5
6
|
import { Header } from "./Header.js";
|
|
6
7
|
import { ListView } from "./ListView.js";
|
|
7
8
|
import { SearchBox } from "./SearchBox.js";
|
|
@@ -24,6 +25,22 @@ function findItemById(items, id) {
|
|
|
24
25
|
}
|
|
25
26
|
return null;
|
|
26
27
|
}
|
|
28
|
+
function getNextSelectableIndex(renderedItems, currentIndex, direction) {
|
|
29
|
+
let next = currentIndex + direction;
|
|
30
|
+
while(next >= 0 && next < renderedItems.length){
|
|
31
|
+
if (renderedItems[next]?.type === 'item') return next;
|
|
32
|
+
next += direction;
|
|
33
|
+
}
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
function getFirstSelectableIndex(renderedItems) {
|
|
37
|
+
for(let i = 0; i < renderedItems.length; i++)if (renderedItems[i]?.type === 'item') return i;
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
function getLastSelectableIndex(renderedItems) {
|
|
41
|
+
for(let i = renderedItems.length - 1; i >= 0; i--)if (renderedItems[i]?.type === 'item') return i;
|
|
42
|
+
return -1;
|
|
43
|
+
}
|
|
27
44
|
function searchLeafItems(items, query) {
|
|
28
45
|
const results = [];
|
|
29
46
|
for (const item of items)if ('function' != typeof item.children) {
|
|
@@ -43,13 +60,23 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
43
60
|
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
44
61
|
const [animationDirection, setAnimationDirection] = useState('forward');
|
|
45
62
|
const navigationStack = useNavigationStack();
|
|
63
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
46
64
|
const containerRef = useRef(null);
|
|
47
65
|
const transitionTimeoutRef = useRef(void 0);
|
|
48
66
|
const searchIdRef = useRef(0);
|
|
49
67
|
const initialItemsRef = useRef(initialItems);
|
|
68
|
+
const listRef = useListRef(null);
|
|
69
|
+
const listViewRef = useRef(null);
|
|
70
|
+
const searchInputRef = useRef(null);
|
|
50
71
|
const isSearching = useMemo(()=>search.length > 0, [
|
|
51
72
|
search
|
|
52
73
|
]);
|
|
74
|
+
const displayedItems = useMemo(()=>isSearching && !isSearchingInitialItems ? searchedItems : items, [
|
|
75
|
+
isSearching,
|
|
76
|
+
isSearchingInitialItems,
|
|
77
|
+
searchedItems,
|
|
78
|
+
items
|
|
79
|
+
]);
|
|
53
80
|
const startTransition = useCallback((direction)=>{
|
|
54
81
|
if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
|
|
55
82
|
setIsTransitioning(true);
|
|
@@ -58,11 +85,22 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
58
85
|
setIsTransitioning(false);
|
|
59
86
|
}, TRANSITION_DURATION);
|
|
60
87
|
}, []);
|
|
88
|
+
const navigateToIndex = useCallback((index)=>{
|
|
89
|
+
setActiveIndex(index);
|
|
90
|
+
if (-1 === index) return void searchInputRef.current?.focus();
|
|
91
|
+
listRef.current?.scrollToRow({
|
|
92
|
+
index,
|
|
93
|
+
align: 'auto'
|
|
94
|
+
});
|
|
95
|
+
}, [
|
|
96
|
+
listRef
|
|
97
|
+
]);
|
|
61
98
|
const clearSearch = useCallback(()=>{
|
|
62
99
|
setSearch('');
|
|
63
100
|
setSearchedItems([]);
|
|
64
101
|
setSearchLoading(false);
|
|
65
102
|
setIsSearchingInitialItems(true);
|
|
103
|
+
setActiveIndex(-1);
|
|
66
104
|
}, []);
|
|
67
105
|
const handleSearch = useCallback(async (query)=>{
|
|
68
106
|
if (!query.trim()) {
|
|
@@ -73,6 +111,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
73
111
|
return;
|
|
74
112
|
}
|
|
75
113
|
setSearch(query);
|
|
114
|
+
setActiveIndex(-1);
|
|
76
115
|
searchIdRef.current += 1;
|
|
77
116
|
const currentRequestId = searchIdRef.current;
|
|
78
117
|
setSearchLoading(true);
|
|
@@ -93,6 +132,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
93
132
|
]);
|
|
94
133
|
const handleBackTransition = useCallback(()=>{
|
|
95
134
|
startTransition('back');
|
|
135
|
+
setActiveIndex(-1);
|
|
96
136
|
const previousState = navigationStack.pop();
|
|
97
137
|
if (previousState) {
|
|
98
138
|
setItems(previousState.data.items);
|
|
@@ -121,6 +161,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
121
161
|
setItems(nestedItems);
|
|
122
162
|
setCurrentParentItem(item);
|
|
123
163
|
clearSearch();
|
|
164
|
+
setActiveIndex(-1);
|
|
124
165
|
startTransition('forward');
|
|
125
166
|
setChildrenLoading(false);
|
|
126
167
|
}, [
|
|
@@ -178,6 +219,96 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
178
219
|
}, [
|
|
179
220
|
items
|
|
180
221
|
]);
|
|
222
|
+
const activeDescendantId = useMemo(()=>{
|
|
223
|
+
if (activeIndex < 0) return;
|
|
224
|
+
const renderItem = listViewRef.current?.renderedItems[activeIndex];
|
|
225
|
+
if (renderItem?.type === 'item') return `toolbox-item-${renderItem.item.id}`;
|
|
226
|
+
}, [
|
|
227
|
+
activeIndex
|
|
228
|
+
]);
|
|
229
|
+
const handleNavigationKeyDown = useCallback((e)=>{
|
|
230
|
+
if (isTransitioning) return;
|
|
231
|
+
const renderedItems = listViewRef.current?.renderedItems ?? [];
|
|
232
|
+
const navigateDown = ()=>{
|
|
233
|
+
if (-1 === activeIndex) {
|
|
234
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
235
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
236
|
+
} else {
|
|
237
|
+
const nextIndex = getNextSelectableIndex(renderedItems, activeIndex, 1);
|
|
238
|
+
if (-1 !== nextIndex) navigateToIndex(nextIndex);
|
|
239
|
+
else {
|
|
240
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
241
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
const navigateUp = ()=>{
|
|
246
|
+
activeIndex <= 0 || -1 === getNextSelectableIndex(renderedItems, activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(renderedItems, activeIndex, -1));
|
|
247
|
+
};
|
|
248
|
+
switch(e.key){
|
|
249
|
+
case 'ArrowDown':
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
navigateDown();
|
|
252
|
+
break;
|
|
253
|
+
case 'ArrowUp':
|
|
254
|
+
e.preventDefault();
|
|
255
|
+
navigateUp();
|
|
256
|
+
break;
|
|
257
|
+
case 'Space':
|
|
258
|
+
case 'Enter':
|
|
259
|
+
if (activeIndex >= 0) {
|
|
260
|
+
const renderItem = renderedItems[activeIndex];
|
|
261
|
+
if (renderItem?.type === 'item') {
|
|
262
|
+
e.preventDefault();
|
|
263
|
+
handleItemSelect(renderItem.item);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
break;
|
|
267
|
+
case 'ArrowRight':
|
|
268
|
+
if (activeIndex >= 0) {
|
|
269
|
+
const renderItem = renderedItems[activeIndex];
|
|
270
|
+
if (renderItem?.type === 'item' && renderItem.item.children) {
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
handleItemSelect(renderItem.item);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
case 'ArrowLeft':
|
|
277
|
+
if (activeIndex >= 0 && navigationStack.canGoBack) {
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
handleBackTransition();
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
case 'Tab':
|
|
283
|
+
e.preventDefault();
|
|
284
|
+
if (e.shiftKey) navigateUp();
|
|
285
|
+
else navigateDown();
|
|
286
|
+
break;
|
|
287
|
+
case 'Home':
|
|
288
|
+
{
|
|
289
|
+
if (-1 === activeIndex) break;
|
|
290
|
+
e.preventDefault();
|
|
291
|
+
const firstIndex = getFirstSelectableIndex(renderedItems);
|
|
292
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case 'End':
|
|
296
|
+
{
|
|
297
|
+
if (-1 === activeIndex) break;
|
|
298
|
+
e.preventDefault();
|
|
299
|
+
const lastIndex = getLastSelectableIndex(renderedItems);
|
|
300
|
+
if (-1 !== lastIndex) navigateToIndex(lastIndex);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}, [
|
|
305
|
+
isTransitioning,
|
|
306
|
+
activeIndex,
|
|
307
|
+
navigationStack.canGoBack,
|
|
308
|
+
navigateToIndex,
|
|
309
|
+
handleItemSelect,
|
|
310
|
+
handleBackTransition
|
|
311
|
+
]);
|
|
181
312
|
useEffect(()=>{
|
|
182
313
|
const handleKeyDown = (e)=>{
|
|
183
314
|
if ('Escape' === e.key) if (isSearching) {
|
|
@@ -223,19 +354,25 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
223
354
|
value: search,
|
|
224
355
|
onChange: handleSearch,
|
|
225
356
|
clear: clearSearch,
|
|
226
|
-
placeholder: "Search"
|
|
357
|
+
placeholder: "Search",
|
|
358
|
+
inputRef: searchInputRef,
|
|
359
|
+
onNavigationKeyDown: handleNavigationKeyDown,
|
|
360
|
+
activeDescendantId: activeDescendantId
|
|
227
361
|
}),
|
|
228
362
|
/*#__PURE__*/ jsx(AnimatedContainer, {
|
|
229
363
|
children: /*#__PURE__*/ jsx(AnimatedContent, {
|
|
230
364
|
entering: isTransitioning,
|
|
231
365
|
direction: animationDirection,
|
|
232
366
|
children: /*#__PURE__*/ jsx(ListView, {
|
|
367
|
+
ref: listViewRef,
|
|
233
368
|
isLoading: childrenLoading || searchLoading || loading,
|
|
234
|
-
items:
|
|
369
|
+
items: displayedItems,
|
|
370
|
+
activeIndex: activeIndex,
|
|
371
|
+
listRef: listRef,
|
|
235
372
|
emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
|
|
236
|
-
enableSections: !isSearching,
|
|
237
373
|
onItemClick: handleItemSelect,
|
|
238
|
-
onItemHover: onItemHover
|
|
374
|
+
onItemHover: onItemHover,
|
|
375
|
+
enableSections: !isSearching
|
|
239
376
|
})
|
|
240
377
|
})
|
|
241
378
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/apollo-react",
|
|
3
|
-
"version": "3.54.0-pr354.
|
|
3
|
+
"version": "3.54.0-pr354.f47b811",
|
|
4
4
|
"description": "Apollo Design System - React component library with Material UI theming",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
"zod": "^4.3.5",
|
|
202
202
|
"zustand": "^5.0.9",
|
|
203
203
|
"@uipath/apollo-core": "5.7.1",
|
|
204
|
-
"@uipath/apollo-wind": "0.
|
|
204
|
+
"@uipath/apollo-wind": "0.15.0"
|
|
205
205
|
},
|
|
206
206
|
"devDependencies": {
|
|
207
207
|
"@lingui/cli": "^5.6.1",
|