@uipath/apollo-react 3.53.0-pr349.8a75b3d → 3.54.0-pr354.17cbb75

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.
@@ -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)(external_Toolbox_index_cjs_namespaceObject.Toolbox, {
72
- title: title ?? 'Add Node',
73
- initialItems: nodeListOptions,
74
- loading: loading,
75
- onItemSelect: handleNodeListItemSelect,
76
- onSearch: handleSearch,
77
- onClose: onClose,
78
- onItemHover: onNodeHover
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":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAU9D,eAAO,MAAM,YAAY,yDA2EvB,CAAC"}
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(Toolbox, {
44
- title: title ?? 'Add Node',
45
- initialItems: nodeListOptions,
46
- loading: loading,
47
- onItemSelect: handleNodeListItemSelect,
48
- onSearch: handleSearch,
49
- onClose: onClose,
50
- onItemHover: onNodeHover
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,9 @@ 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,
227
+ id: "toolbox-listbox",
228
+ role: "listbox",
218
229
  rowProps: rowProps,
219
230
  rowComponent: ListViewRow,
220
231
  rowCount: renderedItems.length,
@@ -223,8 +234,10 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
223
234
  });
224
235
  });
225
236
  exports.ListView = __webpack_exports__.ListView;
237
+ exports.buildRenderedItems = __webpack_exports__.buildRenderedItems;
226
238
  for(var __rspack_i in __webpack_exports__)if (-1 === [
227
- "ListView"
239
+ "ListView",
240
+ "buildRenderedItems"
228
241
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
229
242
  Object.defineProperty(exports, '__esModule', {
230
243
  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":"AAUA,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,KAAK,UAAU,CAAC,CAAC,SAAS,QAAQ,IAC9B;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,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,QAAQ;IAClD,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,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;AAyGD,UAAU,aAAa,CAAC,CAAC,SAAS,QAAQ;IACxC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,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,sGAQ9D,aAAa,CAAC,CAAC,CAAC,8CAkFjB,CAAC"}
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,8CAmDjB,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,9 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
187
194
  ]
188
195
  });
189
196
  return /*#__PURE__*/ jsx(StyledList, {
197
+ listRef: listRef,
198
+ id: "toolbox-listbox",
199
+ role: "listbox",
190
200
  rowProps: rowProps,
191
201
  rowComponent: ListViewRow,
192
202
  rowCount: renderedItems.length,
@@ -194,4 +204,4 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
194
204
  overscanCount: 20
195
205
  });
196
206
  });
197
- export { ListView_ListView as ListView };
207
+ 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-border);
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;;UAe1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;cAA0B,MAAM;yGAazD,CAAC;AAEF,eAAO,MAAM,UAAU,EAkClB,OAAO,IAAI,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-border);
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 inputRef = (0, external_react_namespaceObject.useRef)(null);
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-expanded": true,
64
+ "aria-controls": "toolbox-listbox",
65
+ "aria-activedescendant": activeDescendantId,
59
66
  className: "searchbox-input",
60
67
  placeholder: placeholder,
61
68
  value: value,
62
- onChange: (e)=>onChange(e.target.value)
69
+ onChange: (e)=>onChange(e.target.value),
70
+ onKeyDown: onNavigationKeyDown
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;CACtB;AAED,eAAO,MAAM,SAAS,sDAuCpB,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 inputRef = useRef(null);
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-expanded": true,
36
+ "aria-controls": "toolbox-listbox",
37
+ "aria-activedescendant": activeDescendantId,
31
38
  className: "searchbox-input",
32
39
  placeholder: placeholder,
33
40
  value: value,
34
- onChange: (e)=>onChange(e.target.value)
41
+ onChange: (e)=>onChange(e.target.value),
42
+ onKeyDown: onNavigationKeyDown
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");
@@ -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,65 @@ 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
+ switch(e.key){
269
+ case 'ArrowDown':
270
+ e.preventDefault();
271
+ if (-1 === activeIndex) {
272
+ const firstIndex = getFirstSelectableIndex();
273
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
274
+ } else {
275
+ const nextIndex = getNextSelectableIndex(activeIndex, 1);
276
+ if (-1 !== nextIndex) navigateToIndex(nextIndex);
277
+ }
278
+ break;
279
+ case 'ArrowUp':
280
+ e.preventDefault();
281
+ activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(activeIndex, -1));
282
+ break;
283
+ case 'Enter':
284
+ if (activeIndex >= 0) {
285
+ const renderItem = renderedItems[activeIndex];
286
+ if (renderItem?.type === 'item') {
287
+ e.preventDefault();
288
+ handleItemSelect(renderItem.item);
289
+ }
290
+ }
291
+ break;
292
+ case 'Home':
293
+ {
294
+ e.preventDefault();
295
+ const firstIndex = getFirstSelectableIndex();
296
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
297
+ break;
298
+ }
299
+ case 'End':
300
+ {
301
+ e.preventDefault();
302
+ const lastIndex = getLastSelectableIndex();
303
+ if (-1 !== lastIndex) navigateToIndex(lastIndex);
304
+ break;
305
+ }
306
+ }
307
+ }, [
308
+ isTransitioning,
309
+ activeIndex,
310
+ renderedItems,
311
+ navigateToIndex,
312
+ handleItemSelect,
313
+ getNextSelectableIndex,
314
+ getFirstSelectableIndex,
315
+ getLastSelectableIndex
316
+ ]);
209
317
  (0, external_react_namespaceObject.useEffect)(()=>{
210
318
  const handleKeyDown = (e)=>{
211
319
  if ('Escape' === e.key) if (isSearching) {
@@ -251,7 +359,10 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
251
359
  value: search,
252
360
  onChange: handleSearch,
253
361
  clear: clearSearch,
254
- placeholder: "Search"
362
+ placeholder: "Search",
363
+ inputRef: searchInputRef,
364
+ onNavigationKeyDown: handleNavigationKeyDown,
365
+ activeDescendantId: activeDescendantId
255
366
  }),
256
367
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContainer, {
257
368
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContent, {
@@ -259,7 +370,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
259
370
  direction: animationDirection,
260
371
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_cjs_namespaceObject.ListView, {
261
372
  isLoading: childrenLoading || searchLoading || loading,
262
- items: isSearching && !isSearchingInitialItems ? searchedItems : items,
373
+ items: displayedItems,
374
+ activeIndex: activeIndex,
375
+ listRef: listRef,
263
376
  emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
264
377
  enableSections: !isSearching,
265
378
  onItemClick: handleItemSelect,
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbox.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/Toolbox/Toolbox.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,YAAY,CAAC;AAuCrD,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,2CAoQjB"}
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,2CAwYjB"}
@@ -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,65 @@ 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
+ switch(e.key){
241
+ case 'ArrowDown':
242
+ e.preventDefault();
243
+ if (-1 === activeIndex) {
244
+ const firstIndex = getFirstSelectableIndex();
245
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
246
+ } else {
247
+ const nextIndex = getNextSelectableIndex(activeIndex, 1);
248
+ if (-1 !== nextIndex) navigateToIndex(nextIndex);
249
+ }
250
+ break;
251
+ case 'ArrowUp':
252
+ e.preventDefault();
253
+ activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1) ? navigateToIndex(-1) : navigateToIndex(getNextSelectableIndex(activeIndex, -1));
254
+ break;
255
+ case 'Enter':
256
+ if (activeIndex >= 0) {
257
+ const renderItem = renderedItems[activeIndex];
258
+ if (renderItem?.type === 'item') {
259
+ e.preventDefault();
260
+ handleItemSelect(renderItem.item);
261
+ }
262
+ }
263
+ break;
264
+ case 'Home':
265
+ {
266
+ e.preventDefault();
267
+ const firstIndex = getFirstSelectableIndex();
268
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
269
+ break;
270
+ }
271
+ case 'End':
272
+ {
273
+ e.preventDefault();
274
+ const lastIndex = getLastSelectableIndex();
275
+ if (-1 !== lastIndex) navigateToIndex(lastIndex);
276
+ break;
277
+ }
278
+ }
279
+ }, [
280
+ isTransitioning,
281
+ activeIndex,
282
+ renderedItems,
283
+ navigateToIndex,
284
+ handleItemSelect,
285
+ getNextSelectableIndex,
286
+ getFirstSelectableIndex,
287
+ getLastSelectableIndex
288
+ ]);
181
289
  useEffect(()=>{
182
290
  const handleKeyDown = (e)=>{
183
291
  if ('Escape' === e.key) if (isSearching) {
@@ -223,7 +331,10 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
223
331
  value: search,
224
332
  onChange: handleSearch,
225
333
  clear: clearSearch,
226
- placeholder: "Search"
334
+ placeholder: "Search",
335
+ inputRef: searchInputRef,
336
+ onNavigationKeyDown: handleNavigationKeyDown,
337
+ activeDescendantId: activeDescendantId
227
338
  }),
228
339
  /*#__PURE__*/ jsx(AnimatedContainer, {
229
340
  children: /*#__PURE__*/ jsx(AnimatedContent, {
@@ -231,7 +342,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
231
342
  direction: animationDirection,
232
343
  children: /*#__PURE__*/ jsx(ListView, {
233
344
  isLoading: childrenLoading || searchLoading || loading,
234
- items: isSearching && !isSearchingInitialItems ? searchedItems : items,
345
+ items: displayedItems,
346
+ activeIndex: activeIndex,
347
+ listRef: listRef,
235
348
  emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
236
349
  enableSections: !isSearching,
237
350
  onItemClick: handleItemSelect,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/apollo-react",
3
- "version": "3.53.0-pr349.8a75b3d",
3
+ "version": "3.54.0-pr354.17cbb75",
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.14.0"
204
+ "@uipath/apollo-wind": "0.15.0"
205
205
  },
206
206
  "devDependencies": {
207
207
  "@lingui/cli": "^5.6.1",