@uipath/apollo-react 3.53.0-pr349.8a75b3d → 3.54.0-pr354.9b2638b

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,14 @@ 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,
79
110
  style: buttonStyle,
80
111
  onClick: handleButtonClick,
81
112
  onHoverStart: handleButtonHover,
82
- className: isLoading ? 'loading' : '',
113
+ className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
114
+ "data-active": isActive || void 0,
83
115
  disabled: isLoading,
84
116
  children: [
85
117
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(IconContainerMemoized, {
@@ -134,48 +166,22 @@ const ListViewRow = /*#__PURE__*/ (0, external_react_namespaceObject.memo)(({ in
134
166
  ]
135
167
  });
136
168
  });
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 }) {
169
+ 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
170
  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
- }, [
171
+ const renderedItems = (0, external_react_namespaceObject.useMemo)(()=>buildRenderedItems(items, enableSections), [
168
172
  items,
169
173
  enableSections
170
174
  ]);
171
175
  const rowProps = (0, external_react_namespaceObject.useMemo)(()=>({
172
176
  renderedItems,
177
+ activeIndex,
173
178
  isLoading,
174
179
  isDarkMode,
175
180
  onItemClick,
176
181
  onItemHover
177
182
  }), [
178
183
  renderedItems,
184
+ activeIndex,
179
185
  isLoading,
180
186
  isDarkMode,
181
187
  onItemClick,
@@ -215,6 +221,7 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
215
221
  ]
216
222
  });
217
223
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_styles_cjs_namespaceObject.StyledList, {
224
+ listRef: listRef,
218
225
  rowProps: rowProps,
219
226
  rowComponent: ListViewRow,
220
227
  rowCount: renderedItems.length,
@@ -223,8 +230,10 @@ const ListView_ListView = /*#__PURE__*/ (0, external_react_namespaceObject.memo)
223
230
  });
224
231
  });
225
232
  exports.ListView = __webpack_exports__.ListView;
233
+ exports.buildRenderedItems = __webpack_exports__.buildRenderedItems;
226
234
  for(var __rspack_i in __webpack_exports__)if (-1 === [
227
- "ListView"
235
+ "ListView",
236
+ "buildRenderedItems"
228
237
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
229
238
  Object.defineProperty(exports, '__esModule', {
230
239
  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,CAiCjB;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;AA6GD,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,14 @@ 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,
51
81
  style: buttonStyle,
52
82
  onClick: handleButtonClick,
53
83
  onHoverStart: handleButtonHover,
54
- className: isLoading ? 'loading' : '',
84
+ className: `${isLoading ? 'loading' : ''} ${isActive ? 'active' : ''}`,
85
+ "data-active": isActive || void 0,
55
86
  disabled: isLoading,
56
87
  children: [
57
88
  /*#__PURE__*/ jsxs(IconContainerMemoized, {
@@ -106,48 +137,22 @@ const ListViewRow = /*#__PURE__*/ memo(({ index, style, ariaAttributes, rendered
106
137
  ]
107
138
  });
108
139
  });
109
- const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
140
+ const ListView_ListView = /*#__PURE__*/ memo(function({ items, activeIndex = -1, listRef, onItemClick, onItemHover, emptyStateMessage = 'No items found', emptyStateIcon = 'search_off', isLoading = false, enableSections = true }) {
110
141
  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
- }, [
142
+ const renderedItems = useMemo(()=>buildRenderedItems(items, enableSections), [
140
143
  items,
141
144
  enableSections
142
145
  ]);
143
146
  const rowProps = useMemo(()=>({
144
147
  renderedItems,
148
+ activeIndex,
145
149
  isLoading,
146
150
  isDarkMode,
147
151
  onItemClick,
148
152
  onItemHover
149
153
  }), [
150
154
  renderedItems,
155
+ activeIndex,
151
156
  isLoading,
152
157
  isDarkMode,
153
158
  onItemClick,
@@ -187,6 +192,7 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
187
192
  ]
188
193
  });
189
194
  return /*#__PURE__*/ jsx(StyledList, {
195
+ listRef: listRef,
190
196
  rowProps: rowProps,
191
197
  rowComponent: ListViewRow,
192
198
  rowCount: renderedItems.length,
@@ -194,4 +200,4 @@ const ListView_ListView = /*#__PURE__*/ memo(function({ items, onItemClick, onIt
194
200
  overscanCount: 20
195
201
  });
196
202
  });
197
- export { ListView_ListView as ListView };
203
+ 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,22 @@ 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, onArrowDown }) {
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
+ ]);
42
+ const handleKeyDown = (0, external_react_namespaceObject.useCallback)((e)=>{
43
+ if ('ArrowDown' === e.key) {
44
+ e.preventDefault();
45
+ onArrowDown?.();
46
+ }
47
+ }, [
48
+ onArrowDown
49
+ ]);
39
50
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_SearchBox_styles_cjs_namespaceObject.StyledSearchForm, {
40
51
  autoComplete: "off",
41
52
  className: "searchbox-form",
@@ -59,7 +70,8 @@ const SearchBox_SearchBox = /*#__PURE__*/ (0, external_react_namespaceObject.mem
59
70
  className: "searchbox-input",
60
71
  placeholder: placeholder,
61
72
  value: value,
62
- onChange: (e)=>onChange(e.target.value)
73
+ onChange: (e)=>onChange(e.target.value),
74
+ onKeyDown: handleKeyDown
63
75
  }),
64
76
  value && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
65
77
  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
+ onArrowDown?: () => 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;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,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,eAAO,MAAM,SAAS,sDAqDpB,CAAC"}
@@ -1,13 +1,24 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cx } from "../../utils/index.js";
3
3
  import { ApIcon } from "../../../material/components/index.js";
4
- import { memo, useEffect, useRef } from "react";
4
+ import { memo, useCallback, 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, onArrowDown }) {
7
+ const internalRef = useRef(null);
8
+ const inputRef = externalInputRef ?? internalRef;
8
9
  useEffect(()=>{
9
10
  inputRef.current?.focus();
10
- }, []);
11
+ }, [
12
+ inputRef
13
+ ]);
14
+ const handleKeyDown = useCallback((e)=>{
15
+ if ('ArrowDown' === e.key) {
16
+ e.preventDefault();
17
+ onArrowDown?.();
18
+ }
19
+ }, [
20
+ onArrowDown
21
+ ]);
11
22
  return /*#__PURE__*/ jsx(StyledSearchForm, {
12
23
  autoComplete: "off",
13
24
  className: "searchbox-form",
@@ -31,7 +42,8 @@ const SearchBox_SearchBox = /*#__PURE__*/ memo(function({ value, onChange, clear
31
42
  className: "searchbox-input",
32
43
  placeholder: placeholder,
33
44
  value: value,
34
- onChange: (e)=>onChange(e.target.value)
45
+ onChange: (e)=>onChange(e.target.value),
46
+ onKeyDown: handleKeyDown
35
47
  }),
36
48
  value && /*#__PURE__*/ jsx("button", {
37
49
  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,22 @@ 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 (-1 === index) setTimeout(()=>searchInputRef.current?.focus(), 0);
128
+ else listRef.current?.scrollToRow({
129
+ index,
130
+ align: 'auto'
131
+ });
132
+ }, [
133
+ listRef
134
+ ]);
89
135
  const clearSearch = (0, external_react_namespaceObject.useCallback)(()=>{
90
136
  setSearch('');
91
137
  setSearchedItems([]);
92
138
  setSearchLoading(false);
93
139
  setIsSearchingInitialItems(true);
140
+ setActiveIndex(-1);
94
141
  }, []);
95
142
  const handleSearch = (0, external_react_namespaceObject.useCallback)(async (query)=>{
96
143
  if (!query.trim()) {
@@ -101,6 +148,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
101
148
  return;
102
149
  }
103
150
  setSearch(query);
151
+ setActiveIndex(-1);
104
152
  searchIdRef.current += 1;
105
153
  const currentRequestId = searchIdRef.current;
106
154
  setSearchLoading(true);
@@ -121,6 +169,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
121
169
  ]);
122
170
  const handleBackTransition = (0, external_react_namespaceObject.useCallback)(()=>{
123
171
  startTransition('back');
172
+ setActiveIndex(-1);
124
173
  const previousState = navigationStack.pop();
125
174
  if (previousState) {
126
175
  setItems(previousState.data.items);
@@ -149,6 +198,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
149
198
  setItems(nestedItems);
150
199
  setCurrentParentItem(item);
151
200
  clearSearch();
201
+ setActiveIndex(-1);
152
202
  startTransition('forward');
153
203
  setChildrenLoading(false);
154
204
  }, [
@@ -206,14 +256,70 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
206
256
  }, [
207
257
  items
208
258
  ]);
259
+ const handleSearchArrowDown = (0, external_react_namespaceObject.useCallback)(()=>{
260
+ if (isTransitioning || 0 === renderedItems.length) return;
261
+ const firstIndex = getFirstSelectableIndex();
262
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
263
+ }, [
264
+ isTransitioning,
265
+ renderedItems.length,
266
+ getFirstSelectableIndex,
267
+ navigateToIndex
268
+ ]);
209
269
  (0, external_react_namespaceObject.useEffect)(()=>{
210
270
  const handleKeyDown = (e)=>{
211
- if ('Escape' === e.key) if (isSearching) {
212
- searchIdRef.current += 1;
213
- startTransition('back');
214
- clearSearch();
215
- } else if (navigationStack.canGoBack) handleBackTransition();
216
- else onClose();
271
+ if ('Escape' === e.key) {
272
+ if (isSearching) {
273
+ searchIdRef.current += 1;
274
+ startTransition('back');
275
+ clearSearch();
276
+ } else if (navigationStack.canGoBack) handleBackTransition();
277
+ else onClose();
278
+ return;
279
+ }
280
+ if (isTransitioning) return;
281
+ const isSearchFocused = document.activeElement === searchInputRef.current;
282
+ if (isSearchFocused) return;
283
+ switch(e.key){
284
+ case 'ArrowDown':
285
+ {
286
+ e.preventDefault();
287
+ const nextIndex = getNextSelectableIndex(activeIndex, 1);
288
+ if (-1 !== nextIndex) navigateToIndex(nextIndex);
289
+ break;
290
+ }
291
+ case 'ArrowUp':
292
+ e.preventDefault();
293
+ if (activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1)) navigateToIndex(-1);
294
+ else {
295
+ const prevIndex = getNextSelectableIndex(activeIndex, -1);
296
+ navigateToIndex(prevIndex);
297
+ }
298
+ break;
299
+ case 'Enter':
300
+ if (activeIndex >= 0) {
301
+ const renderItem = renderedItems[activeIndex];
302
+ if (renderItem?.type === 'item') {
303
+ e.preventDefault();
304
+ handleItemSelect(renderItem.item);
305
+ }
306
+ }
307
+ break;
308
+ case 'Home':
309
+ {
310
+ e.preventDefault();
311
+ const firstIndex = getFirstSelectableIndex();
312
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
313
+ break;
314
+ }
315
+ case 'End':
316
+ {
317
+ e.preventDefault();
318
+ const lastIndex = getLastSelectableIndex();
319
+ if (-1 !== lastIndex) navigateToIndex(lastIndex);
320
+ break;
321
+ }
322
+ }
217
323
  };
218
324
  const handleClickOutside = (e)=>{
219
325
  if (containerRef.current && !containerRef.current.contains(e.target)) onClose();
@@ -226,11 +332,19 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
226
332
  };
227
333
  }, [
228
334
  isSearching,
335
+ isTransitioning,
336
+ activeIndex,
337
+ renderedItems,
229
338
  navigationStack.canGoBack,
230
339
  onClose,
231
340
  clearSearch,
232
341
  startTransition,
233
- handleBackTransition
342
+ handleBackTransition,
343
+ handleItemSelect,
344
+ navigateToIndex,
345
+ getNextSelectableIndex,
346
+ getFirstSelectableIndex,
347
+ getLastSelectableIndex
234
348
  ]);
235
349
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
236
350
  ref: containerRef,
@@ -251,7 +365,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
251
365
  value: search,
252
366
  onChange: handleSearch,
253
367
  clear: clearSearch,
254
- placeholder: "Search"
368
+ placeholder: "Search",
369
+ inputRef: searchInputRef,
370
+ onArrowDown: handleSearchArrowDown
255
371
  }),
256
372
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContainer, {
257
373
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContent, {
@@ -259,7 +375,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
259
375
  direction: animationDirection,
260
376
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_cjs_namespaceObject.ListView, {
261
377
  isLoading: childrenLoading || searchLoading || loading,
262
- items: isSearching && !isSearchingInitialItems ? searchedItems : items,
378
+ items: displayedItems,
379
+ activeIndex: activeIndex,
380
+ listRef: listRef,
263
381
  emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
264
382
  enableSections: !isSearching,
265
383
  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,2CA0YjB"}
@@ -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,22 @@ 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 (-1 === index) setTimeout(()=>searchInputRef.current?.focus(), 0);
100
+ else listRef.current?.scrollToRow({
101
+ index,
102
+ align: 'auto'
103
+ });
104
+ }, [
105
+ listRef
106
+ ]);
61
107
  const clearSearch = useCallback(()=>{
62
108
  setSearch('');
63
109
  setSearchedItems([]);
64
110
  setSearchLoading(false);
65
111
  setIsSearchingInitialItems(true);
112
+ setActiveIndex(-1);
66
113
  }, []);
67
114
  const handleSearch = useCallback(async (query)=>{
68
115
  if (!query.trim()) {
@@ -73,6 +120,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
73
120
  return;
74
121
  }
75
122
  setSearch(query);
123
+ setActiveIndex(-1);
76
124
  searchIdRef.current += 1;
77
125
  const currentRequestId = searchIdRef.current;
78
126
  setSearchLoading(true);
@@ -93,6 +141,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
93
141
  ]);
94
142
  const handleBackTransition = useCallback(()=>{
95
143
  startTransition('back');
144
+ setActiveIndex(-1);
96
145
  const previousState = navigationStack.pop();
97
146
  if (previousState) {
98
147
  setItems(previousState.data.items);
@@ -121,6 +170,7 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
121
170
  setItems(nestedItems);
122
171
  setCurrentParentItem(item);
123
172
  clearSearch();
173
+ setActiveIndex(-1);
124
174
  startTransition('forward');
125
175
  setChildrenLoading(false);
126
176
  }, [
@@ -178,14 +228,70 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
178
228
  }, [
179
229
  items
180
230
  ]);
231
+ const handleSearchArrowDown = useCallback(()=>{
232
+ if (isTransitioning || 0 === renderedItems.length) return;
233
+ const firstIndex = getFirstSelectableIndex();
234
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
235
+ }, [
236
+ isTransitioning,
237
+ renderedItems.length,
238
+ getFirstSelectableIndex,
239
+ navigateToIndex
240
+ ]);
181
241
  useEffect(()=>{
182
242
  const handleKeyDown = (e)=>{
183
- if ('Escape' === e.key) if (isSearching) {
184
- searchIdRef.current += 1;
185
- startTransition('back');
186
- clearSearch();
187
- } else if (navigationStack.canGoBack) handleBackTransition();
188
- else onClose();
243
+ if ('Escape' === e.key) {
244
+ if (isSearching) {
245
+ searchIdRef.current += 1;
246
+ startTransition('back');
247
+ clearSearch();
248
+ } else if (navigationStack.canGoBack) handleBackTransition();
249
+ else onClose();
250
+ return;
251
+ }
252
+ if (isTransitioning) return;
253
+ const isSearchFocused = document.activeElement === searchInputRef.current;
254
+ if (isSearchFocused) return;
255
+ switch(e.key){
256
+ case 'ArrowDown':
257
+ {
258
+ e.preventDefault();
259
+ const nextIndex = getNextSelectableIndex(activeIndex, 1);
260
+ if (-1 !== nextIndex) navigateToIndex(nextIndex);
261
+ break;
262
+ }
263
+ case 'ArrowUp':
264
+ e.preventDefault();
265
+ if (activeIndex <= 0 || -1 === getNextSelectableIndex(activeIndex, -1)) navigateToIndex(-1);
266
+ else {
267
+ const prevIndex = getNextSelectableIndex(activeIndex, -1);
268
+ navigateToIndex(prevIndex);
269
+ }
270
+ break;
271
+ case 'Enter':
272
+ if (activeIndex >= 0) {
273
+ const renderItem = renderedItems[activeIndex];
274
+ if (renderItem?.type === 'item') {
275
+ e.preventDefault();
276
+ handleItemSelect(renderItem.item);
277
+ }
278
+ }
279
+ break;
280
+ case 'Home':
281
+ {
282
+ e.preventDefault();
283
+ const firstIndex = getFirstSelectableIndex();
284
+ if (-1 !== firstIndex) navigateToIndex(firstIndex);
285
+ break;
286
+ }
287
+ case 'End':
288
+ {
289
+ e.preventDefault();
290
+ const lastIndex = getLastSelectableIndex();
291
+ if (-1 !== lastIndex) navigateToIndex(lastIndex);
292
+ break;
293
+ }
294
+ }
189
295
  };
190
296
  const handleClickOutside = (e)=>{
191
297
  if (containerRef.current && !containerRef.current.contains(e.target)) onClose();
@@ -198,11 +304,19 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
198
304
  };
199
305
  }, [
200
306
  isSearching,
307
+ isTransitioning,
308
+ activeIndex,
309
+ renderedItems,
201
310
  navigationStack.canGoBack,
202
311
  onClose,
203
312
  clearSearch,
204
313
  startTransition,
205
- handleBackTransition
314
+ handleBackTransition,
315
+ handleItemSelect,
316
+ navigateToIndex,
317
+ getNextSelectableIndex,
318
+ getFirstSelectableIndex,
319
+ getLastSelectableIndex
206
320
  ]);
207
321
  return /*#__PURE__*/ jsx("div", {
208
322
  ref: containerRef,
@@ -223,7 +337,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
223
337
  value: search,
224
338
  onChange: handleSearch,
225
339
  clear: clearSearch,
226
- placeholder: "Search"
340
+ placeholder: "Search",
341
+ inputRef: searchInputRef,
342
+ onArrowDown: handleSearchArrowDown
227
343
  }),
228
344
  /*#__PURE__*/ jsx(AnimatedContainer, {
229
345
  children: /*#__PURE__*/ jsx(AnimatedContent, {
@@ -231,7 +347,9 @@ function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title,
231
347
  direction: animationDirection,
232
348
  children: /*#__PURE__*/ jsx(ListView, {
233
349
  isLoading: childrenLoading || searchLoading || loading,
234
- items: isSearching && !isSearchingInitialItems ? searchedItems : items,
350
+ items: displayedItems,
351
+ activeIndex: activeIndex,
352
+ listRef: listRef,
235
353
  emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
236
354
  enableSections: !isSearching,
237
355
  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.9b2638b",
4
4
  "description": "Apollo Design System - React component library with Material UI theming",
5
5
  "repository": {
6
6
  "type": "git",
@@ -200,8 +200,8 @@
200
200
  "use-sync-external-store": "^1.2.0",
201
201
  "zod": "^4.3.5",
202
202
  "zustand": "^5.0.9",
203
- "@uipath/apollo-core": "5.7.1",
204
- "@uipath/apollo-wind": "0.14.0"
203
+ "@uipath/apollo-wind": "0.15.0",
204
+ "@uipath/apollo-core": "5.7.1"
205
205
  },
206
206
  "devDependencies": {
207
207
  "@lingui/cli": "^5.6.1",