@harborclient/sdk 1.3.4 → 1.3.6

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 (58) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/components/Breadcrumb/SegmentShell.d.ts +12 -1
  3. package/dist/components/Breadcrumb/SegmentShell.d.ts.map +1 -1
  4. package/dist/components/Breadcrumb/SegmentShell.js +7 -5
  5. package/dist/components/Button/index.d.ts +2 -2
  6. package/dist/components/Button/index.d.ts.map +1 -1
  7. package/dist/components/Button/index.js +2 -1
  8. package/dist/components/CodeEditor/index.d.ts +7 -4
  9. package/dist/components/CodeEditor/index.d.ts.map +1 -1
  10. package/dist/components/CodeEditor/index.js +15 -176
  11. package/dist/components/CodeEditor/selectionActionToolbar.d.ts +162 -0
  12. package/dist/components/CodeEditor/selectionActionToolbar.d.ts.map +1 -0
  13. package/dist/components/CodeEditor/selectionActionToolbar.js +319 -0
  14. package/dist/components/CopyToChatButton/constants.d.ts +18 -0
  15. package/dist/components/CopyToChatButton/constants.d.ts.map +1 -0
  16. package/dist/components/CopyToChatButton/constants.js +19 -0
  17. package/dist/components/CopyToChatButton/index.d.ts +49 -0
  18. package/dist/components/CopyToChatButton/index.d.ts.map +1 -0
  19. package/dist/components/CopyToChatButton/index.js +43 -0
  20. package/dist/components/FloatingDialog/floatingDialogPosition.d.ts +52 -0
  21. package/dist/components/FloatingDialog/floatingDialogPosition.d.ts.map +1 -0
  22. package/dist/components/FloatingDialog/floatingDialogPosition.js +33 -0
  23. package/dist/components/FloatingDialog/index.d.ts +99 -0
  24. package/dist/components/FloatingDialog/index.d.ts.map +1 -0
  25. package/dist/components/FloatingDialog/index.js +279 -0
  26. package/dist/components/PageHeader/index.d.ts +2 -1
  27. package/dist/components/PageHeader/index.d.ts.map +1 -1
  28. package/dist/components/PageHeader/index.js +3 -2
  29. package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts +42 -4
  30. package/dist/components/SidebarItem/SidebarEnvironmentItem.d.ts.map +1 -1
  31. package/dist/components/SidebarItem/SidebarEnvironmentItem.js +34 -5
  32. package/dist/components/SidebarItem/SidebarRequestItem.d.ts +5 -1
  33. package/dist/components/SidebarItem/SidebarRequestItem.d.ts.map +1 -1
  34. package/dist/components/SidebarItem/SidebarRequestItem.js +2 -2
  35. package/dist/components/SidebarItem/SidebarWorkspaceItem.d.ts +9 -1
  36. package/dist/components/SidebarItem/SidebarWorkspaceItem.d.ts.map +1 -1
  37. package/dist/components/SidebarItem/SidebarWorkspaceItem.js +15 -2
  38. package/dist/components/TabBar/TabContextMenu.d.ts +3 -0
  39. package/dist/components/TabBar/TabContextMenu.d.ts.map +1 -1
  40. package/dist/components/TabBar/TabContextMenu.js +25 -16
  41. package/dist/components/VariableTable/index.d.ts +1 -1
  42. package/dist/components/VariableTable/index.d.ts.map +1 -1
  43. package/dist/components/VariableTable/index.js +14 -3
  44. package/dist/components/index.d.ts +4 -2
  45. package/dist/components/index.d.ts.map +1 -1
  46. package/dist/components/index.js +3 -1
  47. package/dist/runtime/createBridgedPluginContext.js +74 -0
  48. package/dist/snippets.d.ts +26 -2
  49. package/dist/styles.css +16 -0
  50. package/dist/types.d.ts +273 -1
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/ui/index.d.ts +1 -0
  53. package/dist/ui/index.d.ts.map +1 -1
  54. package/dist/ui/index.js +1 -0
  55. package/package.json +1 -1
  56. package/dist/components/SelectionActionToolbar/index.d.ts +0 -41
  57. package/dist/components/SelectionActionToolbar/index.d.ts.map +0 -1
  58. package/dist/components/SelectionActionToolbar/index.js +0 -13
@@ -0,0 +1,279 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from '@harborclient/sdk/react';
3
+ import { cn } from '../utils.js';
4
+ import { FLOATING_DIALOG_DEFAULT_LEFT, FLOATING_DIALOG_DEFAULT_TOP, FLOATING_DIALOG_VIEWPORT_MARGIN_PX, isFloatingDialogFullyOnScreen } from './floatingDialogPosition.js';
5
+ /**
6
+ * Clamps a proposed size into min/max and remaining viewport space.
7
+ *
8
+ * @param width - Proposed width.
9
+ * @param height - Proposed height.
10
+ * @param left - Current panel left.
11
+ * @param top - Current panel top.
12
+ * @param minWidth - Minimum width.
13
+ * @param minHeight - Minimum height.
14
+ * @param maxWidth - Optional max width cap.
15
+ * @param maxHeight - Optional max height cap.
16
+ * @returns Clamped size.
17
+ */
18
+ function clampFloatingDialogSize(width, height, left, top, minWidth, minHeight, maxWidth, maxHeight) {
19
+ const margin = FLOATING_DIALOG_VIEWPORT_MARGIN_PX;
20
+ const viewportWidth = typeof window !== 'undefined' ? window.innerWidth : width;
21
+ const viewportHeight = typeof window !== 'undefined' ? window.innerHeight : height;
22
+ const roomWidth = Math.max(minWidth, viewportWidth - left - margin);
23
+ const roomHeight = Math.max(minHeight, viewportHeight - top - margin);
24
+ const widthCap = maxWidth != null ? Math.min(maxWidth, roomWidth) : roomWidth;
25
+ const heightCap = maxHeight != null ? Math.min(maxHeight, roomHeight) : roomHeight;
26
+ return {
27
+ width: Math.min(Math.max(width, minWidth), widthCap),
28
+ height: Math.min(Math.max(height, minHeight), heightCap)
29
+ };
30
+ }
31
+ /**
32
+ * Non-blocking, draggable dialog panel with no modal mask.
33
+ *
34
+ * Clicks pass through to the UI behind the panel. Drag by the handle region.
35
+ * When `initialWidth` and `initialHeight` are provided, a southeast resize
36
+ * handle appears (pointer + arrow-key accessible). Parents persist geometry via
37
+ * `onPositionChange` / `onSizeChange`. If the panel would open or remain
38
+ * off-screen after a window resize, it relocates to the default corner.
39
+ *
40
+ * Uses the elevated `bg-control` fill (not `bg-surface`) with a stronger border
41
+ * and theme-aware shadow so the panel stays readable against the app chrome in
42
+ * both light and dark themes.
43
+ *
44
+ * @param props - Dialog labelling, geometry, and content props.
45
+ * @returns Floating dialog element.
46
+ */
47
+ export function FloatingDialog({ label, labelledBy, onClose, disableEscape = false, className, bodyClassName, initialLeft = FLOATING_DIALOG_DEFAULT_LEFT, initialTop = FLOATING_DIALOG_DEFAULT_TOP, onPositionChange, initialWidth, initialHeight, minWidth = 240, minHeight = 120, maxWidth, maxHeight, onSizeChange, dragHandle, children }) {
48
+ const resizable = initialWidth != null && initialHeight != null;
49
+ const panelRef = useRef(null);
50
+ const [position, setPosition] = useState({
51
+ left: initialLeft,
52
+ top: initialTop
53
+ });
54
+ const [size, setSize] = useState(() => resizable
55
+ ? clampFloatingDialogSize(initialWidth, initialHeight, initialLeft, initialTop, minWidth, minHeight, maxWidth, maxHeight)
56
+ : null);
57
+ const positionRef = useRef(position);
58
+ const sizeRef = useRef(size);
59
+ const onPositionChangeRef = useRef(onPositionChange);
60
+ const onSizeChangeRef = useRef(onSizeChange);
61
+ const dragStateRef = useRef(null);
62
+ const resizeStateRef = useRef(null);
63
+ /**
64
+ * Keeps the latest position available to resize handlers without rebinding.
65
+ */
66
+ useEffect(() => {
67
+ positionRef.current = position;
68
+ }, [position]);
69
+ /**
70
+ * Keeps the latest size available to relocate / resize handlers.
71
+ */
72
+ useEffect(() => {
73
+ sizeRef.current = size;
74
+ }, [size]);
75
+ /**
76
+ * Keeps the latest position-change callback available to layout/resize handlers.
77
+ */
78
+ useEffect(() => {
79
+ onPositionChangeRef.current = onPositionChange;
80
+ }, [onPositionChange]);
81
+ /**
82
+ * Keeps the latest size-change callback available to resize handlers.
83
+ */
84
+ useEffect(() => {
85
+ onSizeChangeRef.current = onSizeChange;
86
+ }, [onSizeChange]);
87
+ /**
88
+ * Moves the panel to the default corner when it would sit outside the viewport.
89
+ */
90
+ const relocateToCornerIfOffScreen = useCallback(() => {
91
+ const panel = panelRef.current;
92
+ if (panel == null) {
93
+ return;
94
+ }
95
+ const measured = sizeRef.current ?? {
96
+ width: panel.offsetWidth,
97
+ height: panel.offsetHeight
98
+ };
99
+ const current = positionRef.current;
100
+ if (isFloatingDialogFullyOnScreen(current, measured)) {
101
+ return;
102
+ }
103
+ const corner = {
104
+ left: FLOATING_DIALOG_DEFAULT_LEFT,
105
+ top: FLOATING_DIALOG_DEFAULT_TOP
106
+ };
107
+ positionRef.current = corner;
108
+ setPosition(corner);
109
+ onPositionChangeRef.current?.(corner);
110
+ }, []);
111
+ /**
112
+ * After first paint and whenever the window resizes, relocates only when off-screen.
113
+ */
114
+ useLayoutEffect(() => {
115
+ relocateToCornerIfOffScreen();
116
+ window.addEventListener('resize', relocateToCornerIfOffScreen);
117
+ return () => window.removeEventListener('resize', relocateToCornerIfOffScreen);
118
+ }, [relocateToCornerIfOffScreen]);
119
+ /**
120
+ * Closes the dialog when Escape is pressed unless disabled.
121
+ */
122
+ useEffect(() => {
123
+ if (disableEscape) {
124
+ return;
125
+ }
126
+ /**
127
+ * Dismisses the floating dialog on Escape.
128
+ *
129
+ * @param event - Keyboard event.
130
+ */
131
+ const handleKeyDown = (event) => {
132
+ if (event.key === 'Escape') {
133
+ onClose();
134
+ }
135
+ };
136
+ document.addEventListener('keydown', handleKeyDown);
137
+ return () => document.removeEventListener('keydown', handleKeyDown);
138
+ }, [disableEscape, onClose]);
139
+ /**
140
+ * Begins a pointer drag from the header handle.
141
+ *
142
+ * @param event - Pointer down event on the drag handle.
143
+ */
144
+ const handlePointerDown = useCallback((event) => {
145
+ if (event.button !== 0) {
146
+ return;
147
+ }
148
+ event.currentTarget.setPointerCapture(event.pointerId);
149
+ dragStateRef.current = {
150
+ pointerId: event.pointerId,
151
+ originX: event.clientX,
152
+ originY: event.clientY,
153
+ startLeft: position.left,
154
+ startTop: position.top
155
+ };
156
+ }, [position.left, position.top]);
157
+ /**
158
+ * Updates panel position while dragging.
159
+ *
160
+ * @param event - Pointer move event.
161
+ */
162
+ const handlePointerMove = useCallback((event) => {
163
+ const drag = dragStateRef.current;
164
+ if (drag == null || drag.pointerId !== event.pointerId) {
165
+ return;
166
+ }
167
+ const next = {
168
+ left: Math.max(FLOATING_DIALOG_VIEWPORT_MARGIN_PX, drag.startLeft + (event.clientX - drag.originX)),
169
+ top: Math.max(FLOATING_DIALOG_VIEWPORT_MARGIN_PX, drag.startTop + (event.clientY - drag.originY))
170
+ };
171
+ positionRef.current = next;
172
+ setPosition(next);
173
+ }, []);
174
+ /**
175
+ * Ends an active pointer drag and notifies the parent of the final position.
176
+ *
177
+ * @param event - Pointer up/cancel event.
178
+ */
179
+ const handlePointerUp = useCallback((event) => {
180
+ const drag = dragStateRef.current;
181
+ if (drag == null || drag.pointerId !== event.pointerId) {
182
+ return;
183
+ }
184
+ dragStateRef.current = null;
185
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
186
+ event.currentTarget.releasePointerCapture(event.pointerId);
187
+ }
188
+ onPositionChangeRef.current?.(positionRef.current);
189
+ }, []);
190
+ /**
191
+ * Begins a southeast resize from the resize handle.
192
+ *
193
+ * @param event - Pointer down on the resize handle.
194
+ */
195
+ const handleResizePointerDown = useCallback((event) => {
196
+ if (!resizable || size == null || event.button !== 0) {
197
+ return;
198
+ }
199
+ event.stopPropagation();
200
+ event.currentTarget.setPointerCapture(event.pointerId);
201
+ resizeStateRef.current = {
202
+ pointerId: event.pointerId,
203
+ originX: event.clientX,
204
+ originY: event.clientY,
205
+ startWidth: size.width,
206
+ startHeight: size.height
207
+ };
208
+ }, [resizable, size]);
209
+ /**
210
+ * Updates panel size while resizing from the SE handle.
211
+ *
212
+ * @param event - Pointer move on the resize handle.
213
+ */
214
+ const handleResizePointerMove = useCallback((event) => {
215
+ const resize = resizeStateRef.current;
216
+ if (resize == null || resize.pointerId !== event.pointerId) {
217
+ return;
218
+ }
219
+ const next = clampFloatingDialogSize(resize.startWidth + (event.clientX - resize.originX), resize.startHeight + (event.clientY - resize.originY), positionRef.current.left, positionRef.current.top, minWidth, minHeight, maxWidth, maxHeight);
220
+ sizeRef.current = next;
221
+ setSize(next);
222
+ }, [maxHeight, maxWidth, minHeight, minWidth]);
223
+ /**
224
+ * Ends an active resize and notifies the parent of the final size.
225
+ *
226
+ * @param event - Pointer up/cancel on the resize handle.
227
+ */
228
+ const handleResizePointerUp = useCallback((event) => {
229
+ const resize = resizeStateRef.current;
230
+ if (resize == null || resize.pointerId !== event.pointerId) {
231
+ return;
232
+ }
233
+ resizeStateRef.current = null;
234
+ if (event.currentTarget.hasPointerCapture(event.pointerId)) {
235
+ event.currentTarget.releasePointerCapture(event.pointerId);
236
+ }
237
+ if (sizeRef.current != null) {
238
+ onSizeChangeRef.current?.(sizeRef.current);
239
+ }
240
+ }, []);
241
+ /**
242
+ * Adjusts size with arrow keys when the resize handle is focused.
243
+ *
244
+ * @param event - Keyboard event on the resize handle.
245
+ */
246
+ const handleResizeKeyDown = useCallback((event) => {
247
+ if (size == null) {
248
+ return;
249
+ }
250
+ const step = event.shiftKey ? 24 : 8;
251
+ let deltaW = 0;
252
+ let deltaH = 0;
253
+ if (event.key === 'ArrowRight') {
254
+ deltaW = step;
255
+ }
256
+ else if (event.key === 'ArrowLeft') {
257
+ deltaW = -step;
258
+ }
259
+ else if (event.key === 'ArrowDown') {
260
+ deltaH = step;
261
+ }
262
+ else if (event.key === 'ArrowUp') {
263
+ deltaH = -step;
264
+ }
265
+ else {
266
+ return;
267
+ }
268
+ event.preventDefault();
269
+ const next = clampFloatingDialogSize(size.width + deltaW, size.height + deltaH, positionRef.current.left, positionRef.current.top, minWidth, minHeight, maxWidth, maxHeight);
270
+ sizeRef.current = next;
271
+ setSize(next);
272
+ onSizeChangeRef.current?.(next);
273
+ }, [maxHeight, maxWidth, minHeight, minWidth, size]);
274
+ return (_jsxs("div", { ref: panelRef, role: "dialog", "aria-modal": "false", "aria-label": labelledBy ? undefined : label, "aria-labelledby": labelledBy, className: cn('hc-floating-dialog fixed z-[60] flex min-w-[240px] flex-col overflow-hidden rounded-lg border border-text/15 bg-control shadow-[0_8px_28px_rgba(0,0,0,0.18)] dark:shadow-[0_12px_36px_rgba(0,0,0,0.55)]', className), style: {
275
+ left: position.left,
276
+ top: position.top,
277
+ ...(size != null ? { width: size.width, height: size.height } : {})
278
+ }, children: [_jsx("div", { className: "hc-floating-dialog-handle shrink-0 cursor-grab touch-none active:cursor-grabbing", onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerUp, children: dragHandle }), _jsx("div", { className: cn('hc-floating-dialog-body min-h-0 flex-1 overflow-auto p-3', bodyClassName), children: children }), resizable ? (_jsx("button", { type: "button", "aria-label": "Resize dialog", className: "absolute right-0 bottom-0 h-4 w-4 cursor-se-resize border-0 bg-transparent p-0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent", onPointerDown: handleResizePointerDown, onPointerMove: handleResizePointerMove, onPointerUp: handleResizePointerUp, onPointerCancel: handleResizePointerUp, onKeyDown: handleResizeKeyDown, children: _jsx("span", { className: "pointer-events-none absolute right-1 bottom-1 h-2 w-2 border-r-2 border-b-2 border-muted", "aria-hidden": true }) })) : null] }));
279
+ }
@@ -20,7 +20,8 @@ interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
20
20
  }
21
21
  /**
22
22
  * Full-bleed page header with a bordered bottom edge, title block on the left,
23
- * and optional action controls on the right.
23
+ * and optional action controls on the right. Sticks to the top of its nearest
24
+ * scroll ancestor so title and actions stay visible while page content scrolls.
24
25
  */
25
26
  export declare function PageHeader({ title, description, icon, children, className, ...props }: Props): JSX.Element;
26
27
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA6BrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA6BrB"}
@@ -3,8 +3,9 @@ import { FaIcon } from '../FaIcon/index.js';
3
3
  import { cn } from '../utils.js';
4
4
  /**
5
5
  * Full-bleed page header with a bordered bottom edge, title block on the left,
6
- * and optional action controls on the right.
6
+ * and optional action controls on the right. Sticks to the top of its nearest
7
+ * scroll ancestor so title and actions stay visible while page content scrolls.
7
8
  */
8
9
  export function PageHeader({ title, description, icon, children, className, ...props }) {
9
- return (_jsxs("div", { ...props, className: cn('hc-page-header -mx-6 mb-4 flex flex-wrap items-center gap-2 border-b border-separator px-6 py-4', className), children: [_jsxs("div", { className: "hc-page-header-content min-w-0 flex-1", children: [_jsxs("h2", { className: "hc-page-header-title m-0 flex items-center gap-2 text-[22px] leading-[1.15] font-bold tracking-[-0.01em] text-text", children: [icon ? (_jsx(FaIcon, { icon: icon, className: "hc-page-header-title-icon h-4 w-4 shrink-0 text-muted", "aria-hidden": true })) : null, title] }), description ? (_jsx("p", { className: "hc-page-header-description m-0 mt-1 leading-6 text-muted", children: description })) : null] }), children ? (_jsx("div", { className: "hc-page-header-actions flex flex-wrap items-center gap-2", children: children })) : null] }));
10
+ return (_jsxs("div", { ...props, className: cn('hc-page-header sticky top-0 z-10 -mx-6 mb-4 flex flex-wrap items-center gap-2 border-b border-separator bg-surface px-6 py-4', className), children: [_jsxs("div", { className: "hc-page-header-content min-w-0 flex-1", children: [_jsxs("h2", { className: "hc-page-header-title m-0 flex items-center gap-2 text-[22px] leading-[1.15] font-bold tracking-[-0.01em] text-text", children: [icon ? (_jsx(FaIcon, { icon: icon, className: "hc-page-header-title-icon h-4 w-4 shrink-0 text-muted", "aria-hidden": true })) : null, title] }), description ? (_jsx("p", { className: "hc-page-header-description m-0 mt-1 leading-6 text-muted", children: description })) : null] }), children ? (_jsx("div", { className: "hc-page-header-actions flex flex-wrap items-center gap-2", children: children })) : null] }));
10
11
  }
@@ -1,3 +1,4 @@
1
+ import type { IconDefinition } from '@fortawesome/fontawesome-svg-core';
1
2
  import type { JSX, MouseEvent, ReactNode } from 'react';
2
3
  import { type SidebarItemSortableConfig } from './SidebarItem.js';
3
4
  interface Props {
@@ -21,13 +22,46 @@ interface Props {
21
22
  * Whether this row should use selected/highlighted row styling.
22
23
  */
23
24
  selected?: boolean;
25
+ /**
26
+ * Whether this environment has nested child environments.
27
+ */
28
+ hasChildren?: boolean;
29
+ /**
30
+ * Whether the child environment list is expanded.
31
+ */
32
+ expanded?: boolean;
33
+ /**
34
+ * Id of the child region controlled by this row (`SidebarTreeGroup` id).
35
+ */
36
+ childrenId?: string;
37
+ /**
38
+ * Nesting depth for indentation (`0` = root, no extra indent).
39
+ */
40
+ level?: number;
41
+ /**
42
+ * Total siblings at this level (tree a11y).
43
+ */
44
+ setSize?: number;
45
+ /**
46
+ * 1-based position among siblings at this level (tree a11y).
47
+ */
48
+ posInSet?: number;
49
+ /**
50
+ * Toggles child environment expand/collapse when {@link hasChildren} is true.
51
+ */
52
+ onToggleExpand?: () => void;
53
+ /**
54
+ * Icons for expand/collapse chevrons when {@link hasChildren} is true.
55
+ */
56
+ expandIcon?: IconDefinition;
57
+ collapseIcon?: IconDefinition;
24
58
  /**
25
59
  * dnd-kit sortable configuration for environment reordering.
26
60
  */
27
61
  sortable?: SidebarItemSortableConfig;
28
62
  /**
29
- * Accessible label for the listbox option. When omitted, the name is derived
30
- * from visible row content (name, variable summary).
63
+ * Accessible label for the listbox option or tree item. When omitted, the name
64
+ * is derived from visible row content (name, variable summary).
31
65
  */
32
66
  ariaLabel?: string;
33
67
  /**
@@ -64,15 +98,19 @@ interface Props {
64
98
  */
65
99
  dataSidebarEnvironmentId?: string | number;
66
100
  /**
67
- * HTML element for the row container. Use `li` inside {@link SidebarListbox}.
101
+ * HTML element for the row container. Use `li` inside {@link SidebarListbox}
102
+ * or {@link SidebarTree}.
68
103
  */
69
104
  as?: 'div' | 'li';
70
105
  }
71
106
  /**
72
107
  * Renders an environment row in the Collections sidebar Environments section.
73
108
  *
109
+ * Flat list rows use listbox option semantics. Nested tree rows (when `level` is
110
+ * set) use treeitem semantics with optional expand/collapse chevrons.
111
+ *
74
112
  * The accessible name is derived from visible row content (name, variable summary).
75
113
  */
76
- export declare function SidebarEnvironmentItem({ name, variableSummary, markerDot, selected, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, onDoubleClick, onEnter, actions, dataSidebarEnvironmentId, as }: Props): JSX.Element;
114
+ export declare function SidebarEnvironmentItem({ name, variableSummary, markerDot, selected, hasChildren, expanded, childrenId, level, setSize, posInSet, onToggleExpand, expandIcon, collapseIcon, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, onDoubleClick, onEnter, actions, dataSidebarEnvironmentId, as }: Props): JSX.Element;
77
115
  export {};
78
116
  //# sourceMappingURL=SidebarEnvironmentItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SidebarEnvironmentItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarEnvironmentItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAiB,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvE,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAI/E,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3C;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,eAAe,EACf,SAAS,EACT,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,EACb,OAAO,EACP,OAAO,EACP,wBAAwB,EACxB,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAwDrB"}
1
+ {"version":3,"file":"SidebarEnvironmentItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarEnvironmentItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAiB,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAU/E,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B;;OAEG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,YAAY,CAAC,EAAE,cAAc,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3C;;;OAGG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAOD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,eAAe,EACf,SAAS,EACT,QAAgB,EAChB,WAAmB,EACnB,QAAgB,EAChB,UAAU,EACV,KAAK,EACL,OAAO,EACP,QAAQ,EACR,cAAc,EACd,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,EACb,OAAO,EACP,OAAO,EACP,wBAAwB,EACxB,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAmGrB"}
@@ -1,14 +1,26 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { FaIcon } from '../FaIcon/index.js';
2
3
  import { SidebarItem } from './SidebarItem.js';
3
4
  import { SidebarMarkerDot } from './SidebarMarkerDot.js';
4
- import { SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
5
+ import { SIDEBAR_CHEVRON_BUTTON_CLASS, SIDEBAR_CHEVRON_ICON_CLASS, SIDEBAR_CHEVRON_LABEL_OFFSET_CLASS, SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
6
+ import { stopSortableDragPointerDown } from './stopSortableDragPointerDown.js';
7
+ /**
8
+ * Nesting indent step matching Tailwind `ml-4` (1rem) per depth level.
9
+ */
10
+ const ENVIRONMENT_LEVEL_INDENT_PX = 16;
5
11
  /**
6
12
  * Renders an environment row in the Collections sidebar Environments section.
7
13
  *
14
+ * Flat list rows use listbox option semantics. Nested tree rows (when `level` is
15
+ * set) use treeitem semantics with optional expand/collapse chevrons.
16
+ *
8
17
  * The accessible name is derived from visible row content (name, variable summary).
9
18
  */
10
- export function SidebarEnvironmentItem({ name, variableSummary, markerDot, selected = false, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, onDoubleClick, onEnter, actions, dataSidebarEnvironmentId, as = 'li' }) {
11
- const useListboxOption = as === 'li';
19
+ export function SidebarEnvironmentItem({ name, variableSummary, markerDot, selected = false, hasChildren = false, expanded = false, childrenId, level, setSize, posInSet, onToggleExpand, expandIcon, collapseIcon, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, onDoubleClick, onEnter, actions, dataSidebarEnvironmentId, as = 'li' }) {
20
+ const useTreeItem = as === 'li' && level != null;
21
+ const useListboxOption = as === 'li' && !useTreeItem;
22
+ const showChevron = hasChildren && expandIcon != null && collapseIcon != null && onToggleExpand != null;
23
+ const indentPx = (level ?? 0) * ENVIRONMENT_LEVEL_INDENT_PX;
12
24
  /**
13
25
  * Opens environment settings when Enter is pressed on the name area.
14
26
  */
@@ -20,6 +32,8 @@ export function SidebarEnvironmentItem({ name, variableSummary, markerDot, selec
20
32
  event.stopPropagation();
21
33
  onEnter();
22
34
  };
35
+ const chevronLabel = expanded ? `Collapse environment "${name}"` : `Expand environment "${name}"`;
36
+ const labelOffsetClass = useTreeItem ? SIDEBAR_CHEVRON_LABEL_OFFSET_CLASS : '';
23
37
  return (_jsx(SidebarItem, { selected: selected, sortable: sortable, onContextMenu: onContextMenu, actions: actions, as: as, listboxOption: useListboxOption
24
38
  ? {
25
39
  ariaLabel,
@@ -29,7 +43,22 @@ export function SidebarEnvironmentItem({ name, variableSummary, markerDot, selec
29
43
  onDoubleClick,
30
44
  onKeyDown: onEnter != null ? handleKeyDown : undefined
31
45
  }
32
- : undefined, children: _jsxs("span", { className: SIDEBAR_ITEM_BUTTON_CLASS, ...(dataSidebarEnvironmentId != null
46
+ : undefined, treeItem: useTreeItem
47
+ ? {
48
+ ariaLabel,
49
+ expanded: hasChildren ? expanded : undefined,
50
+ controlsId: hasChildren ? childrenId : undefined,
51
+ level: (level ?? 0) + 1,
52
+ setSize,
53
+ posInSet,
54
+ onClick,
55
+ onDoubleClick,
56
+ onKeyDown: onEnter != null ? handleKeyDown : undefined
57
+ }
58
+ : undefined, children: _jsxs("span", { className: SIDEBAR_ITEM_BUTTON_CLASS, style: indentPx > 0 ? { paddingLeft: indentPx } : undefined, ...(dataSidebarEnvironmentId != null
33
59
  ? { 'data-sidebar-environment-id': String(dataSidebarEnvironmentId) }
34
- : {}), children: [_jsxs("span", { className: "inline-flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "min-w-0 truncate", children: name }), markerDot != null ? (_jsx(SidebarMarkerDot, { marker: markerDot.marker, visible: markerDot.visible, label: markerDot.label })) : null] }), _jsx("span", { className: "shrink-0 text-muted", children: variableSummary })] }) }));
60
+ : {}), children: [showChevron ? (_jsx("button", { type: "button", className: SIDEBAR_CHEVRON_BUTTON_CLASS, onClick: (event) => {
61
+ event.stopPropagation();
62
+ onToggleExpand();
63
+ }, onPointerDown: stopSortableDragPointerDown, tabIndex: -1, "aria-label": chevronLabel, children: _jsx(FaIcon, { icon: expanded ? collapseIcon : expandIcon, className: SIDEBAR_CHEVRON_ICON_CLASS }) })) : useTreeItem ? (_jsx("span", { className: "inline-flex h-4 w-4 shrink-0", "aria-hidden": true })) : null, _jsxs("span", { className: `inline-flex min-w-0 flex-1 items-center gap-1.5 ${labelOffsetClass}`, children: [_jsx("span", { className: "min-w-0 truncate", children: name }), markerDot != null ? (_jsx(SidebarMarkerDot, { marker: markerDot.marker, visible: markerDot.visible, label: markerDot.label })) : null] }), _jsx("span", { className: "shrink-0 text-muted", children: variableSummary })] }) }));
35
64
  }
@@ -71,6 +71,10 @@ interface Props {
71
71
  * HTML element for the row container. Use `li` inside {@link SidebarListbox}.
72
72
  */
73
73
  as?: 'div' | 'li';
74
+ /**
75
+ * Additional class names merged onto the row container (e.g. to drop sidebar inset).
76
+ */
77
+ className?: string;
74
78
  }
75
79
  /**
76
80
  * Renders a saved-request sidebar row with method badge, optional color marker dot or git
@@ -81,6 +85,6 @@ interface Props {
81
85
  *
82
86
  * Wrap lists in {@link SidebarListbox} and pass `as="li"` for valid listbox semantics.
83
87
  */
84
- export declare function SidebarRequestItem({ method, name, nameClassName, markerDot, methodColors, statusMarker, selected, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, actions, as }: Props): JSX.Element;
88
+ export declare function SidebarRequestItem({ method, name, nameClassName, markerDot, methodColors, statusMarker, selected, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, actions, as, className }: Props): JSX.Element;
85
89
  export {};
86
90
  //# sourceMappingURL=SidebarRequestItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SidebarRequestItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarRequestItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAM/E,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,YAAY,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,IAAI,EACJ,aAAa,EACb,SAAS,EACT,YAAmB,EACnB,YAAY,EACZ,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA6CrB"}
1
+ {"version":3,"file":"SidebarRequestItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarRequestItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAM/E,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,YAAY,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,IAAI,EACJ,aAAa,EACb,SAAS,EACT,YAAmB,EACnB,YAAY,EACZ,QAAgB,EAChB,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,EAAS,EACT,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA8CrB"}
@@ -13,9 +13,9 @@ import { SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
13
13
  *
14
14
  * Wrap lists in {@link SidebarListbox} and pass `as="li"` for valid listbox semantics.
15
15
  */
16
- export function SidebarRequestItem({ method, name, nameClassName, markerDot, methodColors = true, statusMarker, selected = false, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, actions, as = 'li' }) {
16
+ export function SidebarRequestItem({ method, name, nameClassName, markerDot, methodColors = true, statusMarker, selected = false, sortable, ariaLabel, ariaSelected, ariaCurrent, onContextMenu, onClick, actions, as = 'li', className }) {
17
17
  const useListboxOption = as === 'li';
18
- return (_jsx(SidebarItem, { selected: selected, sortable: sortable, onContextMenu: onContextMenu, actions: actions, as: as, listboxOption: useListboxOption
18
+ return (_jsx(SidebarItem, { selected: selected, sortable: sortable, onContextMenu: onContextMenu, actions: actions, as: as, className: className, listboxOption: useListboxOption
19
19
  ? {
20
20
  ariaLabel,
21
21
  ariaSelected,
@@ -38,6 +38,14 @@ interface Props {
38
38
  * Called when the primary row area is activated.
39
39
  */
40
40
  onClick?: (event: MouseEvent<HTMLElement>) => void;
41
+ /**
42
+ * Called when the primary row area is double-clicked.
43
+ */
44
+ onDoubleClick?: (event: MouseEvent<HTMLElement>) => void;
45
+ /**
46
+ * Called when Enter is pressed on the primary row area.
47
+ */
48
+ onEnter?: () => void;
41
49
  /**
42
50
  * Trailing actions slot, typically a row actions menu.
43
51
  */
@@ -50,6 +58,6 @@ interface Props {
50
58
  /**
51
59
  * Renders a workspace row in the Collections sidebar Workspaces section.
52
60
  */
53
- export declare function SidebarWorkspaceItem({ name, summary, icon, markerDot, selected, sortable, onContextMenu, onClick, actions, as }: Props): JSX.Element;
61
+ export declare function SidebarWorkspaceItem({ name, summary, icon, markerDot, selected, sortable, onContextMenu, onClick, onDoubleClick, onEnter, actions, as }: Props): JSX.Element;
54
62
  export {};
55
63
  //# sourceMappingURL=SidebarWorkspaceItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SidebarWorkspaceItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarWorkspaceItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAExD,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAI/E,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,QAAgB,EAChB,QAAQ,EACR,aAAa,EACb,OAAO,EACP,OAAO,EACP,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAkCrB"}
1
+ {"version":3,"file":"SidebarWorkspaceItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarWorkspaceItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAiB,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAI/E,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QAClC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IAErC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,SAAS,EACT,QAAgB,EAChB,QAAQ,EACR,aAAa,EACb,OAAO,EACP,aAAa,EACb,OAAO,EACP,OAAO,EACP,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAiDrB"}
@@ -6,11 +6,24 @@ import { SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
6
6
  /**
7
7
  * Renders a workspace row in the Collections sidebar Workspaces section.
8
8
  */
9
- export function SidebarWorkspaceItem({ name, summary, icon, markerDot, selected = false, sortable, onContextMenu, onClick, actions, as = 'li' }) {
9
+ export function SidebarWorkspaceItem({ name, summary, icon, markerDot, selected = false, sortable, onContextMenu, onClick, onDoubleClick, onEnter, actions, as = 'li' }) {
10
10
  const useListboxOption = as === 'li';
11
+ /**
12
+ * Opens workspace settings when Enter is pressed on the row.
13
+ */
14
+ const handleKeyDown = (event) => {
15
+ if (event.key !== 'Enter' || onEnter == null) {
16
+ return;
17
+ }
18
+ event.preventDefault();
19
+ event.stopPropagation();
20
+ onEnter();
21
+ };
11
22
  return (_jsx(SidebarItem, { selected: selected, sortable: sortable, onContextMenu: onContextMenu, actions: actions, as: as, listboxOption: useListboxOption
12
23
  ? {
13
- onClick
24
+ onClick,
25
+ onDoubleClick,
26
+ onKeyDown: onEnter != null ? handleKeyDown : undefined
14
27
  }
15
28
  : undefined, children: _jsxs("span", { className: `${SIDEBAR_ITEM_BUTTON_CLASS} gap-2 rounded-md px-2 py-1`, children: [_jsx(FaIcon, { icon: icon, className: "h-3.5 w-3.5 shrink-0 text-muted", "aria-hidden": true }), _jsxs("span", { className: "inline-flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "min-w-0 truncate", children: name }), markerDot != null ? (_jsx(SidebarMarkerDot, { marker: markerDot.marker, visible: markerDot.visible, label: markerDot.label })) : null] }), _jsx("span", { className: "shrink-0 text-muted", children: summary })] }) }));
16
29
  }
@@ -17,6 +17,9 @@ interface Props {
17
17
  }
18
18
  /**
19
19
  * Cursor-positioned context menu for tab bars, rendered in a portal at the click point.
20
+ *
21
+ * @param props - Menu groups, cursor anchor, and close handler.
22
+ * @returns Portal menu panel, or null when there are no items.
20
23
  */
21
24
  export declare function TabContextMenu({ groups, position, onClose }: Props): JSX.Element | null;
22
25
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"TabContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/TabBar/TabContextMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAI1E,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,YAAY,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAgBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAkJvF"}
1
+ {"version":3,"file":"TabContextMenu.d.ts","sourceRoot":"","sources":["../../../src/components/TabBar/TabContextMenu.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAU1E,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,YAAY,CAAC;IAEvB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAoKvF"}