@uipath/apollo-wind 2.78.0 → 2.79.1

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.
Files changed (39) hide show
  1. package/dist/components/ui/index.cjs +32 -32
  2. package/dist/components/ui/input.cjs +1 -1
  3. package/dist/components/ui/input.d.ts +2 -1
  4. package/dist/components/ui/input.js +1 -1
  5. package/dist/components/ui/json-tree-view/EditorChrome.cjs +5 -2
  6. package/dist/components/ui/json-tree-view/EditorChrome.js +5 -2
  7. package/dist/components/ui/json-tree-view/JsonLeafValueEditor.cjs +6 -3
  8. package/dist/components/ui/json-tree-view/JsonLeafValueEditor.js +6 -3
  9. package/dist/components/ui/json-tree-view/JsonTree.cjs +66 -38
  10. package/dist/components/ui/json-tree-view/JsonTree.d.ts +6 -1
  11. package/dist/components/ui/json-tree-view/JsonTree.js +66 -38
  12. package/dist/components/ui/json-tree-view/JsonTree.types.d.ts +6 -1
  13. package/dist/components/ui/json-tree-view/JsonTreeRow.cjs +116 -81
  14. package/dist/components/ui/json-tree-view/JsonTreeRow.d.ts +16 -8
  15. package/dist/components/ui/json-tree-view/JsonTreeRow.js +116 -81
  16. package/dist/components/ui/json-tree-view/NodeKey.cjs +2 -2
  17. package/dist/components/ui/json-tree-view/NodeKey.js +2 -2
  18. package/dist/components/ui/json-tree-view/RowActions.cjs +6 -6
  19. package/dist/components/ui/json-tree-view/RowActions.js +6 -6
  20. package/dist/components/ui/json-tree-view/buildJsonTree.cjs +20 -1
  21. package/dist/components/ui/json-tree-view/buildJsonTree.d.ts +4 -0
  22. package/dist/components/ui/json-tree-view/buildJsonTree.js +20 -1
  23. package/dist/components/ui/json-tree-view/strings.cjs +2 -0
  24. package/dist/components/ui/json-tree-view/strings.d.ts +12 -0
  25. package/dist/components/ui/json-tree-view/strings.js +2 -0
  26. package/dist/components/ui/json-tree-view/treeGrid.cjs +306 -0
  27. package/dist/components/ui/json-tree-view/treeGrid.d.ts +36 -0
  28. package/dist/components/ui/json-tree-view/treeGrid.js +269 -0
  29. package/dist/components/ui/tool-call.cjs +2 -2
  30. package/dist/components/ui/tool-call.js +2 -2
  31. package/dist/lib/clipboard.cjs +4 -0
  32. package/dist/lib/clipboard.js +4 -0
  33. package/dist/lib/use-ancestor-density.cjs +2 -2
  34. package/dist/lib/use-ancestor-density.js +2 -2
  35. package/dist/lib/use-isomorphic-layout-effect.cjs +37 -0
  36. package/dist/lib/use-isomorphic-layout-effect.d.ts +3 -0
  37. package/dist/lib/use-isomorphic-layout-effect.js +3 -0
  38. package/dist/styles.css +16 -13
  39. package/package.json +1 -1
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ isParentRow: ()=>isParentRow,
28
+ useTreeGrid: ()=>useTreeGrid
29
+ });
30
+ const external_react_namespaceObject = require("react");
31
+ const use_isomorphic_layout_effect_cjs_namespaceObject = require("../../../lib/use-isomorphic-layout-effect.cjs");
32
+ const external_buildJsonTree_cjs_namespaceObject = require("./buildJsonTree.cjs");
33
+ const EDITOR_ATTR = 'data-json-tree-editor';
34
+ const SKIP_ATTR = 'data-json-tree-skip';
35
+ const MANAGED_ATTR = 'data-json-tree-tabindex';
36
+ const ROW_SELECTOR = '[role="row"]';
37
+ const CONTROL_SELECTOR = 'button, a[href], input, select, textarea, [contenteditable="true"], [tabindex]:not([role="gridcell"])';
38
+ const TEXT_ENTRY_SELECTOR = `input, textarea, select, [contenteditable="true"], [${EDITOR_ATTR}]`;
39
+ const HANDLED_KEYS = new Set([
40
+ 'ArrowDown',
41
+ 'ArrowUp',
42
+ 'ArrowLeft',
43
+ 'ArrowRight',
44
+ 'PageDown',
45
+ 'PageUp',
46
+ 'Home',
47
+ 'End',
48
+ 'Enter'
49
+ ]);
50
+ const PAGE_SIZE = 10;
51
+ function isOwnRow(grid, row) {
52
+ return row.closest('[role="treegrid"]') === grid;
53
+ }
54
+ function isNavigable(element) {
55
+ return !element.hasAttribute('disabled') && !element.closest(`[${EDITOR_ATTR}], [${SKIP_ATTR}], [aria-hidden="true"]`);
56
+ }
57
+ function cellsOf(row) {
58
+ return Array.from(row.querySelectorAll('[role="gridcell"]'));
59
+ }
60
+ function stopsOf(cell) {
61
+ const controls = Array.from(cell.querySelectorAll(CONTROL_SELECTOR)).filter(isNavigable);
62
+ if (controls.length > 0) return controls;
63
+ return cell.textContent?.trim() ? [
64
+ cell
65
+ ] : [];
66
+ }
67
+ function rowStops(row) {
68
+ return cellsOf(row).flatMap(stopsOf);
69
+ }
70
+ function cellNameOf(element) {
71
+ return element.closest('[role="gridcell"]')?.dataset.cell;
72
+ }
73
+ function findRow(grid, path) {
74
+ return Array.from(grid.querySelectorAll(ROW_SELECTOR)).find((row)=>row.dataset.path === path && isOwnRow(grid, row));
75
+ }
76
+ function focusInRow(row, cell) {
77
+ const target = cell ? cellsOf(row).find((c)=>c.dataset.cell === cell) : void 0;
78
+ const stop = target ? stopsOf(target)[0] : void 0;
79
+ (stop ?? row).focus();
80
+ }
81
+ function syncRowTabOrder(row, tabbable) {
82
+ for (const control of row.querySelectorAll(CONTROL_SELECTOR)){
83
+ if (control.closest(`[${SKIP_ATTR}]`)) continue;
84
+ const saved = control.getAttribute(MANAGED_ATTR);
85
+ if (tabbable) {
86
+ if (null === saved) continue;
87
+ if ('' === saved) control.removeAttribute('tabindex');
88
+ else control.setAttribute('tabindex', saved);
89
+ control.removeAttribute(MANAGED_ATTR);
90
+ } else if (null === saved) {
91
+ control.setAttribute(MANAGED_ATTR, control.getAttribute('tabindex') ?? '');
92
+ control.setAttribute('tabindex', '-1');
93
+ }
94
+ }
95
+ }
96
+ function ancestorPaths(segments) {
97
+ const paths = [];
98
+ let path = '';
99
+ for (const segment of segments.slice(0, -1)){
100
+ path = (0, external_buildJsonTree_cjs_namespaceObject.appendPathSegment)(path, segment);
101
+ paths.unshift(path);
102
+ }
103
+ return paths;
104
+ }
105
+ function isParentRow(row) {
106
+ return !!row.node.children?.length;
107
+ }
108
+ function useTreeGrid({ rows, indexByPath, collapsed, toggle }) {
109
+ const [grid, setGrid] = (0, external_react_namespaceObject.useState)(null);
110
+ const [active, setActive] = (0, external_react_namespaceObject.useState)(null);
111
+ const activePath = (0, external_react_namespaceObject.useMemo)(()=>{
112
+ if (active && indexByPath.has(active.path)) return active.path;
113
+ const ancestor = active && ancestorPaths(active.segments).find((path)=>indexByPath.has(path));
114
+ return ancestor ?? rows[0]?.node.path ?? null;
115
+ }, [
116
+ active,
117
+ indexByPath,
118
+ rows
119
+ ]);
120
+ const pendingFocusRef = (0, external_react_namespaceObject.useRef)(null);
121
+ const openEditorsRef = (0, external_react_namespaceObject.useRef)({});
122
+ const lastFocusedRef = (0, external_react_namespaceObject.useRef)(null);
123
+ const activePathRef = (0, external_react_namespaceObject.useRef)(activePath);
124
+ const syncedPathRef = (0, external_react_namespaceObject.useRef)(null);
125
+ (0, use_isomorphic_layout_effect_cjs_namespaceObject.useIsomorphicLayoutEffect)(()=>{
126
+ activePathRef.current = activePath;
127
+ const previous = syncedPathRef.current;
128
+ syncedPathRef.current = activePath;
129
+ if (!grid || previous === activePath) return;
130
+ for (const path of [
131
+ previous,
132
+ activePath
133
+ ]){
134
+ const row = null === path ? void 0 : findRow(grid, path);
135
+ if (row) syncRowTabOrder(row, path === activePath);
136
+ }
137
+ }, [
138
+ grid,
139
+ activePath
140
+ ]);
141
+ (0, use_isomorphic_layout_effect_cjs_namespaceObject.useIsomorphicLayoutEffect)(()=>{
142
+ if (!grid) return;
143
+ const sync = (row)=>syncRowTabOrder(row, row.dataset.path === activePathRef.current);
144
+ for (const row of grid.querySelectorAll(ROW_SELECTOR))sync(row);
145
+ const observer = new MutationObserver((mutations)=>{
146
+ const touched = new Set();
147
+ for (const mutation of mutations)for (const added of mutation.addedNodes){
148
+ if (!(added instanceof Element)) continue;
149
+ const row = added.closest(ROW_SELECTOR);
150
+ if (row) touched.add(row);
151
+ for (const inner of added.querySelectorAll(ROW_SELECTOR))touched.add(inner);
152
+ }
153
+ for (const row of touched)sync(row);
154
+ });
155
+ observer.observe(grid, {
156
+ childList: true,
157
+ subtree: true
158
+ });
159
+ return ()=>observer.disconnect();
160
+ }, [
161
+ grid
162
+ ]);
163
+ (0, use_isomorphic_layout_effect_cjs_namespaceObject.useIsomorphicLayoutEffect)(()=>{
164
+ const pending = pendingFocusRef.current;
165
+ pendingFocusRef.current = null;
166
+ if (!grid) return;
167
+ const row = pending && findRow(grid, pending.path);
168
+ if (pending && row) {
169
+ const { opener } = pending;
170
+ if (opener instanceof HTMLElement && opener.isConnected && row.contains(opener)) opener.focus();
171
+ else focusInRow(row, pending.cell);
172
+ return;
173
+ }
174
+ const lost = lastFocusedRef.current;
175
+ const focusDropped = !document.activeElement || document.activeElement === document.body;
176
+ if (lost && !lost.isConnected && focusDropped && activePath) findRow(grid, activePath)?.focus();
177
+ });
178
+ const focusRow = (index, cell)=>{
179
+ const row = rows[index];
180
+ if (!row) return;
181
+ const element = grid && findRow(grid, row.node.path);
182
+ if (element) return void focusInRow(element, cell);
183
+ pendingFocusRef.current = {
184
+ path: row.node.path,
185
+ cell
186
+ };
187
+ setActive({
188
+ path: row.node.path,
189
+ segments: row.node.segments
190
+ });
191
+ };
192
+ const trackEditor = (kind, set)=>(path)=>{
193
+ if (null !== path) {
194
+ const opener = document.activeElement;
195
+ const cell = (opener && cellNameOf(opener)) ?? ('json' === kind ? 'actions' : void 0);
196
+ openEditorsRef.current[kind] = {
197
+ path,
198
+ cell,
199
+ opener
200
+ };
201
+ } else {
202
+ const open = openEditorsRef.current[kind];
203
+ openEditorsRef.current[kind] = void 0;
204
+ if (open && grid && findRow(grid, open.path)?.contains(document.activeElement)) pendingFocusRef.current = open;
205
+ }
206
+ set(path);
207
+ };
208
+ const onKeyDown = (event)=>{
209
+ if (!HANDLED_KEYS.has(event.key) || event.altKey || event.metaKey || event.shiftKey) return;
210
+ if (event.ctrlKey && 'Home' !== event.key && 'End' !== event.key) return;
211
+ const { target, currentTarget } = event;
212
+ if (!(target instanceof HTMLElement) || !currentTarget.contains(target)) return;
213
+ if (target.closest(TEXT_ENTRY_SELECTOR)) return;
214
+ const row = target.closest(ROW_SELECTOR);
215
+ if (!row || !isOwnRow(currentTarget, row)) return;
216
+ const path = row.dataset.path;
217
+ const index = void 0 === path ? void 0 : indexByPath.get(path);
218
+ const flatRow = void 0 === index ? void 0 : rows[index];
219
+ if (void 0 === path || void 0 === index || !flatRow) return;
220
+ const isParent = isParentRow(flatRow);
221
+ const expanded = isParent && !(0, external_buildJsonTree_cjs_namespaceObject.isPathCollapsed)(collapsed, path);
222
+ const onRow = target === row;
223
+ const stops = onRow ? [] : rowStops(row);
224
+ const at = stops.indexOf(target);
225
+ const cell = onRow ? void 0 : cellNameOf(target);
226
+ const last = rows.length - 1;
227
+ const moveTo = (next)=>focusRow(Math.max(0, Math.min(last, next)), cell);
228
+ switch(event.key){
229
+ case 'ArrowDown':
230
+ moveTo(index + 1);
231
+ break;
232
+ case 'ArrowUp':
233
+ moveTo(index - 1);
234
+ break;
235
+ case 'PageDown':
236
+ moveTo(index + PAGE_SIZE);
237
+ break;
238
+ case 'PageUp':
239
+ moveTo(index - PAGE_SIZE);
240
+ break;
241
+ case 'Home':
242
+ if (onRow || event.ctrlKey) moveTo(0);
243
+ else stops[0]?.focus();
244
+ break;
245
+ case 'End':
246
+ if (onRow || event.ctrlKey) moveTo(last);
247
+ else stops[stops.length - 1]?.focus();
248
+ break;
249
+ case 'ArrowRight':
250
+ if (onRow) if (isParent && !expanded && toggle) toggle(path);
251
+ else rowStops(row)[0]?.focus();
252
+ else stops[at + 1]?.focus();
253
+ break;
254
+ case 'ArrowLeft':
255
+ if (onRow) if (expanded && toggle) toggle(path);
256
+ else {
257
+ const parentPath = ancestorPaths(flatRow.node.segments)[0];
258
+ const parent = void 0 === parentPath ? void 0 : indexByPath.get(parentPath);
259
+ if (void 0 !== parent) focusRow(parent, void 0);
260
+ }
261
+ else (stops[at - 1] ?? row).focus();
262
+ break;
263
+ case 'Enter':
264
+ if (!onRow || !isParent || !toggle) return;
265
+ toggle(path);
266
+ break;
267
+ }
268
+ event.preventDefault();
269
+ event.stopPropagation();
270
+ };
271
+ const onFocus = (event)=>{
272
+ const { target } = event;
273
+ if (!(target instanceof HTMLElement)) return;
274
+ lastFocusedRef.current = target;
275
+ const path = target.closest(ROW_SELECTOR)?.dataset.path;
276
+ const index = void 0 === path ? void 0 : indexByPath.get(path);
277
+ const row = void 0 === index ? void 0 : rows[index];
278
+ if (void 0 === path || !row || path === active?.path) return;
279
+ setActive({
280
+ path,
281
+ segments: row.node.segments
282
+ });
283
+ };
284
+ const onBlur = (event)=>{
285
+ if (!event.currentTarget.contains(event.relatedTarget)) lastFocusedRef.current = null;
286
+ };
287
+ return {
288
+ activePath,
289
+ gridHandlers: {
290
+ ref: setGrid,
291
+ onFocus,
292
+ onBlur,
293
+ onKeyDownCapture: onKeyDown
294
+ },
295
+ trackEditor
296
+ };
297
+ }
298
+ exports.isParentRow = __webpack_exports__.isParentRow;
299
+ exports.useTreeGrid = __webpack_exports__.useTreeGrid;
300
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
301
+ "isParentRow",
302
+ "useTreeGrid"
303
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
304
+ Object.defineProperty(exports, '__esModule', {
305
+ value: true
306
+ });
@@ -0,0 +1,36 @@
1
+ import { type FocusEvent, type KeyboardEvent } from 'react';
2
+ import { type FlatJsonTreeRow } from './buildJsonTree';
3
+ /**
4
+ * The tree's keyboard model, the APG treegrid pattern: one Tab stop for the
5
+ * whole tree, arrows between rows and across a row's controls.
6
+ */
7
+ /** The cells every row renders, in reading order. Up/Down keeps focus in the same one. */
8
+ export type TreeGridCell = 'name' | 'value' | 'actions' | 'detail';
9
+ /** Rows that can expand: a container with at least one child row to show. */
10
+ export declare function isParentRow(row: FlatJsonTreeRow): boolean;
11
+ /** The leaf editors (inline and wrapped) and the JSON editor, which can be open at once. */
12
+ type EditorKind = 'leaf' | 'json';
13
+ export interface UseTreeGridOptions {
14
+ rows: FlatJsonTreeRow[];
15
+ indexByPath: Map<string, number>;
16
+ collapsed: Record<string, boolean>;
17
+ /** Undefined when the host fixes expansion. */
18
+ toggle?: (path: string) => void;
19
+ }
20
+ /**
21
+ * Focus and keyboard state for the grid: which row holds the Tab stop, the Tab
22
+ * order that follows it, arrow-key moves, and putting focus back when an editor
23
+ * closes or the focused row leaves the view.
24
+ */
25
+ export declare function useTreeGrid({ rows, indexByPath, collapsed, toggle }: UseTreeGridOptions): {
26
+ /** The row holding the Tab stop, kept mounted by a virtualized tree. */
27
+ activePath: string;
28
+ gridHandlers: {
29
+ ref: import("react").Dispatch<import("react").SetStateAction<HTMLDivElement | null>>;
30
+ onFocus: (event: FocusEvent<HTMLElement>) => void;
31
+ onBlur: (event: FocusEvent<HTMLElement>) => void;
32
+ onKeyDownCapture: (event: KeyboardEvent<HTMLElement>) => void;
33
+ };
34
+ trackEditor: (kind: EditorKind, set: (path: string | null) => void) => (path: string | null) => void;
35
+ };
36
+ export {};
@@ -0,0 +1,269 @@
1
+ import { useMemo, useRef, useState } from "react";
2
+ import { useIsomorphicLayoutEffect } from "../../../lib/use-isomorphic-layout-effect.js";
3
+ import { appendPathSegment, isPathCollapsed } from "./buildJsonTree.js";
4
+ const EDITOR_ATTR = 'data-json-tree-editor';
5
+ const SKIP_ATTR = 'data-json-tree-skip';
6
+ const MANAGED_ATTR = 'data-json-tree-tabindex';
7
+ const ROW_SELECTOR = '[role="row"]';
8
+ const CONTROL_SELECTOR = 'button, a[href], input, select, textarea, [contenteditable="true"], [tabindex]:not([role="gridcell"])';
9
+ const TEXT_ENTRY_SELECTOR = `input, textarea, select, [contenteditable="true"], [${EDITOR_ATTR}]`;
10
+ const HANDLED_KEYS = new Set([
11
+ 'ArrowDown',
12
+ 'ArrowUp',
13
+ 'ArrowLeft',
14
+ 'ArrowRight',
15
+ 'PageDown',
16
+ 'PageUp',
17
+ 'Home',
18
+ 'End',
19
+ 'Enter'
20
+ ]);
21
+ const PAGE_SIZE = 10;
22
+ function isOwnRow(grid, row) {
23
+ return row.closest('[role="treegrid"]') === grid;
24
+ }
25
+ function isNavigable(element) {
26
+ return !element.hasAttribute('disabled') && !element.closest(`[${EDITOR_ATTR}], [${SKIP_ATTR}], [aria-hidden="true"]`);
27
+ }
28
+ function cellsOf(row) {
29
+ return Array.from(row.querySelectorAll('[role="gridcell"]'));
30
+ }
31
+ function stopsOf(cell) {
32
+ const controls = Array.from(cell.querySelectorAll(CONTROL_SELECTOR)).filter(isNavigable);
33
+ if (controls.length > 0) return controls;
34
+ return cell.textContent?.trim() ? [
35
+ cell
36
+ ] : [];
37
+ }
38
+ function rowStops(row) {
39
+ return cellsOf(row).flatMap(stopsOf);
40
+ }
41
+ function cellNameOf(element) {
42
+ return element.closest('[role="gridcell"]')?.dataset.cell;
43
+ }
44
+ function findRow(grid, path) {
45
+ return Array.from(grid.querySelectorAll(ROW_SELECTOR)).find((row)=>row.dataset.path === path && isOwnRow(grid, row));
46
+ }
47
+ function focusInRow(row, cell) {
48
+ const target = cell ? cellsOf(row).find((c)=>c.dataset.cell === cell) : void 0;
49
+ const stop = target ? stopsOf(target)[0] : void 0;
50
+ (stop ?? row).focus();
51
+ }
52
+ function syncRowTabOrder(row, tabbable) {
53
+ for (const control of row.querySelectorAll(CONTROL_SELECTOR)){
54
+ if (control.closest(`[${SKIP_ATTR}]`)) continue;
55
+ const saved = control.getAttribute(MANAGED_ATTR);
56
+ if (tabbable) {
57
+ if (null === saved) continue;
58
+ if ('' === saved) control.removeAttribute('tabindex');
59
+ else control.setAttribute('tabindex', saved);
60
+ control.removeAttribute(MANAGED_ATTR);
61
+ } else if (null === saved) {
62
+ control.setAttribute(MANAGED_ATTR, control.getAttribute('tabindex') ?? '');
63
+ control.setAttribute('tabindex', '-1');
64
+ }
65
+ }
66
+ }
67
+ function ancestorPaths(segments) {
68
+ const paths = [];
69
+ let path = '';
70
+ for (const segment of segments.slice(0, -1)){
71
+ path = appendPathSegment(path, segment);
72
+ paths.unshift(path);
73
+ }
74
+ return paths;
75
+ }
76
+ function isParentRow(row) {
77
+ return !!row.node.children?.length;
78
+ }
79
+ function useTreeGrid({ rows, indexByPath, collapsed, toggle }) {
80
+ const [grid, setGrid] = useState(null);
81
+ const [active, setActive] = useState(null);
82
+ const activePath = useMemo(()=>{
83
+ if (active && indexByPath.has(active.path)) return active.path;
84
+ const ancestor = active && ancestorPaths(active.segments).find((path)=>indexByPath.has(path));
85
+ return ancestor ?? rows[0]?.node.path ?? null;
86
+ }, [
87
+ active,
88
+ indexByPath,
89
+ rows
90
+ ]);
91
+ const pendingFocusRef = useRef(null);
92
+ const openEditorsRef = useRef({});
93
+ const lastFocusedRef = useRef(null);
94
+ const activePathRef = useRef(activePath);
95
+ const syncedPathRef = useRef(null);
96
+ useIsomorphicLayoutEffect(()=>{
97
+ activePathRef.current = activePath;
98
+ const previous = syncedPathRef.current;
99
+ syncedPathRef.current = activePath;
100
+ if (!grid || previous === activePath) return;
101
+ for (const path of [
102
+ previous,
103
+ activePath
104
+ ]){
105
+ const row = null === path ? void 0 : findRow(grid, path);
106
+ if (row) syncRowTabOrder(row, path === activePath);
107
+ }
108
+ }, [
109
+ grid,
110
+ activePath
111
+ ]);
112
+ useIsomorphicLayoutEffect(()=>{
113
+ if (!grid) return;
114
+ const sync = (row)=>syncRowTabOrder(row, row.dataset.path === activePathRef.current);
115
+ for (const row of grid.querySelectorAll(ROW_SELECTOR))sync(row);
116
+ const observer = new MutationObserver((mutations)=>{
117
+ const touched = new Set();
118
+ for (const mutation of mutations)for (const added of mutation.addedNodes){
119
+ if (!(added instanceof Element)) continue;
120
+ const row = added.closest(ROW_SELECTOR);
121
+ if (row) touched.add(row);
122
+ for (const inner of added.querySelectorAll(ROW_SELECTOR))touched.add(inner);
123
+ }
124
+ for (const row of touched)sync(row);
125
+ });
126
+ observer.observe(grid, {
127
+ childList: true,
128
+ subtree: true
129
+ });
130
+ return ()=>observer.disconnect();
131
+ }, [
132
+ grid
133
+ ]);
134
+ useIsomorphicLayoutEffect(()=>{
135
+ const pending = pendingFocusRef.current;
136
+ pendingFocusRef.current = null;
137
+ if (!grid) return;
138
+ const row = pending && findRow(grid, pending.path);
139
+ if (pending && row) {
140
+ const { opener } = pending;
141
+ if (opener instanceof HTMLElement && opener.isConnected && row.contains(opener)) opener.focus();
142
+ else focusInRow(row, pending.cell);
143
+ return;
144
+ }
145
+ const lost = lastFocusedRef.current;
146
+ const focusDropped = !document.activeElement || document.activeElement === document.body;
147
+ if (lost && !lost.isConnected && focusDropped && activePath) findRow(grid, activePath)?.focus();
148
+ });
149
+ const focusRow = (index, cell)=>{
150
+ const row = rows[index];
151
+ if (!row) return;
152
+ const element = grid && findRow(grid, row.node.path);
153
+ if (element) return void focusInRow(element, cell);
154
+ pendingFocusRef.current = {
155
+ path: row.node.path,
156
+ cell
157
+ };
158
+ setActive({
159
+ path: row.node.path,
160
+ segments: row.node.segments
161
+ });
162
+ };
163
+ const trackEditor = (kind, set)=>(path)=>{
164
+ if (null !== path) {
165
+ const opener = document.activeElement;
166
+ const cell = (opener && cellNameOf(opener)) ?? ('json' === kind ? 'actions' : void 0);
167
+ openEditorsRef.current[kind] = {
168
+ path,
169
+ cell,
170
+ opener
171
+ };
172
+ } else {
173
+ const open = openEditorsRef.current[kind];
174
+ openEditorsRef.current[kind] = void 0;
175
+ if (open && grid && findRow(grid, open.path)?.contains(document.activeElement)) pendingFocusRef.current = open;
176
+ }
177
+ set(path);
178
+ };
179
+ const onKeyDown = (event)=>{
180
+ if (!HANDLED_KEYS.has(event.key) || event.altKey || event.metaKey || event.shiftKey) return;
181
+ if (event.ctrlKey && 'Home' !== event.key && 'End' !== event.key) return;
182
+ const { target, currentTarget } = event;
183
+ if (!(target instanceof HTMLElement) || !currentTarget.contains(target)) return;
184
+ if (target.closest(TEXT_ENTRY_SELECTOR)) return;
185
+ const row = target.closest(ROW_SELECTOR);
186
+ if (!row || !isOwnRow(currentTarget, row)) return;
187
+ const path = row.dataset.path;
188
+ const index = void 0 === path ? void 0 : indexByPath.get(path);
189
+ const flatRow = void 0 === index ? void 0 : rows[index];
190
+ if (void 0 === path || void 0 === index || !flatRow) return;
191
+ const isParent = isParentRow(flatRow);
192
+ const expanded = isParent && !isPathCollapsed(collapsed, path);
193
+ const onRow = target === row;
194
+ const stops = onRow ? [] : rowStops(row);
195
+ const at = stops.indexOf(target);
196
+ const cell = onRow ? void 0 : cellNameOf(target);
197
+ const last = rows.length - 1;
198
+ const moveTo = (next)=>focusRow(Math.max(0, Math.min(last, next)), cell);
199
+ switch(event.key){
200
+ case 'ArrowDown':
201
+ moveTo(index + 1);
202
+ break;
203
+ case 'ArrowUp':
204
+ moveTo(index - 1);
205
+ break;
206
+ case 'PageDown':
207
+ moveTo(index + PAGE_SIZE);
208
+ break;
209
+ case 'PageUp':
210
+ moveTo(index - PAGE_SIZE);
211
+ break;
212
+ case 'Home':
213
+ if (onRow || event.ctrlKey) moveTo(0);
214
+ else stops[0]?.focus();
215
+ break;
216
+ case 'End':
217
+ if (onRow || event.ctrlKey) moveTo(last);
218
+ else stops[stops.length - 1]?.focus();
219
+ break;
220
+ case 'ArrowRight':
221
+ if (onRow) if (isParent && !expanded && toggle) toggle(path);
222
+ else rowStops(row)[0]?.focus();
223
+ else stops[at + 1]?.focus();
224
+ break;
225
+ case 'ArrowLeft':
226
+ if (onRow) if (expanded && toggle) toggle(path);
227
+ else {
228
+ const parentPath = ancestorPaths(flatRow.node.segments)[0];
229
+ const parent = void 0 === parentPath ? void 0 : indexByPath.get(parentPath);
230
+ if (void 0 !== parent) focusRow(parent, void 0);
231
+ }
232
+ else (stops[at - 1] ?? row).focus();
233
+ break;
234
+ case 'Enter':
235
+ if (!onRow || !isParent || !toggle) return;
236
+ toggle(path);
237
+ break;
238
+ }
239
+ event.preventDefault();
240
+ event.stopPropagation();
241
+ };
242
+ const onFocus = (event)=>{
243
+ const { target } = event;
244
+ if (!(target instanceof HTMLElement)) return;
245
+ lastFocusedRef.current = target;
246
+ const path = target.closest(ROW_SELECTOR)?.dataset.path;
247
+ const index = void 0 === path ? void 0 : indexByPath.get(path);
248
+ const row = void 0 === index ? void 0 : rows[index];
249
+ if (void 0 === path || !row || path === active?.path) return;
250
+ setActive({
251
+ path,
252
+ segments: row.node.segments
253
+ });
254
+ };
255
+ const onBlur = (event)=>{
256
+ if (!event.currentTarget.contains(event.relatedTarget)) lastFocusedRef.current = null;
257
+ };
258
+ return {
259
+ activePath,
260
+ gridHandlers: {
261
+ ref: setGrid,
262
+ onFocus,
263
+ onBlur,
264
+ onKeyDownCapture: onKeyDown
265
+ },
266
+ trackEditor
267
+ };
268
+ }
269
+ export { isParentRow, useTreeGrid };
@@ -40,6 +40,7 @@ const external_lucide_react_namespaceObject = require("lucide-react");
40
40
  const external_react_namespaceObject = require("react");
41
41
  const index_cjs_namespaceObject = require("../../lib/index.cjs");
42
42
  const disclosure_row_cjs_namespaceObject = require("../../lib/disclosure-row.cjs");
43
+ const use_isomorphic_layout_effect_cjs_namespaceObject = require("../../lib/use-isomorphic-layout-effect.cjs");
43
44
  const external_collapsible_cjs_namespaceObject = require("./collapsible.cjs");
44
45
  const external_json_tree_view_index_cjs_namespaceObject = require("./json-tree-view/index.cjs");
45
46
  const DEFAULT_TOOL_CALL_STRINGS = {
@@ -70,7 +71,6 @@ function mergeStrings(overrides) {
70
71
  }
71
72
  return merged;
72
73
  }
73
- const useIsomorphicLayoutEffect = "u" < typeof window ? external_react_namespaceObject.useEffect : external_react_namespaceObject.useLayoutEffect;
74
74
  const TOGGLE_CLASSES = `${disclosure_row_cjs_namespaceObject.disclosureRowClassName} hover:text-foreground`;
75
75
  const toolCallVariants = (0, external_class_variance_authority_namespaceObject.cva)('group/tool-call flex w-full min-w-0 flex-col text-muted-foreground', {
76
76
  variants: {
@@ -191,7 +191,7 @@ const ToolCallHeader = /*#__PURE__*/ external_react_namespaceObject.forwardRef((
191
191
  ToolCallHeader.displayName = 'ToolCallHeader';
192
192
  const ToolCallContent = /*#__PURE__*/ external_react_namespaceObject.forwardRef(({ className, ...props }, ref)=>{
193
193
  const { registerContent } = useToolCallContext('ToolCallContent');
194
- useIsomorphicLayoutEffect(()=>registerContent(), [
194
+ (0, use_isomorphic_layout_effect_cjs_namespaceObject.useIsomorphicLayoutEffect)(()=>registerContent(), [
195
195
  registerContent
196
196
  ]);
197
197
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_collapsible_cjs_namespaceObject.CollapsibleContent, {
@@ -1,9 +1,10 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { cva } from "class-variance-authority";
3
3
  import { ChevronDown, ChevronRight, CircleCheck, CircleX, Clock, Loader2 } from "lucide-react";
4
- import { createContext, forwardRef, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useState } from "react";
4
+ import { createContext, forwardRef, useCallback, useContext, useMemo, useState } from "react";
5
5
  import { cn } from "../../lib/index.js";
6
6
  import { disclosureRowClassName } from "../../lib/disclosure-row.js";
7
+ import { useIsomorphicLayoutEffect } from "../../lib/use-isomorphic-layout-effect.js";
7
8
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./collapsible.js";
8
9
  import { JsonTreeView, buildJsonTree, collectContainerPaths } from "./json-tree-view/index.js";
9
10
  const DEFAULT_TOOL_CALL_STRINGS = {
@@ -34,7 +35,6 @@ function mergeStrings(overrides) {
34
35
  }
35
36
  return merged;
36
37
  }
37
- const useIsomorphicLayoutEffect = "u" < typeof window ? useEffect : useLayoutEffect;
38
38
  const TOGGLE_CLASSES = `${disclosureRowClassName} hover:text-foreground`;
39
39
  const toolCallVariants = cva('group/tool-call flex w-full min-w-0 flex-col text-muted-foreground', {
40
40
  variants: {
@@ -37,6 +37,7 @@ async function copyTextToClipboard(text) {
37
37
  textarea.setAttribute('readonly', '');
38
38
  textarea.style.position = 'fixed';
39
39
  textarea.style.opacity = '0';
40
+ const previousFocus = document.activeElement;
40
41
  document.body.appendChild(textarea);
41
42
  const selection = document.getSelection();
42
43
  const previousRange = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null;
@@ -48,6 +49,9 @@ async function copyTextToClipboard(text) {
48
49
  copied = false;
49
50
  }
50
51
  textarea.remove();
52
+ if (previousFocus instanceof HTMLElement) previousFocus.focus({
53
+ preventScroll: true
54
+ });
51
55
  if (previousRange && selection) {
52
56
  selection.removeAllRanges();
53
57
  selection.addRange(previousRange);