@uipath/apollo-react 3.53.0-pr349.8a75b3d → 3.54.0-pr354.029fc6a
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/AddNodePanel/AddNodePanel.cjs +21 -8
- package/dist/canvas/components/AddNodePanel/AddNodePanel.d.ts.map +1 -1
- package/dist/canvas/components/AddNodePanel/AddNodePanel.js +11 -8
- package/dist/canvas/components/Toolbox/ListView.cjs +45 -34
- package/dist/canvas/components/Toolbox/ListView.d.ts +7 -2
- package/dist/canvas/components/Toolbox/ListView.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/ListView.js +41 -33
- 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 +8 -4
- package/dist/canvas/components/Toolbox/SearchBox.d.ts +2 -0
- package/dist/canvas/components/Toolbox/SearchBox.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/SearchBox.js +8 -4
- package/dist/canvas/components/Toolbox/Toolbox.cjs +140 -2
- package/dist/canvas/components/Toolbox/Toolbox.d.ts.map +1 -1
- package/dist/canvas/components/Toolbox/Toolbox.js +141 -3
- package/package.json +2 -2
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.n = (module)=>{
|
|
5
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
+
__webpack_require__.d(getter, {
|
|
7
|
+
a: getter
|
|
8
|
+
});
|
|
9
|
+
return getter;
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
3
12
|
(()=>{
|
|
4
13
|
__webpack_require__.d = (exports1, definition)=>{
|
|
5
14
|
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
@@ -28,6 +37,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
28
37
|
});
|
|
29
38
|
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
30
39
|
const external_react_namespaceObject = require("react");
|
|
40
|
+
const external_react_focus_lock_namespaceObject = require("react-focus-lock");
|
|
41
|
+
var external_react_focus_lock_default = /*#__PURE__*/ __webpack_require__.n(external_react_focus_lock_namespaceObject);
|
|
31
42
|
const index_cjs_namespaceObject = require("../../core/index.cjs");
|
|
32
43
|
const external_hooks_index_cjs_namespaceObject = require("../../hooks/index.cjs");
|
|
33
44
|
const external_Toolbox_index_cjs_namespaceObject = require("../Toolbox/index.cjs");
|
|
@@ -68,14 +79,16 @@ const AddNodePanel_AddNodePanel = /*#__PURE__*/ (0, external_react_namespaceObje
|
|
|
68
79
|
}, [
|
|
69
80
|
onNodeSelect
|
|
70
81
|
]);
|
|
71
|
-
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_react_focus_lock_default(), {
|
|
83
|
+
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_index_cjs_namespaceObject.Toolbox, {
|
|
84
|
+
title: title ?? 'Add Node',
|
|
85
|
+
initialItems: nodeListOptions,
|
|
86
|
+
loading: loading,
|
|
87
|
+
onItemSelect: handleNodeListItemSelect,
|
|
88
|
+
onSearch: handleSearch,
|
|
89
|
+
onClose: onClose,
|
|
90
|
+
onItemHover: onNodeHover
|
|
91
|
+
})
|
|
79
92
|
});
|
|
80
93
|
});
|
|
81
94
|
exports.AddNodePanel = __webpack_exports__.AddNodePanel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddNodePanel.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/AddNodePanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AddNodePanel.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/AddNodePanel/AddNodePanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAU9D,eAAO,MAAM,YAAY,yDA6EvB,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useCallback, useMemo } from "react";
|
|
3
|
+
import react_focus_lock from "react-focus-lock";
|
|
3
4
|
import { useOptionalNodeTypeRegistry } from "../../core/index.js";
|
|
4
5
|
import { usePreviewNode } from "../../hooks/index.js";
|
|
5
6
|
import { Toolbox } from "../Toolbox/index.js";
|
|
@@ -40,14 +41,16 @@ const AddNodePanel_AddNodePanel = /*#__PURE__*/ memo(function({ onNodeSelect, on
|
|
|
40
41
|
}, [
|
|
41
42
|
onNodeSelect
|
|
42
43
|
]);
|
|
43
|
-
return /*#__PURE__*/ jsx(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
return /*#__PURE__*/ jsx(react_focus_lock, {
|
|
45
|
+
children: /*#__PURE__*/ jsx(Toolbox, {
|
|
46
|
+
title: title ?? 'Add Node',
|
|
47
|
+
initialItems: nodeListOptions,
|
|
48
|
+
loading: loading,
|
|
49
|
+
onItemSelect: handleNodeListItemSelect,
|
|
50
|
+
onSearch: handleSearch,
|
|
51
|
+
onClose: onClose,
|
|
52
|
+
onItemHover: onNodeHover
|
|
53
|
+
})
|
|
51
54
|
});
|
|
52
55
|
});
|
|
53
56
|
export { AddNodePanel_AddNodePanel as AddNodePanel };
|
|
@@ -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,16 @@ 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
|
+
id: `toolbox-item-${item.id}`,
|
|
111
|
+
role: "option",
|
|
112
|
+
"aria-selected": isActive,
|
|
79
113
|
style: buttonStyle,
|
|
80
114
|
onClick: handleButtonClick,
|
|
81
115
|
onHoverStart: handleButtonHover,
|
|
82
|
-
className: isLoading ? 'loading' : ''
|
|
116
|
+
className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
|
|
83
117
|
disabled: isLoading,
|
|
84
118
|
children: [
|
|
85
119
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(IconContainerMemoized, {
|
|
@@ -134,48 +168,22 @@ const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ in
|
|
|
134
168
|
]
|
|
135
169
|
});
|
|
136
170
|
});
|
|
137
|
-
const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(function({ items, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
|
|
171
|
+
const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(function({ items, activeIndex = -1, listRef, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
|
|
138
172
|
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
|
-
}, [
|
|
173
|
+
const renderedItems = (0, external_react_namespaceObject.useMemo)(()=>buildRenderedItems(items, enableSections), [
|
|
168
174
|
items,
|
|
169
175
|
enableSections
|
|
170
176
|
]);
|
|
171
177
|
const rowProps = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
172
178
|
renderedItems,
|
|
179
|
+
activeIndex,
|
|
173
180
|
isLoading,
|
|
174
181
|
isDarkMode,
|
|
175
182
|
onItemClick,
|
|
176
183
|
onItemHover
|
|
177
184
|
}), [
|
|
178
185
|
renderedItems,
|
|
186
|
+
activeIndex,
|
|
179
187
|
isLoading,
|
|
180
188
|
isDarkMode,
|
|
181
189
|
onItemClick,
|
|
@@ -215,6 +223,7 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
|
|
|
215
223
|
]
|
|
216
224
|
});
|
|
217
225
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_styles_cjs_namespaceObject.StyledList, {
|
|
226
|
+
listRef: listRef,
|
|
218
227
|
rowProps: rowProps,
|
|
219
228
|
rowComponent: ListViewRow,
|
|
220
229
|
rowCount: renderedItems.length,
|
|
@@ -223,8 +232,10 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
|
|
|
223
232
|
});
|
|
224
233
|
});
|
|
225
234
|
exports.ListView = __webpack_exports__.ListView;
|
|
235
|
+
exports.buildRenderedItems = __webpack_exports__.buildRenderedItems;
|
|
226
236
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
227
|
-
"ListView"
|
|
237
|
+
"ListView",
|
|
238
|
+
"buildRenderedItems"
|
|
228
239
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
229
240
|
Object.defineProperty(exports, '__esModule', {
|
|
230
241
|
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,15 +15,17 @@ 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;
|
|
@@ -30,6 +33,8 @@ export interface ListViewRowProps<T extends ListItem> {
|
|
|
30
33
|
}
|
|
31
34
|
interface ListViewProps<T extends ListItem> {
|
|
32
35
|
items: T[];
|
|
36
|
+
activeIndex?: number;
|
|
37
|
+
listRef?: React.RefObject<ListImperativeAPI | null>;
|
|
33
38
|
onItemClick: (item: T) => void;
|
|
34
39
|
onItemHover?: (item: T) => void;
|
|
35
40
|
emptyStateMessage?: string;
|
|
@@ -37,6 +42,6 @@ interface ListViewProps<T extends ListItem> {
|
|
|
37
42
|
isLoading?: boolean;
|
|
38
43
|
enableSections?: boolean;
|
|
39
44
|
}
|
|
40
|
-
export declare const ListView: import("react").MemoExoticComponent<(<T extends ListItem>({ items, onItemClick, onItemHover, emptyStateMessage, emptyStateIcon, isLoading, enableSections, }: ListViewProps<T>) => import("react/jsx-runtime").JSX.Element)>;
|
|
45
|
+
export declare const ListView: import("react").MemoExoticComponent<(<T extends ListItem>({ items, activeIndex, listRef, onItemClick, onItemHover, emptyStateMessage, emptyStateIcon, isLoading, enableSections, }: ListViewProps<T>) => import("react/jsx-runtime").JSX.Element)>;
|
|
41
46
|
export {};
|
|
42
47
|
//# 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;AA+GD,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;AAED,eAAO,MAAM,QAAQ,wCAA0B,CAAC,SAAS,QAAQ,4HAU9D,aAAa,CAAC,CAAC,CAAC,8CAiDjB,CAAC"}
|
|
@@ -7,8 +7,37 @@ import { ApIcon, ApTooltip } from "../../../material/components/index.js";
|
|
|
7
7
|
import { memo, useCallback, 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,16 @@ 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
|
+
id: `toolbox-item-${item.id}`,
|
|
82
|
+
role: "option",
|
|
83
|
+
"aria-selected": isActive,
|
|
51
84
|
style: buttonStyle,
|
|
52
85
|
onClick: handleButtonClick,
|
|
53
86
|
onHoverStart: handleButtonHover,
|
|
54
|
-
className: isLoading ? 'loading' : ''
|
|
87
|
+
className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
|
|
55
88
|
disabled: isLoading,
|
|
56
89
|
children: [
|
|
57
90
|
/*#__PURE__*/ jsxs(IconContainerMemoized, {
|
|
@@ -106,48 +139,22 @@ const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, rendered
|
|
|
106
139
|
]
|
|
107
140
|
});
|
|
108
141
|
});
|
|
109
|
-
const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
|
|
142
|
+
const ListView_ListView = /*#__PURE__*/ memo(function({ items, activeIndex = -1, listRef, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
|
|
110
143
|
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
|
-
}, [
|
|
144
|
+
const renderedItems = useMemo(()=>buildRenderedItems(items, enableSections), [
|
|
140
145
|
items,
|
|
141
146
|
enableSections
|
|
142
147
|
]);
|
|
143
148
|
const rowProps = useMemo(()=>({
|
|
144
149
|
renderedItems,
|
|
150
|
+
activeIndex,
|
|
145
151
|
isLoading,
|
|
146
152
|
isDarkMode,
|
|
147
153
|
onItemClick,
|
|
148
154
|
onItemHover
|
|
149
155
|
}), [
|
|
150
156
|
renderedItems,
|
|
157
|
+
activeIndex,
|
|
151
158
|
isLoading,
|
|
152
159
|
isDarkMode,
|
|
153
160
|
onItemClick,
|
|
@@ -187,6 +194,7 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
|
|
|
187
194
|
]
|
|
188
195
|
});
|
|
189
196
|
return /*#__PURE__*/ jsx(StyledList, {
|
|
197
|
+
listRef: listRef,
|
|
190
198
|
rowProps: rowProps,
|
|
191
199
|
rowComponent: ListViewRow,
|
|
192
200
|
rowCount: renderedItems.length,
|
|
@@ -194,4 +202,4 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
|
|
|
194
202
|
overscanCount: 20
|
|
195
203
|
});
|
|
196
204
|
});
|
|
197
|
-
export { ListView_ListView as ListView };
|
|
205
|
+
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 }) {
|
|
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",
|
|
@@ -59,7 +62,8 @@ const SearchBox_SearchBox = /*#__PURE__*/ (0, external_react_namespaceObject.mem
|
|
|
59
62
|
className: "searchbox-input",
|
|
60
63
|
placeholder: placeholder,
|
|
61
64
|
value: value,
|
|
62
|
-
onChange: (e)=>onChange(e.target.value)
|
|
65
|
+
onChange: (e)=>onChange(e.target.value),
|
|
66
|
+
onKeyDown: onNavigationKeyDown
|
|
63
67
|
}),
|
|
64
68
|
value && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
|
|
65
69
|
type: "button",
|
|
@@ -3,6 +3,8 @@ 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;
|
|
6
8
|
}
|
|
7
9
|
export declare const SearchBox: import("react").NamedExoticComponent<SearchBoxProps>;
|
|
8
10
|
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;CACxD;AAED,eAAO,MAAM,SAAS,sDA2CpB,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 }) {
|
|
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",
|
|
@@ -31,7 +34,8 @@ const SearchBox_SearchBox = /*#__PURE__*/ memo(function({ value, onChange, clear
|
|
|
31
34
|
className: "searchbox-input",
|
|
32
35
|
placeholder: placeholder,
|
|
33
36
|
value: value,
|
|
34
|
-
onChange: (e)=>onChange(e.target.value)
|
|
37
|
+
onChange: (e)=>onChange(e.target.value),
|
|
38
|
+
onKeyDown: onNavigationKeyDown
|
|
35
39
|
}),
|
|
36
40
|
value && /*#__PURE__*/ jsx("button", {
|
|
37
41
|
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");
|
|
@@ -71,13 +72,48 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
71
72
|
const [isTransitioning, setIsTransitioning] = (0, external_react_namespaceObject.useState)(false);
|
|
72
73
|
const [animationDirection, setAnimationDirection] = (0, external_react_namespaceObject.useState)('forward');
|
|
73
74
|
const navigationStack = (0, index_cjs_namespaceObject.useNavigationStack)();
|
|
75
|
+
const [activeIndex, setActiveIndex] = (0, external_react_namespaceObject.useState)(-1);
|
|
74
76
|
const containerRef = (0, external_react_namespaceObject.useRef)(null);
|
|
75
77
|
const transitionTimeoutRef = (0, external_react_namespaceObject.useRef)(void 0);
|
|
76
78
|
const searchIdRef = (0, external_react_namespaceObject.useRef)(0);
|
|
77
79
|
const initialItemsRef = (0, external_react_namespaceObject.useRef)(initialItems);
|
|
80
|
+
const listRef = (0, external_react_window_namespaceObject.useListRef)(null);
|
|
81
|
+
const searchInputRef = (0, external_react_namespaceObject.useRef)(null);
|
|
78
82
|
const isSearching = (0, external_react_namespaceObject.useMemo)(()=>search.length > 0, [
|
|
79
83
|
search
|
|
80
84
|
]);
|
|
85
|
+
const displayedItems = (0, external_react_namespaceObject.useMemo)(()=>isSearching && !isSearchingInitialItems ? searchedItems : items, [
|
|
86
|
+
isSearching,
|
|
87
|
+
isSearchingInitialItems,
|
|
88
|
+
searchedItems,
|
|
89
|
+
items
|
|
90
|
+
]);
|
|
91
|
+
const renderedItems = (0, external_react_namespaceObject.useMemo)(()=>(0, external_ListView_cjs_namespaceObject.buildRenderedItems)(displayedItems, !isSearching), [
|
|
92
|
+
displayedItems,
|
|
93
|
+
isSearching
|
|
94
|
+
]);
|
|
95
|
+
const getNextSelectableIndex = (0, external_react_namespaceObject.useCallback)((currentIndex, direction)=>{
|
|
96
|
+
let next = currentIndex + direction;
|
|
97
|
+
while(next >= 0 && next < renderedItems.length){
|
|
98
|
+
if (renderedItems[next]?.type === 'item') return next;
|
|
99
|
+
next += direction;
|
|
100
|
+
}
|
|
101
|
+
return -1;
|
|
102
|
+
}, [
|
|
103
|
+
renderedItems
|
|
104
|
+
]);
|
|
105
|
+
const getFirstSelectableIndex = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
106
|
+
for(let i = 0; i < renderedItems.length; i++)if (renderedItems[i]?.type === 'item') return i;
|
|
107
|
+
return -1;
|
|
108
|
+
}, [
|
|
109
|
+
renderedItems
|
|
110
|
+
]);
|
|
111
|
+
const getLastSelectableIndex = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
112
|
+
for(let i = renderedItems.length - 1; i >= 0; i--)if (renderedItems[i]?.type === 'item') return i;
|
|
113
|
+
return -1;
|
|
114
|
+
}, [
|
|
115
|
+
renderedItems
|
|
116
|
+
]);
|
|
81
117
|
const startTransition = (0, external_react_namespaceObject.useCallback)((direction)=>{
|
|
82
118
|
if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
|
|
83
119
|
setIsTransitioning(true);
|
|
@@ -86,11 +122,21 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
86
122
|
setIsTransitioning(false);
|
|
87
123
|
}, TRANSITION_DURATION);
|
|
88
124
|
}, []);
|
|
125
|
+
const navigateToIndex = (0, external_react_namespaceObject.useCallback)((index)=>{
|
|
126
|
+
setActiveIndex(index);
|
|
127
|
+
if (index >= 0) listRef.current?.scrollToRow({
|
|
128
|
+
index,
|
|
129
|
+
align: 'auto'
|
|
130
|
+
});
|
|
131
|
+
}, [
|
|
132
|
+
listRef
|
|
133
|
+
]);
|
|
89
134
|
const clearSearch = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
90
135
|
setSearch('');
|
|
91
136
|
setSearchedItems([]);
|
|
92
137
|
setSearchLoading(false);
|
|
93
138
|
setIsSearchingInitialItems(true);
|
|
139
|
+
setActiveIndex(-1);
|
|
94
140
|
}, []);
|
|
95
141
|
const handleSearch = (0, external_react_namespaceObject.useCallback)(async (query)=>{
|
|
96
142
|
if (!query.trim()) {
|
|
@@ -101,6 +147,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
101
147
|
return;
|
|
102
148
|
}
|
|
103
149
|
setSearch(query);
|
|
150
|
+
setActiveIndex(-1);
|
|
104
151
|
searchIdRef.current += 1;
|
|
105
152
|
const currentRequestId = searchIdRef.current;
|
|
106
153
|
setSearchLoading(true);
|
|
@@ -121,6 +168,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
121
168
|
]);
|
|
122
169
|
const handleBackTransition = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
123
170
|
startTransition('back');
|
|
171
|
+
setActiveIndex(-1);
|
|
124
172
|
const previousState = navigationStack.pop();
|
|
125
173
|
if (previousState) {
|
|
126
174
|
setItems(previousState.data.items);
|
|
@@ -149,6 +197,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
149
197
|
setItems(nestedItems);
|
|
150
198
|
setCurrentParentItem(item);
|
|
151
199
|
clearSearch();
|
|
200
|
+
setActiveIndex(-1);
|
|
152
201
|
startTransition('forward');
|
|
153
202
|
setChildrenLoading(false);
|
|
154
203
|
}, [
|
|
@@ -206,6 +255,87 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
206
255
|
}, [
|
|
207
256
|
items
|
|
208
257
|
]);
|
|
258
|
+
const activeDescendantId = (0, external_react_namespaceObject.useMemo)(()=>{
|
|
259
|
+
if (activeIndex < 0) return;
|
|
260
|
+
const renderItem = renderedItems[activeIndex];
|
|
261
|
+
if (renderItem?.type === 'item') return `toolbox-item-${renderItem.item.id}`;
|
|
262
|
+
}, [
|
|
263
|
+
activeIndex,
|
|
264
|
+
renderedItems
|
|
265
|
+
]);
|
|
266
|
+
const handleNavigationKeyDown = (0, external_react_namespaceObject.useCallback)((e)=>{
|
|
267
|
+
if (isTransitioning) return;
|
|
268
|
+
const input = searchInputRef.current;
|
|
269
|
+
const cursorAtStart = input ? 0 === input.selectionStart && 0 === input.selectionEnd : true;
|
|
270
|
+
const cursorAtEnd = input ? input.selectionStart === input.value.length && input.selectionEnd === input.value.length : true;
|
|
271
|
+
switch(e.key){
|
|
272
|
+
case 'ArrowDown':
|
|
273
|
+
e.preventDefault();
|
|
274
|
+
if (-1 === activeIndex) {
|
|
275
|
+
const firstIndex = getFirstSelectableIndex();
|
|
276
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
277
|
+
} else {
|
|
278
|
+
const nextIndex = getNextSelectableIndex(activeIndex, 1);
|
|
279
|
+
if (-1 !== nextIndex) navigateToIndex(nextIndex);
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
282
|
+
case 'ArrowUp':
|
|
283
|
+
e.preventDefault();
|
|
284
|
+
activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(activeIndex, -1));
|
|
285
|
+
break;
|
|
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 (!cursorAtEnd) break;
|
|
297
|
+
if (activeIndex >= 0) {
|
|
298
|
+
const renderItem = renderedItems[activeIndex];
|
|
299
|
+
if (renderItem?.type === 'item' && renderItem.item.children) {
|
|
300
|
+
e.preventDefault();
|
|
301
|
+
handleItemSelect(renderItem.item);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
break;
|
|
305
|
+
case 'ArrowLeft':
|
|
306
|
+
if (!cursorAtStart) break;
|
|
307
|
+
if (activeIndex >= 0 && navigationStack.canGoBack) {
|
|
308
|
+
e.preventDefault();
|
|
309
|
+
handleBackTransition();
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
312
|
+
case 'Home':
|
|
313
|
+
{
|
|
314
|
+
e.preventDefault();
|
|
315
|
+
const firstIndex = getFirstSelectableIndex();
|
|
316
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
case 'End':
|
|
320
|
+
{
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
const lastIndex = getLastSelectableIndex();
|
|
323
|
+
if (-1 !== lastIndex) navigateToIndex(lastIndex);
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}, [
|
|
328
|
+
isTransitioning,
|
|
329
|
+
activeIndex,
|
|
330
|
+
renderedItems,
|
|
331
|
+
navigationStack.canGoBack,
|
|
332
|
+
navigateToIndex,
|
|
333
|
+
handleItemSelect,
|
|
334
|
+
handleBackTransition,
|
|
335
|
+
getNextSelectableIndex,
|
|
336
|
+
getFirstSelectableIndex,
|
|
337
|
+
getLastSelectableIndex
|
|
338
|
+
]);
|
|
209
339
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
210
340
|
const handleKeyDown = (e)=>{
|
|
211
341
|
if ('Escape' === e.key) if (isSearching) {
|
|
@@ -235,6 +365,10 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
235
365
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
|
|
236
366
|
ref: containerRef,
|
|
237
367
|
"data-testid": "toolbox-container",
|
|
368
|
+
tabIndex: 0,
|
|
369
|
+
role: "application",
|
|
370
|
+
"aria-activedescendant": activeDescendantId,
|
|
371
|
+
"aria-label": currentParentItem?.name || title,
|
|
238
372
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_layouts_index_cjs_namespaceObject.Column, {
|
|
239
373
|
px: 20,
|
|
240
374
|
py: 12,
|
|
@@ -251,7 +385,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
251
385
|
value: search,
|
|
252
386
|
onChange: handleSearch,
|
|
253
387
|
clear: clearSearch,
|
|
254
|
-
placeholder: "Search"
|
|
388
|
+
placeholder: "Search",
|
|
389
|
+
inputRef: searchInputRef,
|
|
390
|
+
onNavigationKeyDown: handleNavigationKeyDown
|
|
255
391
|
}),
|
|
256
392
|
/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContainer, {
|
|
257
393
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContent, {
|
|
@@ -259,7 +395,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
259
395
|
direction: animationDirection,
|
|
260
396
|
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_cjs_namespaceObject.ListView, {
|
|
261
397
|
isLoading: childrenLoading || searchLoading || loading,
|
|
262
|
-
items:
|
|
398
|
+
items: displayedItems,
|
|
399
|
+
activeIndex: activeIndex,
|
|
400
|
+
listRef: listRef,
|
|
263
401
|
emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
|
|
264
402
|
enableSections: !isSearching,
|
|
265
403
|
onItemClick: handleItemSelect,
|
|
@@ -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,EAAsB,KAAK,QAAQ,EAAY,MAAM,YAAY,CAAC;AAuCzE,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;AAoBD,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,2CA2ajB"}
|
|
@@ -2,8 +2,9 @@ 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
|
-
import { ListView } from "./ListView.js";
|
|
7
|
+
import { ListView, buildRenderedItems } from "./ListView.js";
|
|
7
8
|
import { SearchBox } from "./SearchBox.js";
|
|
8
9
|
import { AnimatedContainer, AnimatedContent } from "./Toolbox.styles.js";
|
|
9
10
|
const TRANSITION_DURATION = 150;
|
|
@@ -43,13 +44,48 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
43
44
|
const [isTransitioning, setIsTransitioning] = useState(false);
|
|
44
45
|
const [animationDirection, setAnimationDirection] = useState('forward');
|
|
45
46
|
const navigationStack = useNavigationStack();
|
|
47
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
46
48
|
const containerRef = useRef(null);
|
|
47
49
|
const transitionTimeoutRef = useRef(void 0);
|
|
48
50
|
const searchIdRef = useRef(0);
|
|
49
51
|
const initialItemsRef = useRef(initialItems);
|
|
52
|
+
const listRef = useListRef(null);
|
|
53
|
+
const searchInputRef = useRef(null);
|
|
50
54
|
const isSearching = useMemo(()=>search.length > 0, [
|
|
51
55
|
search
|
|
52
56
|
]);
|
|
57
|
+
const displayedItems = useMemo(()=>isSearching && !isSearchingInitialItems ? searchedItems : items, [
|
|
58
|
+
isSearching,
|
|
59
|
+
isSearchingInitialItems,
|
|
60
|
+
searchedItems,
|
|
61
|
+
items
|
|
62
|
+
]);
|
|
63
|
+
const renderedItems = useMemo(()=>buildRenderedItems(displayedItems, !isSearching), [
|
|
64
|
+
displayedItems,
|
|
65
|
+
isSearching
|
|
66
|
+
]);
|
|
67
|
+
const getNextSelectableIndex = useCallback((currentIndex, direction)=>{
|
|
68
|
+
let next = currentIndex + direction;
|
|
69
|
+
while(next >= 0 && next < renderedItems.length){
|
|
70
|
+
if (renderedItems[next]?.type === 'item') return next;
|
|
71
|
+
next += direction;
|
|
72
|
+
}
|
|
73
|
+
return -1;
|
|
74
|
+
}, [
|
|
75
|
+
renderedItems
|
|
76
|
+
]);
|
|
77
|
+
const getFirstSelectableIndex = useCallback(()=>{
|
|
78
|
+
for(let i = 0; i < renderedItems.length; i++)if (renderedItems[i]?.type === 'item') return i;
|
|
79
|
+
return -1;
|
|
80
|
+
}, [
|
|
81
|
+
renderedItems
|
|
82
|
+
]);
|
|
83
|
+
const getLastSelectableIndex = useCallback(()=>{
|
|
84
|
+
for(let i = renderedItems.length - 1; i >= 0; i--)if (renderedItems[i]?.type === 'item') return i;
|
|
85
|
+
return -1;
|
|
86
|
+
}, [
|
|
87
|
+
renderedItems
|
|
88
|
+
]);
|
|
53
89
|
const startTransition = useCallback((direction)=>{
|
|
54
90
|
if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
|
|
55
91
|
setIsTransitioning(true);
|
|
@@ -58,11 +94,21 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
58
94
|
setIsTransitioning(false);
|
|
59
95
|
}, TRANSITION_DURATION);
|
|
60
96
|
}, []);
|
|
97
|
+
const navigateToIndex = useCallback((index)=>{
|
|
98
|
+
setActiveIndex(index);
|
|
99
|
+
if (index >= 0) listRef.current?.scrollToRow({
|
|
100
|
+
index,
|
|
101
|
+
align: 'auto'
|
|
102
|
+
});
|
|
103
|
+
}, [
|
|
104
|
+
listRef
|
|
105
|
+
]);
|
|
61
106
|
const clearSearch = useCallback(()=>{
|
|
62
107
|
setSearch('');
|
|
63
108
|
setSearchedItems([]);
|
|
64
109
|
setSearchLoading(false);
|
|
65
110
|
setIsSearchingInitialItems(true);
|
|
111
|
+
setActiveIndex(-1);
|
|
66
112
|
}, []);
|
|
67
113
|
const handleSearch = useCallback(async (query)=>{
|
|
68
114
|
if (!query.trim()) {
|
|
@@ -73,6 +119,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
73
119
|
return;
|
|
74
120
|
}
|
|
75
121
|
setSearch(query);
|
|
122
|
+
setActiveIndex(-1);
|
|
76
123
|
searchIdRef.current += 1;
|
|
77
124
|
const currentRequestId = searchIdRef.current;
|
|
78
125
|
setSearchLoading(true);
|
|
@@ -93,6 +140,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
93
140
|
]);
|
|
94
141
|
const handleBackTransition = useCallback(()=>{
|
|
95
142
|
startTransition('back');
|
|
143
|
+
setActiveIndex(-1);
|
|
96
144
|
const previousState = navigationStack.pop();
|
|
97
145
|
if (previousState) {
|
|
98
146
|
setItems(previousState.data.items);
|
|
@@ -121,6 +169,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
121
169
|
setItems(nestedItems);
|
|
122
170
|
setCurrentParentItem(item);
|
|
123
171
|
clearSearch();
|
|
172
|
+
setActiveIndex(-1);
|
|
124
173
|
startTransition('forward');
|
|
125
174
|
setChildrenLoading(false);
|
|
126
175
|
}, [
|
|
@@ -178,6 +227,87 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
178
227
|
}, [
|
|
179
228
|
items
|
|
180
229
|
]);
|
|
230
|
+
const activeDescendantId = useMemo(()=>{
|
|
231
|
+
if (activeIndex < 0) return;
|
|
232
|
+
const renderItem = renderedItems[activeIndex];
|
|
233
|
+
if (renderItem?.type === 'item') return `toolbox-item-${renderItem.item.id}`;
|
|
234
|
+
}, [
|
|
235
|
+
activeIndex,
|
|
236
|
+
renderedItems
|
|
237
|
+
]);
|
|
238
|
+
const handleNavigationKeyDown = useCallback((e)=>{
|
|
239
|
+
if (isTransitioning) return;
|
|
240
|
+
const input = searchInputRef.current;
|
|
241
|
+
const cursorAtStart = input ? 0 === input.selectionStart && 0 === input.selectionEnd : true;
|
|
242
|
+
const cursorAtEnd = input ? input.selectionStart === input.value.length && input.selectionEnd === input.value.length : true;
|
|
243
|
+
switch(e.key){
|
|
244
|
+
case 'ArrowDown':
|
|
245
|
+
e.preventDefault();
|
|
246
|
+
if (-1 === activeIndex) {
|
|
247
|
+
const firstIndex = getFirstSelectableIndex();
|
|
248
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
249
|
+
} else {
|
|
250
|
+
const nextIndex = getNextSelectableIndex(activeIndex, 1);
|
|
251
|
+
if (-1 !== nextIndex) navigateToIndex(nextIndex);
|
|
252
|
+
}
|
|
253
|
+
break;
|
|
254
|
+
case 'ArrowUp':
|
|
255
|
+
e.preventDefault();
|
|
256
|
+
activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(activeIndex, -1));
|
|
257
|
+
break;
|
|
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 (!cursorAtEnd) break;
|
|
269
|
+
if (activeIndex >= 0) {
|
|
270
|
+
const renderItem = renderedItems[activeIndex];
|
|
271
|
+
if (renderItem?.type === 'item' && renderItem.item.children) {
|
|
272
|
+
e.preventDefault();
|
|
273
|
+
handleItemSelect(renderItem.item);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
case 'ArrowLeft':
|
|
278
|
+
if (!cursorAtStart) break;
|
|
279
|
+
if (activeIndex >= 0 && navigationStack.canGoBack) {
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
handleBackTransition();
|
|
282
|
+
}
|
|
283
|
+
break;
|
|
284
|
+
case 'Home':
|
|
285
|
+
{
|
|
286
|
+
e.preventDefault();
|
|
287
|
+
const firstIndex = getFirstSelectableIndex();
|
|
288
|
+
if (-1 !== firstIndex) navigateToIndex(firstIndex);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
case 'End':
|
|
292
|
+
{
|
|
293
|
+
e.preventDefault();
|
|
294
|
+
const lastIndex = getLastSelectableIndex();
|
|
295
|
+
if (-1 !== lastIndex) navigateToIndex(lastIndex);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}, [
|
|
300
|
+
isTransitioning,
|
|
301
|
+
activeIndex,
|
|
302
|
+
renderedItems,
|
|
303
|
+
navigationStack.canGoBack,
|
|
304
|
+
navigateToIndex,
|
|
305
|
+
handleItemSelect,
|
|
306
|
+
handleBackTransition,
|
|
307
|
+
getNextSelectableIndex,
|
|
308
|
+
getFirstSelectableIndex,
|
|
309
|
+
getLastSelectableIndex
|
|
310
|
+
]);
|
|
181
311
|
useEffect(()=>{
|
|
182
312
|
const handleKeyDown = (e)=>{
|
|
183
313
|
if ('Escape' === e.key) if (isSearching) {
|
|
@@ -207,6 +337,10 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
207
337
|
return /*#__PURE__*/ jsx("div", {
|
|
208
338
|
ref: containerRef,
|
|
209
339
|
"data-testid": "toolbox-container",
|
|
340
|
+
tabIndex: 0,
|
|
341
|
+
role: "application",
|
|
342
|
+
"aria-activedescendant": activeDescendantId,
|
|
343
|
+
"aria-label": currentParentItem?.name || title,
|
|
210
344
|
children: /*#__PURE__*/ jsxs(Column, {
|
|
211
345
|
px: 20,
|
|
212
346
|
py: 12,
|
|
@@ -223,7 +357,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
223
357
|
value: search,
|
|
224
358
|
onChange: handleSearch,
|
|
225
359
|
clear: clearSearch,
|
|
226
|
-
placeholder: "Search"
|
|
360
|
+
placeholder: "Search",
|
|
361
|
+
inputRef: searchInputRef,
|
|
362
|
+
onNavigationKeyDown: handleNavigationKeyDown
|
|
227
363
|
}),
|
|
228
364
|
/*#__PURE__*/ jsx(AnimatedContainer, {
|
|
229
365
|
children: /*#__PURE__*/ jsx(AnimatedContent, {
|
|
@@ -231,7 +367,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
|
|
|
231
367
|
direction: animationDirection,
|
|
232
368
|
children: /*#__PURE__*/ jsx(ListView, {
|
|
233
369
|
isLoading: childrenLoading || searchLoading || loading,
|
|
234
|
-
items:
|
|
370
|
+
items: displayedItems,
|
|
371
|
+
activeIndex: activeIndex,
|
|
372
|
+
listRef: listRef,
|
|
235
373
|
emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
|
|
236
374
|
enableSections: !isSearching,
|
|
237
375
|
onItemClick: handleItemSelect,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uipath/apollo-react",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.54.0-pr354.029fc6a",
|
|
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",
|