@uipath/apollo-wind 2.79.0 → 2.79.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/forms/metadata-form.cjs +3 -2
- package/dist/components/forms/metadata-form.js +3 -2
- package/dist/components/ui/field-actions/ai-assist-action.cjs +7 -5
- package/dist/components/ui/field-actions/ai-assist-action.js +7 -5
- package/dist/components/ui/field-actions/collapse.cjs +7 -7
- package/dist/components/ui/field-actions/collapse.d.ts +6 -3
- package/dist/components/ui/field-actions/collapse.js +3 -3
- package/dist/components/ui/field-actions/insert-variable-action.cjs +7 -7
- package/dist/components/ui/field-actions/insert-variable-action.js +8 -8
- package/dist/components/ui/index.cjs +34 -34
- package/dist/components/ui/json-tree-view/EditorChrome.cjs +5 -2
- package/dist/components/ui/json-tree-view/EditorChrome.js +5 -2
- package/dist/components/ui/json-tree-view/JsonLeafValueEditor.cjs +6 -3
- package/dist/components/ui/json-tree-view/JsonLeafValueEditor.js +6 -3
- package/dist/components/ui/json-tree-view/JsonTree.cjs +66 -38
- package/dist/components/ui/json-tree-view/JsonTree.d.ts +6 -1
- package/dist/components/ui/json-tree-view/JsonTree.js +66 -38
- package/dist/components/ui/json-tree-view/JsonTree.types.d.ts +6 -1
- package/dist/components/ui/json-tree-view/JsonTreeRow.cjs +116 -81
- package/dist/components/ui/json-tree-view/JsonTreeRow.d.ts +16 -8
- package/dist/components/ui/json-tree-view/JsonTreeRow.js +116 -81
- package/dist/components/ui/json-tree-view/NodeKey.cjs +2 -2
- package/dist/components/ui/json-tree-view/NodeKey.js +2 -2
- package/dist/components/ui/json-tree-view/RowActions.cjs +6 -6
- package/dist/components/ui/json-tree-view/RowActions.js +6 -6
- package/dist/components/ui/json-tree-view/buildJsonTree.cjs +20 -1
- package/dist/components/ui/json-tree-view/buildJsonTree.d.ts +4 -0
- package/dist/components/ui/json-tree-view/buildJsonTree.js +20 -1
- package/dist/components/ui/json-tree-view/strings.cjs +2 -0
- package/dist/components/ui/json-tree-view/strings.d.ts +12 -0
- package/dist/components/ui/json-tree-view/strings.js +2 -0
- package/dist/components/ui/json-tree-view/treeGrid.cjs +306 -0
- package/dist/components/ui/json-tree-view/treeGrid.d.ts +36 -0
- package/dist/components/ui/json-tree-view/treeGrid.js +269 -0
- package/dist/components/ui/quick-form-field/components/field-header.cjs +14 -14
- package/dist/components/ui/quick-form-field/components/field-header.js +15 -15
- package/dist/components/ui/tool-call.cjs +2 -2
- package/dist/components/ui/tool-call.js +2 -2
- package/dist/lib/clipboard.cjs +4 -0
- package/dist/lib/clipboard.js +4 -0
- package/dist/lib/use-ancestor-density.cjs +2 -2
- package/dist/lib/use-ancestor-density.js +2 -2
- package/dist/lib/use-isomorphic-layout-effect.cjs +37 -0
- package/dist/lib/use-isomorphic-layout-effect.d.ts +3 -0
- package/dist/lib/use-isomorphic-layout-effect.js +3 -0
- package/dist/styles.css +18 -26
- package/dist/tailwind.css +2 -1
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../../lib/index.js";
|
|
3
|
-
import { useJsonTreeViewStrings } from "./strings.js";
|
|
4
3
|
import { JsonTreeTooltip } from "./JsonTreeTooltip.js";
|
|
4
|
+
import { useJsonTreeViewStrings } from "./strings.js";
|
|
5
5
|
function NodeKey({ node, label, displayPath, onCopyPath, className }) {
|
|
6
6
|
const strings = useJsonTreeViewStrings();
|
|
7
7
|
const text = label ?? node.key;
|
|
8
8
|
const copyPathText = displayPath ?? node.path;
|
|
9
|
-
const keyClass = cn('min-w-4
|
|
9
|
+
const keyClass = cn('min-w-4 truncate text-xs text-foreground', null != label ? 'font-medium' : 'font-mono', void 0 === node.value && 'text-foreground-muted', className);
|
|
10
10
|
if (!onCopyPath) return /*#__PURE__*/ jsx("span", {
|
|
11
11
|
className: keyClass,
|
|
12
12
|
children: text
|
|
@@ -27,14 +27,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27
27
|
RowActions: ()=>RowActions
|
|
28
28
|
});
|
|
29
29
|
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
30
|
-
const external_button_cjs_namespaceObject = require("../button.cjs");
|
|
31
|
-
const index_cjs_namespaceObject = require("../../../lib/index.cjs");
|
|
32
|
-
const external_dropdown_menu_cjs_namespaceObject = require("../dropdown-menu.cjs");
|
|
33
30
|
const external_lucide_react_namespaceObject = require("lucide-react");
|
|
34
31
|
const external_react_namespaceObject = require("react");
|
|
35
|
-
const
|
|
32
|
+
const external_button_cjs_namespaceObject = require("../button.cjs");
|
|
33
|
+
const external_dropdown_menu_cjs_namespaceObject = require("../dropdown-menu.cjs");
|
|
34
|
+
const index_cjs_namespaceObject = require("../../../lib/index.cjs");
|
|
36
35
|
const external_JsonTreeTooltip_cjs_namespaceObject = require("./JsonTreeTooltip.cjs");
|
|
37
|
-
const
|
|
36
|
+
const external_strings_cjs_namespaceObject = require("./strings.cjs");
|
|
37
|
+
const ACTION_BUTTON_CLASS = 'shrink-0 rounded text-foreground-subtle opacity-0 hover:text-foreground hover:bg-surface-raised group-hover:opacity-100 group-focus-within/row:opacity-100';
|
|
38
38
|
const ACTION_TONE_CLASS = {
|
|
39
39
|
neutral: '',
|
|
40
40
|
info: 'text-info hover:text-info',
|
|
@@ -65,7 +65,7 @@ function RowActions({ node, actions, maxInline, meta }) {
|
|
|
65
65
|
})
|
|
66
66
|
}, action.id);
|
|
67
67
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("span", {
|
|
68
|
-
className: "
|
|
68
|
+
className: "flex shrink-0 items-center gap-0.5",
|
|
69
69
|
children: [
|
|
70
70
|
inline.filter((action)=>'start' === action.placement).map(renderInline),
|
|
71
71
|
null != meta && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button } from "../button.js";
|
|
3
|
-
import { cn } from "../../../lib/index.js";
|
|
4
|
-
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../dropdown-menu.js";
|
|
5
2
|
import { MoreHorizontal } from "lucide-react";
|
|
6
3
|
import { useState } from "react";
|
|
7
|
-
import {
|
|
4
|
+
import { Button } from "../button.js";
|
|
5
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../dropdown-menu.js";
|
|
6
|
+
import { cn } from "../../../lib/index.js";
|
|
8
7
|
import { JsonTreeTooltip } from "./JsonTreeTooltip.js";
|
|
9
|
-
|
|
8
|
+
import { useJsonTreeViewStrings } from "./strings.js";
|
|
9
|
+
const ACTION_BUTTON_CLASS = 'shrink-0 rounded text-foreground-subtle opacity-0 hover:text-foreground hover:bg-surface-raised group-hover:opacity-100 group-focus-within/row:opacity-100';
|
|
10
10
|
const ACTION_TONE_CLASS = {
|
|
11
11
|
neutral: '',
|
|
12
12
|
info: 'text-info hover:text-info',
|
|
@@ -37,7 +37,7 @@ function RowActions({ node, actions, maxInline, meta }) {
|
|
|
37
37
|
})
|
|
38
38
|
}, action.id);
|
|
39
39
|
return /*#__PURE__*/ jsxs("span", {
|
|
40
|
-
className: "
|
|
40
|
+
className: "flex shrink-0 items-center gap-0.5",
|
|
41
41
|
children: [
|
|
42
42
|
inline.filter((action)=>'start' === action.placement).map(renderInline),
|
|
43
43
|
null != meta && /*#__PURE__*/ jsx("span", {
|
|
@@ -246,12 +246,31 @@ function flattenJsonTree(nodes, options = {}, depth = 0) {
|
|
|
246
246
|
if (filterPredicate && !selfPredicateMatch && !predicateMatches?.below.has(node)) continue;
|
|
247
247
|
rows.push({
|
|
248
248
|
node,
|
|
249
|
-
depth: nodeDepth
|
|
249
|
+
depth: nodeDepth,
|
|
250
|
+
posInSet: 0,
|
|
251
|
+
setSize: 0
|
|
250
252
|
});
|
|
251
253
|
if (node.children && !isPathCollapsed(collapsed, node.path)) pushChildren(node.children, nodeDepth + 1, selfQueryMatch ? '' : query, selfPredicateMatch ? void 0 : filterPredicate);
|
|
252
254
|
}
|
|
255
|
+
numberSiblingSets(rows, depth);
|
|
253
256
|
return rows;
|
|
254
257
|
}
|
|
258
|
+
function numberSiblingSets(rows, baseDepth) {
|
|
259
|
+
const openSets = [];
|
|
260
|
+
const close = (set)=>{
|
|
261
|
+
for (const [position, row] of set.entries()){
|
|
262
|
+
row.posInSet = position + 1;
|
|
263
|
+
row.setSize = set.length;
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
for (const row of rows){
|
|
267
|
+
const level = row.depth - baseDepth;
|
|
268
|
+
for (const set of openSets.splice(level + 1))close(set);
|
|
269
|
+
openSets[level] ??= [];
|
|
270
|
+
openSets[level].push(row);
|
|
271
|
+
}
|
|
272
|
+
for (const set of openSets)close(set);
|
|
273
|
+
}
|
|
255
274
|
function collectContainerPaths(nodes, depth = 0) {
|
|
256
275
|
const paths = [];
|
|
257
276
|
const stack = [];
|
|
@@ -37,6 +37,10 @@ export declare function isArrayItemTemplateRoot(node: JsonTreeNode): boolean;
|
|
|
37
37
|
export interface FlatJsonTreeRow {
|
|
38
38
|
node: JsonTreeNode;
|
|
39
39
|
depth: number;
|
|
40
|
+
/** 1-based position among the visible siblings (`aria-posinset`). */
|
|
41
|
+
posInSet: number;
|
|
42
|
+
/** Number of visible siblings, this row included (`aria-setsize`). */
|
|
43
|
+
setSize: number;
|
|
40
44
|
}
|
|
41
45
|
/** Consumer display texts for a node, so search can match them alongside the raw key. */
|
|
42
46
|
export type NodeDisplayTexts = (node: JsonTreeNode) => {
|
|
@@ -206,12 +206,31 @@ function flattenJsonTree(nodes, options = {}, depth = 0) {
|
|
|
206
206
|
if (filterPredicate && !selfPredicateMatch && !predicateMatches?.below.has(node)) continue;
|
|
207
207
|
rows.push({
|
|
208
208
|
node,
|
|
209
|
-
depth: nodeDepth
|
|
209
|
+
depth: nodeDepth,
|
|
210
|
+
posInSet: 0,
|
|
211
|
+
setSize: 0
|
|
210
212
|
});
|
|
211
213
|
if (node.children && !isPathCollapsed(collapsed, node.path)) pushChildren(node.children, nodeDepth + 1, selfQueryMatch ? '' : query, selfPredicateMatch ? void 0 : filterPredicate);
|
|
212
214
|
}
|
|
215
|
+
numberSiblingSets(rows, depth);
|
|
213
216
|
return rows;
|
|
214
217
|
}
|
|
218
|
+
function numberSiblingSets(rows, baseDepth) {
|
|
219
|
+
const openSets = [];
|
|
220
|
+
const close = (set)=>{
|
|
221
|
+
for (const [position, row] of set.entries()){
|
|
222
|
+
row.posInSet = position + 1;
|
|
223
|
+
row.setSize = set.length;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
for (const row of rows){
|
|
227
|
+
const level = row.depth - baseDepth;
|
|
228
|
+
for (const set of openSets.splice(level + 1))close(set);
|
|
229
|
+
openSets[level] ??= [];
|
|
230
|
+
openSets[level].push(row);
|
|
231
|
+
}
|
|
232
|
+
for (const set of openSets)close(set);
|
|
233
|
+
}
|
|
215
234
|
function collectContainerPaths(nodes, depth = 0) {
|
|
216
235
|
const paths = [];
|
|
217
236
|
const stack = [];
|
|
@@ -33,6 +33,7 @@ const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
|
33
33
|
const external_react_namespaceObject = require("react");
|
|
34
34
|
const index_cjs_namespaceObject = require("../../../lib/index.cjs");
|
|
35
35
|
const DEFAULT_JSON_TREE_VIEW_STRINGS = {
|
|
36
|
+
treeLabel: 'JSON fields',
|
|
36
37
|
arrayItem: 'item',
|
|
37
38
|
emptySearch: 'No fields match your search.',
|
|
38
39
|
emptyDefault: 'No fields to display.',
|
|
@@ -43,6 +44,7 @@ const DEFAULT_JSON_TREE_VIEW_STRINGS = {
|
|
|
43
44
|
requiredMarker: 'required',
|
|
44
45
|
referenceType: (typeLabel)=>`${typeLabel} · reference`,
|
|
45
46
|
pathCopied: 'Path copied',
|
|
47
|
+
valueCopied: 'Value copied',
|
|
46
48
|
copyPathHint: 'Click to copy this path',
|
|
47
49
|
copyPathFor: (path)=>`Copy path for ${path}`,
|
|
48
50
|
wrapValue: 'Wrap value',
|
|
@@ -6,6 +6,12 @@ import { type ReactNode } from 'react';
|
|
|
6
6
|
* `DEFAULT_JSON_TREE_VIEW_STRINGS`.
|
|
7
7
|
*/
|
|
8
8
|
export interface JsonTreeViewStrings {
|
|
9
|
+
/**
|
|
10
|
+
* Accessible name of the tree grid when the host passes no `aria-label` or
|
|
11
|
+
* `aria-labelledby`. Optional so catalogs written before it was added still
|
|
12
|
+
* type-check; falls back to the English default.
|
|
13
|
+
*/
|
|
14
|
+
treeLabel?: string;
|
|
9
15
|
/** Label for the synthesized array-item preview row. */
|
|
10
16
|
arrayItem: string;
|
|
11
17
|
emptySearch: string;
|
|
@@ -22,7 +28,13 @@ export interface JsonTreeViewStrings {
|
|
|
22
28
|
* back to the English default.
|
|
23
29
|
*/
|
|
24
30
|
referenceType?: (typeLabel: string) => string;
|
|
31
|
+
/** Announced to screen readers after a path is copied. */
|
|
25
32
|
pathCopied: string;
|
|
33
|
+
/**
|
|
34
|
+
* Announced to screen readers after a value is copied. Optional so catalogs
|
|
35
|
+
* written before it was added still type-check; falls back to the English default.
|
|
36
|
+
*/
|
|
37
|
+
valueCopied?: string;
|
|
26
38
|
copyPathHint: string;
|
|
27
39
|
copyPathFor: (path: string) => string;
|
|
28
40
|
wrapValue: string;
|
|
@@ -2,6 +2,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { createContext, useContext, useMemo } from "react";
|
|
3
3
|
import { cn } from "../../../lib/index.js";
|
|
4
4
|
const DEFAULT_JSON_TREE_VIEW_STRINGS = {
|
|
5
|
+
treeLabel: 'JSON fields',
|
|
5
6
|
arrayItem: 'item',
|
|
6
7
|
emptySearch: 'No fields match your search.',
|
|
7
8
|
emptyDefault: 'No fields to display.',
|
|
@@ -12,6 +13,7 @@ const DEFAULT_JSON_TREE_VIEW_STRINGS = {
|
|
|
12
13
|
requiredMarker: 'required',
|
|
13
14
|
referenceType: (typeLabel)=>`${typeLabel} · reference`,
|
|
14
15
|
pathCopied: 'Path copied',
|
|
16
|
+
valueCopied: 'Value copied',
|
|
15
17
|
copyPathHint: 'Click to copy this path',
|
|
16
18
|
copyPathFor: (path)=>`Copy path for ${path}`,
|
|
17
19
|
wrapValue: 'Wrap value',
|
|
@@ -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 {};
|