@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
@@ -1,18 +1,19 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useVirtualizer } from "@tanstack/react-virtual";
3
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { cn } from "../../../lib/index.js";
5
5
  import { copyTextToClipboard } from "../../../lib/clipboard.js";
6
+ import { useIsomorphicLayoutEffect } from "../../../lib/use-isomorphic-layout-effect.js";
6
7
  import { flattenJsonTree } from "./buildJsonTree.js";
7
8
  import { JsonTreeRow, JsonTreeRowContextProvider, ROW_MIN_HEIGHT_PX } from "./JsonTreeRow.js";
8
9
  import { JsonTreeTooltipProvider } from "./JsonTreeTooltip.js";
9
10
  import { JsonTreeViewProvider, useJsonTreeViewStrings } from "./strings.js";
10
- const useIsomorphicLayoutEffect = "u" < typeof window ? useEffect : useLayoutEffect;
11
+ import { useTreeGrid } from "./treeGrid.js";
11
12
  const VIRTUAL_OVERSCAN = 10;
12
13
  function scrollMarginOf(element, scrollElement) {
13
14
  return Math.round(element.getBoundingClientRect().top - scrollElement.getBoundingClientRect().top + scrollElement.scrollTop);
14
15
  }
15
- function VirtualRows({ rows, container, scrollElement, pinnedPaths }) {
16
+ function VirtualRows({ rows, indexByPath, container, scrollElement, pinnedPaths, gridProps }) {
16
17
  const [scrollMargin, setScrollMargin] = useState(0);
17
18
  const getItemKey = useCallback((index)=>rows[index]?.node.path ?? index, [
18
19
  rows
@@ -34,21 +35,11 @@ function VirtualRows({ rows, container, scrollElement, pinnedPaths }) {
34
35
  const next = scrollMarginOf(container, scrollElement);
35
36
  if (next !== scrollMargin) setScrollMargin(next);
36
37
  });
37
- const isPinning = pinnedPaths.length > 0;
38
- const indexByPath = useMemo(()=>{
39
- if (!isPinning) return;
40
- const byPath = new Map();
41
- for (const [index, row] of rows.entries())byPath.set(row.node.path, index);
42
- return byPath;
43
- }, [
44
- isPinning,
45
- rows
46
- ]);
47
38
  const items = virtualizer.getVirtualItems();
48
39
  const firstWindowed = items[0]?.index ?? -1;
49
40
  const lastWindowed = items[items.length - 1]?.index ?? -2;
50
41
  const pinnedItems = [];
51
- if (indexByPath) for (const path of pinnedPaths){
42
+ for (const path of pinnedPaths){
52
43
  const index = indexByPath.get(path);
53
44
  if (void 0 === index || index >= firstWindowed && index <= lastWindowed) continue;
54
45
  const measurement = virtualizer.measurementsCache[index];
@@ -60,6 +51,7 @@ function VirtualRows({ rows, container, scrollElement, pinnedPaths }) {
60
51
  ...pinnedItems.filter((item)=>item.index > lastWindowed)
61
52
  ];
62
53
  return /*#__PURE__*/ jsx("div", {
54
+ ...gridProps,
63
55
  className: "relative",
64
56
  style: {
65
57
  height: virtualizer.getTotalSize()
@@ -75,8 +67,8 @@ function VirtualRows({ rows, container, scrollElement, pinnedPaths }) {
75
67
  transform: `translateY(${item.start - virtualizer.options.scrollMargin}px)`
76
68
  },
77
69
  children: /*#__PURE__*/ jsx(JsonTreeRow, {
78
- node: row.node,
79
- depth: row.depth
70
+ row: row,
71
+ index: item.index
80
72
  })
81
73
  }, item.key);
82
74
  })
@@ -102,7 +94,7 @@ function JsonTreeView({ strings, tooltipContentClassName, ...props }) {
102
94
  })
103
95
  });
104
96
  }
105
- function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query, filterPredicate, readOnly = false, onEdit, rowWrapper, decorateNode, deriveTypeIcon, renderValue, nodeActions, maxInlineActions = 3, renderCodeEditor, pathForCopy, onCopy, virtualized = false, scrollElement, emptyMessage, className }) {
97
+ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query, filterPredicate, readOnly = false, onEdit, rowWrapper, decorateNode, deriveTypeIcon, renderValue, nodeActions, maxInlineActions = 3, renderCodeEditor, pathForCopy, onCopy, virtualized = false, scrollElement, emptyMessage, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, className }) {
106
98
  const strings = useJsonTreeViewStrings();
107
99
  const [container, setContainer] = useState(null);
108
100
  const usesAncestorScroller = virtualized && !!scrollElement;
@@ -110,15 +102,6 @@ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query,
110
102
  const [editingPath, setEditingPath] = useState(null);
111
103
  const [jsonEditingPath, setJsonEditingPath] = useState(null);
112
104
  const [wrappedPaths, setWrappedPaths] = useState({});
113
- const pinnedPaths = useMemo(()=>[
114
- ...new Set([
115
- editingPath,
116
- jsonEditingPath
117
- ].filter((path)=>null !== path))
118
- ], [
119
- editingPath,
120
- jsonEditingPath
121
- ]);
122
105
  const [copied, setCopied] = useState(null);
123
106
  const copyTimerRef = useRef(null);
124
107
  useEffect(()=>()=>{
@@ -127,10 +110,11 @@ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query,
127
110
  const copy = (node, kind, text)=>{
128
111
  copyTextToClipboard(text).then((ok)=>{
129
112
  if (!ok) return;
130
- setCopied({
131
- path: node.path,
132
- kind
133
- });
113
+ setCopied((prev)=>({
114
+ path: node.path,
115
+ kind,
116
+ id: (prev?.id ?? 0) + 1
117
+ }));
134
118
  if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
135
119
  copyTimerRef.current = setTimeout(()=>setCopied(null), 1500);
136
120
  onCopy?.({
@@ -163,6 +147,37 @@ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query,
163
147
  filterPredicate,
164
148
  decorateNode
165
149
  ]);
150
+ const indexByPath = useMemo(()=>new Map(rows.map((row, index)=>[
151
+ row.node.path,
152
+ index
153
+ ])), [
154
+ rows
155
+ ]);
156
+ const { activePath, gridHandlers, trackEditor } = useTreeGrid({
157
+ rows,
158
+ indexByPath,
159
+ collapsed,
160
+ toggle: onToggleCollapsed
161
+ });
162
+ const pinnedPaths = useMemo(()=>[
163
+ ...new Set([
164
+ editingPath,
165
+ jsonEditingPath,
166
+ activePath
167
+ ].filter((path)=>null !== path))
168
+ ], [
169
+ editingPath,
170
+ jsonEditingPath,
171
+ activePath
172
+ ]);
173
+ const gridProps = {
174
+ ...gridHandlers,
175
+ role: 'treegrid',
176
+ 'aria-label': ariaLabelledBy ? void 0 : ariaLabel ?? strings.treeLabel,
177
+ 'aria-labelledby': ariaLabelledBy,
178
+ 'aria-readonly': !canEdit || void 0,
179
+ 'aria-rowcount': rows.length
180
+ };
166
181
  const templateItemLabel = strings.arrayItem;
167
182
  const filtering = !!query?.trim() || !!filterPredicate;
168
183
  const resolvedEmptyMessage = filtering ? strings.emptySearch : emptyMessage ?? strings.emptyDefault;
@@ -184,8 +199,9 @@ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query,
184
199
  jsonEditingPath,
185
200
  wrappedPaths,
186
201
  copied,
187
- setEditingPath,
188
- setJsonEditingPath,
202
+ activePath,
203
+ setEditingPath: trackEditor('leaf', setEditingPath),
204
+ setJsonEditingPath: trackEditor('json', setJsonEditingPath),
189
205
  copyPath,
190
206
  copyValue,
191
207
  toggleWrapped,
@@ -198,15 +214,27 @@ function JsonTreeViewContent({ nodes, collapsed = {}, onToggleCollapsed, query,
198
214
  ref: setContainer,
199
215
  className: cn(usesAncestorScroller ? 'overflow-x-clip' : 'h-full overflow-y-auto overflow-x-hidden', virtualized && !usesAncestorScroller && 'max-h-screen', virtualized && '[overflow-anchor:none]', className),
200
216
  children: [
201
- virtualized ? /*#__PURE__*/ jsx(VirtualRows, {
217
+ /*#__PURE__*/ jsx("span", {
218
+ role: "status",
219
+ className: "sr-only",
220
+ children: copied && /*#__PURE__*/ jsx("span", {
221
+ children: 'path' === copied.kind ? strings.pathCopied : strings.valueCopied
222
+ }, copied.id)
223
+ }),
224
+ rows.length > 0 && (virtualized ? /*#__PURE__*/ jsx(VirtualRows, {
202
225
  rows: rows,
226
+ indexByPath: indexByPath,
203
227
  container: container,
204
228
  scrollElement: scrollElement,
205
- pinnedPaths: pinnedPaths
206
- }) : rows.map(({ node, depth })=>/*#__PURE__*/ jsx(JsonTreeRow, {
207
- node: node,
208
- depth: depth
209
- }, node.path)),
229
+ pinnedPaths: pinnedPaths,
230
+ gridProps: gridProps
231
+ }) : /*#__PURE__*/ jsx("div", {
232
+ ...gridProps,
233
+ children: rows.map((row, index)=>/*#__PURE__*/ jsx(JsonTreeRow, {
234
+ row: row,
235
+ index: index
236
+ }, row.node.path))
237
+ })),
210
238
  0 === rows.length && /*#__PURE__*/ jsx("span", {
211
239
  className: "p-4 text-center text-xs text-foreground-subtle",
212
240
  children: resolvedEmptyMessage
@@ -248,9 +248,14 @@ export interface JsonTreeChange {
248
248
  previous?: JsonValue;
249
249
  }
250
250
  /**
251
- * Props passed to a custom row container. The wrapper IS the row element:
251
+ * Props passed to a custom row container. The wrapper is the row's visual line:
252
252
  * render a single container applying `className`/`style` and `children`
253
253
  * verbatim, plus whatever behavior you attach (e.g. dnd-kit drag listeners).
254
+ *
255
+ * It renders inside the tree grid's `row` element, which owns the row's role
256
+ * and keyboard focus, so don't give the wrapper a role or tabindex. dnd-kit's
257
+ * `attributes` add both (`role="button"`, `tabIndex={0}`); spread only its
258
+ * `listeners`.
254
259
  */
255
260
  export interface JsonTreeRowWrapperProps {
256
261
  node: JsonTreeNode;
@@ -29,11 +29,10 @@ __webpack_require__.d(__webpack_exports__, {
29
29
  ROW_MIN_HEIGHT_PX: ()=>ROW_MIN_HEIGHT_PX
30
30
  });
31
31
  const jsx_runtime_namespaceObject = require("react/jsx-runtime");
32
- const index_cjs_namespaceObject = require("../../../lib/index.cjs");
33
- const external_label_cjs_namespaceObject = require("../label.cjs");
34
32
  const external_lucide_react_namespaceObject = require("lucide-react");
35
33
  const external_react_namespaceObject = require("react");
36
- const external_strings_cjs_namespaceObject = require("./strings.cjs");
34
+ const external_label_cjs_namespaceObject = require("../label.cjs");
35
+ const index_cjs_namespaceObject = require("../../../lib/index.cjs");
37
36
  const external_buildJsonTree_cjs_namespaceObject = require("./buildJsonTree.cjs");
38
37
  const external_DecorationChip_cjs_namespaceObject = require("./DecorationChip.cjs");
39
38
  const external_JsonContainerEditor_cjs_namespaceObject = require("./JsonContainerEditor.cjs");
@@ -42,15 +41,30 @@ const external_JsonTypeBadge_cjs_namespaceObject = require("./JsonTypeBadge.cjs"
42
41
  const external_NodeKey_cjs_namespaceObject = require("./NodeKey.cjs");
43
42
  const external_RowActions_cjs_namespaceObject = require("./RowActions.cjs");
44
43
  const external_ScalarValueCell_cjs_namespaceObject = require("./ScalarValueCell.cjs");
44
+ const external_strings_cjs_namespaceObject = require("./strings.cjs");
45
+ const external_treeGrid_cjs_namespaceObject = require("./treeGrid.cjs");
45
46
  const ROW_CLASS = 'group flex min-h-7 cursor-default items-center gap-2 py-1 pr-1 transition hover:bg-surface-overlay';
46
47
  const ROW_MIN_HEIGHT_PX = 28;
47
48
  const VALUE_CELL_CLASS = 'flex min-w-8 flex-1 items-center';
49
+ const NAME_CELL_CLASS = 'flex min-w-0 max-w-1/2 items-center gap-2';
50
+ const FOCUS_RING_CLASS = 'outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring';
51
+ const ROW_ELEMENT_CLASS = `group/row ${FOCUS_RING_CLASS}`;
48
52
  function rowIndent(depth, extra = 0) {
49
53
  return {
50
54
  paddingLeft: `${8 + 16 * depth + extra}px`
51
55
  };
52
56
  }
53
57
  const KEY_ALIGN_OFFSET = 44;
58
+ function GridCell({ cell, editing = false, className, ...props }) {
59
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
60
+ role: "gridcell",
61
+ "data-cell": cell,
62
+ tabIndex: -1,
63
+ "data-json-tree-editor": editing ? '' : void 0,
64
+ className: (0, index_cjs_namespaceObject.cn)(FOCUS_RING_CLASS, className),
65
+ ...props
66
+ });
67
+ }
54
68
  const JsonTreeRowContext = /*#__PURE__*/ (0, external_react_namespaceObject.createContext)(null);
55
69
  const JsonTreeRowContextProvider = JsonTreeRowContext.Provider;
56
70
  function useJsonTreeRowContext() {
@@ -58,9 +72,11 @@ function useJsonTreeRowContext() {
58
72
  if (!ctx) throw new Error('JsonTreeRow must be rendered inside a JsonTreeRowContext provider');
59
73
  return ctx;
60
74
  }
61
- function JsonTreeRow({ node, depth }) {
75
+ function JsonTreeRow({ row, index }) {
76
+ const { node, depth } = row;
62
77
  const strings = (0, external_strings_cjs_namespaceObject.useJsonTreeViewStrings)();
63
- const { collapsed, onToggleCollapsed, readOnly, decorateNode, deriveTypeIcon, renderValue, nodeActions, maxInlineActions, renderCodeEditor, pathForCopy, canEdit, RowWrapper, templateItemLabel, editingPath, jsonEditingPath, wrappedPaths, copied, setEditingPath, setJsonEditingPath, copyPath, copyValue, toggleWrapped, commitEdit } = useJsonTreeRowContext();
78
+ const { collapsed, onToggleCollapsed, readOnly, decorateNode, deriveTypeIcon, renderValue, nodeActions, maxInlineActions, renderCodeEditor, pathForCopy, canEdit, RowWrapper, templateItemLabel, editingPath, jsonEditingPath, wrappedPaths, copied, activePath, setEditingPath, setJsonEditingPath, copyPath, copyValue, toggleWrapped, commitEdit } = useJsonTreeRowContext();
79
+ const isTabStop = activePath === node.path;
64
80
  const buildDefaultActions = (node, flags)=>{
65
81
  const actions = [];
66
82
  if (flags.wrappable) actions.push({
@@ -127,7 +143,20 @@ function JsonTreeRow({ node, depth }) {
127
143
  if (event.target.closest('button, a, input, textarea, select, [contenteditable="true"]')) return;
128
144
  onToggleCollapsed?.(node.path);
129
145
  };
146
+ const collapsedHere = isContainer && (0, external_buildJsonTree_cjs_namespaceObject.isPathCollapsed)(collapsed, node.path);
147
+ const editingInline = editingPath === node.path && !wrapped;
148
+ const showsValue = !isContainer && !wrapped && !decoration?.hideValue && (null != customCell || !(readOnly && void 0 === node.value || isTemplate));
149
+ const editingDetail = wrapped && editingPath === node.path && canEdit || isContainer && jsonEditingPath === node.path;
130
150
  return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
151
+ role: "row",
152
+ "data-path": node.path,
153
+ tabIndex: isTabStop ? 0 : -1,
154
+ "aria-level": depth + 1,
155
+ "aria-posinset": row.posInSet,
156
+ "aria-setsize": row.setSize,
157
+ "aria-rowindex": index + 1,
158
+ "aria-expanded": (0, external_treeGrid_cjs_namespaceObject.isParentRow)(row) ? !collapsedHere : void 0,
159
+ className: ROW_ELEMENT_CLASS,
131
160
  children: [
132
161
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(RowWrapper, {
133
162
  node: node,
@@ -135,48 +164,56 @@ function JsonTreeRow({ node, depth }) {
135
164
  style: rowIndent(depth),
136
165
  onClick: rowClickable ? handleRowClick : void 0,
137
166
  children: [
138
- isContainer ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
139
- type: "button",
140
- onClick: ()=>onToggleCollapsed?.(node.path),
141
- disabled: !onToggleCollapsed,
142
- "aria-label": (0, external_buildJsonTree_cjs_namespaceObject.isPathCollapsed)(collapsed, node.path) ? strings.expandKey(node.key) : strings.collapseKey(node.key),
143
- "aria-expanded": !(0, external_buildJsonTree_cjs_namespaceObject.isPathCollapsed)(collapsed, node.path),
144
- className: "grid size-2.5 shrink-0 cursor-pointer place-items-center text-foreground-subtle transition hover:text-foreground disabled:cursor-default disabled:hover:text-foreground-subtle",
145
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.ChevronDown, {
146
- size: 10,
147
- className: (0, index_cjs_namespaceObject.cn)('transition-transform duration-100', (0, external_buildJsonTree_cjs_namespaceObject.isPathCollapsed)(collapsed, node.path) && '-rotate-90')
148
- })
149
- }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
150
- className: "size-2.5 shrink-0"
151
- }),
152
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_JsonTypeBadge_cjs_namespaceObject.JsonTypeBadge, {
153
- type: node.type,
154
- icon: decoration?.badge?.icon ?? deriveTypeIcon?.(node),
155
- className: decoration?.badge?.className,
156
- reference: decoration?.badge?.reference
157
- }),
158
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_NodeKey_cjs_namespaceObject.NodeKey, {
159
- node: node,
160
- label: isTemplateItem ? templateItemLabel : decoration?.label,
161
- displayPath: pathForCopy?.(node.path, node.segments) ?? node.path,
162
- onCopyPath: copyPath,
163
- className: isTemplateItem ? 'font-normal italic text-foreground-subtle' : void 0
164
- }),
165
- copied?.path === node.path && 'path' === copied.kind && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.CircleCheck, {
166
- size: 11,
167
- className: "shrink-0 text-brand",
168
- role: "img",
169
- "aria-label": strings.pathCopied
170
- }),
171
- decoration?.sublabel && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
172
- className: (0, index_cjs_namespaceObject.cn)('min-w-0 truncate font-mono text-[10px] text-foreground-subtle leading-4', decoration.sublabelOnHover && 'hidden group-hover:block group-focus-within:block'),
173
- children: decoration.sublabel
174
- }),
175
- node.required && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_label_cjs_namespaceObject.RequiredIndicator, {
176
- className: "ml-0 shrink-0 text-[10px] text-foreground",
177
- srLabel: strings.requiredMarker
167
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(GridCell, {
168
+ cell: "name",
169
+ className: NAME_CELL_CLASS,
170
+ children: [
171
+ isContainer ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("button", {
172
+ type: "button",
173
+ tabIndex: -1,
174
+ "data-json-tree-skip": "",
175
+ onClick: ()=>onToggleCollapsed?.(node.path),
176
+ disabled: !onToggleCollapsed,
177
+ "aria-label": collapsedHere ? strings.expandKey(node.key) : strings.collapseKey(node.key),
178
+ className: "grid size-2.5 shrink-0 cursor-pointer place-items-center text-foreground-subtle transition hover:text-foreground disabled:cursor-default disabled:hover:text-foreground-subtle",
179
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.ChevronDown, {
180
+ size: 10,
181
+ className: (0, index_cjs_namespaceObject.cn)('transition-transform duration-100', collapsedHere && '-rotate-90')
182
+ })
183
+ }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
184
+ className: "size-2.5 shrink-0"
185
+ }),
186
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_JsonTypeBadge_cjs_namespaceObject.JsonTypeBadge, {
187
+ type: node.type,
188
+ icon: decoration?.badge?.icon ?? deriveTypeIcon?.(node),
189
+ className: decoration?.badge?.className,
190
+ reference: decoration?.badge?.reference
191
+ }),
192
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_NodeKey_cjs_namespaceObject.NodeKey, {
193
+ node: node,
194
+ label: isTemplateItem ? templateItemLabel : decoration?.label,
195
+ displayPath: pathForCopy?.(node.path, node.segments) ?? node.path,
196
+ onCopyPath: copyPath,
197
+ className: isTemplateItem ? 'font-normal italic text-foreground-subtle' : void 0
198
+ }),
199
+ copied?.path === node.path && 'path' === copied.kind && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.CircleCheck, {
200
+ size: 11,
201
+ className: "shrink-0 text-brand",
202
+ "aria-hidden": true
203
+ }),
204
+ decoration?.sublabel && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
205
+ className: (0, index_cjs_namespaceObject.cn)('min-w-0 truncate font-mono text-[10px] text-foreground-subtle leading-4', decoration.sublabelOnHover && 'hidden group-hover:block group-focus-within/row:block'),
206
+ children: decoration.sublabel
207
+ }),
208
+ node.required && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_label_cjs_namespaceObject.RequiredIndicator, {
209
+ className: "ml-0 shrink-0 text-[10px] text-foreground",
210
+ srLabel: strings.requiredMarker
211
+ })
212
+ ]
178
213
  }),
179
- isContainer ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
214
+ isContainer ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(GridCell, {
215
+ cell: "value",
216
+ className: (0, index_cjs_namespaceObject.cn)('flex min-w-0 items-center gap-2', null != customCell && 'flex-1'),
180
217
  children: [
181
218
  !decoration?.hideCount && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
182
219
  className: "shrink-0 whitespace-nowrap font-mono italic text-[10px] text-foreground-subtle",
@@ -188,56 +225,52 @@ function JsonTreeRow({ node, depth }) {
188
225
  }),
189
226
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_DecorationChip_cjs_namespaceObject.DecorationChip, {
190
227
  decoration: decoration
191
- }),
192
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_RowActions_cjs_namespaceObject.RowActions, {
193
- node: node,
194
- actions: actions,
195
- maxInline: maxInlineActions,
196
- meta: decoration?.meta
197
228
  })
198
229
  ]
199
- }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
230
+ }) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(GridCell, {
231
+ cell: "value",
232
+ editing: editingInline,
233
+ className: (0, index_cjs_namespaceObject.cn)('flex flex-1 items-center gap-2', showsValue ? 'min-w-8' : 'min-w-0', showsValue && null == customCell && 'shrink-3'),
200
234
  children: [
201
- !wrapped && !decoration?.hideValue && (null != customCell ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
202
- className: VALUE_CELL_CLASS,
203
- children: customCell
204
- }) : !(readOnly && void 0 === node.value || isTemplate) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
235
+ showsValue && (null != customCell ? customCell : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
205
236
  children: [
206
237
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
207
238
  className: "shrink-0 font-mono text-xs text-foreground-subtle",
208
239
  children: "="
209
240
  }),
210
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
211
- className: (0, index_cjs_namespaceObject.cn)(VALUE_CELL_CLASS, 'shrink-3'),
212
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ScalarValueCell_cjs_namespaceObject.ScalarValueCell, {
213
- node: node,
214
- readOnly: readOnly,
215
- editing: editingPath === node.path,
216
- onStartEdit: (n)=>setEditingPath(n.path),
217
- onStopEdit: ()=>setEditingPath(null),
218
- onEdit: canEdit ? commitEdit : void 0
219
- })
220
- })
221
- ]
222
- })),
223
- editingPath !== node.path && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
224
- children: [
225
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_DecorationChip_cjs_namespaceObject.DecorationChip, {
226
- decoration: decoration
227
- }),
228
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_RowActions_cjs_namespaceObject.RowActions, {
241
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ScalarValueCell_cjs_namespaceObject.ScalarValueCell, {
229
242
  node: node,
230
- actions: actions,
231
- maxInline: maxInlineActions,
232
- meta: decoration?.meta
243
+ readOnly: readOnly,
244
+ editing: editingPath === node.path,
245
+ onStartEdit: (n)=>setEditingPath(n.path),
246
+ onStopEdit: ()=>setEditingPath(null),
247
+ onEdit: canEdit ? commitEdit : void 0
233
248
  })
234
249
  ]
250
+ })),
251
+ editingPath !== node.path && decoration?.chip && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("span", {
252
+ className: "ml-auto flex min-w-0 items-center",
253
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_DecorationChip_cjs_namespaceObject.DecorationChip, {
254
+ decoration: decoration
255
+ })
235
256
  })
236
257
  ]
258
+ }),
259
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(GridCell, {
260
+ cell: "actions",
261
+ className: "ml-auto flex shrink-0 items-center gap-2",
262
+ children: (isContainer || editingPath !== node.path) && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_RowActions_cjs_namespaceObject.RowActions, {
263
+ node: node,
264
+ actions: actions,
265
+ maxInline: maxInlineActions,
266
+ meta: decoration?.meta
267
+ })
237
268
  })
238
269
  ]
239
270
  }),
240
- wrapped && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
271
+ wrapped && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(GridCell, {
272
+ cell: "detail",
273
+ editing: editingDetail,
241
274
  className: "pb-1.5 pr-3.5",
242
275
  style: rowIndent(depth, KEY_ALIGN_OFFSET),
243
276
  children: editingPath === node.path && canEdit ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_JsonMultilineLeafEditor_cjs_namespaceObject.JsonMultilineLeafEditor, {
@@ -259,7 +292,9 @@ function JsonTreeRow({ node, depth }) {
259
292
  })
260
293
  })
261
294
  }),
262
- isContainer && jsonEditingPath === node.path && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
295
+ isContainer && jsonEditingPath === node.path && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(GridCell, {
296
+ cell: "detail",
297
+ editing: true,
263
298
  className: "py-1.5 pr-3.5",
264
299
  style: rowIndent(depth, KEY_ALIGN_OFFSET),
265
300
  children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_JsonContainerEditor_cjs_namespaceObject.JsonContainerEditor, {
@@ -1,11 +1,19 @@
1
+ import { type FlatJsonTreeRow } from './buildJsonTree';
1
2
  import type { CopyEvent, DeriveTypeIcon, JsonTreeNode, JsonTreeRowWrapper, JsonValue, NodeActionsResolver, NodeDecoration, PathForCopy, RenderCodeEditor, RenderValueCell } from './JsonTree.types';
2
3
  /** `min-h-7` above (1.75rem) in px at the default root size: the virtualizer's estimate
3
4
  * until each row is measured, so a different root size costs accuracy but not correctness. */
4
5
  export declare const ROW_MIN_HEIGHT_PX = 28;
6
+ /** The last copy, for the inline confirmation and the tree's announcement. */
7
+ export interface JsonTreeCopyState {
8
+ path: string;
9
+ kind: CopyEvent['kind'];
10
+ /** Re-keys the announcement, so copying twice in a row is heard twice. */
11
+ id: number;
12
+ }
5
13
  /**
6
14
  * Shared, node-invariant context every row needs: the tree config, the mutable
7
15
  * edit/copy state, and the handlers that mutate it. Held once by `JsonTreeView` so
8
- * each `JsonTreeRow` only takes its own `node`/`depth`.
16
+ * each `JsonTreeRow` only takes its own `row` and `index`.
9
17
  */
10
18
  export interface JsonTreeRowContextValue {
11
19
  collapsed: Record<string, boolean>;
@@ -26,10 +34,10 @@ export interface JsonTreeRowContextValue {
26
34
  editingPath: string | null;
27
35
  jsonEditingPath: string | null;
28
36
  wrappedPaths: Record<string, boolean>;
29
- copied: {
30
- path: string;
31
- kind: CopyEvent['kind'];
32
- } | null;
37
+ copied: JsonTreeCopyState | null;
38
+ /** The row holding the tree's single Tab stop. */
39
+ activePath: string | null;
40
+ /** Opening and closing an editor through these also moves focus into and back out of it. */
33
41
  setEditingPath: (path: string | null) => void;
34
42
  setJsonEditingPath: (path: string | null) => void;
35
43
  copyPath: (node: JsonTreeNode) => void;
@@ -44,7 +52,7 @@ export declare const JsonTreeRowContextProvider: import("react").Provider<JsonTr
44
52
  * plus the expanded wrapped-scalar and edit-as-JSON surfaces below it. All
45
53
  * shared state and handlers come from `JsonTreeRowContext`.
46
54
  */
47
- export declare function JsonTreeRow({ node, depth }: {
48
- node: JsonTreeNode;
49
- depth: number;
55
+ export declare function JsonTreeRow({ row, index }: {
56
+ row: FlatJsonTreeRow;
57
+ index: number;
50
58
  }): import("react/jsx-runtime").JSX.Element;