@harborclient/sdk 1.3.8 → 1.3.9
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/CHANGELOG.md +5 -0
- package/dist/components/AnchorMenuPanel/index.d.ts.map +1 -1
- package/dist/components/AnchorMenuPanel/index.js +13 -5
- package/dist/components/Autocomplete/useAutocomplete.d.ts +14 -1
- package/dist/components/Autocomplete/useAutocomplete.d.ts.map +1 -1
- package/dist/components/Autocomplete/useAutocomplete.js +28 -1
- package/dist/components/RoundButton/index.d.ts +5 -1
- package/dist/components/RoundButton/index.d.ts.map +1 -1
- package/dist/components/RoundButton/index.js +2 -2
- package/dist/components/RowActionsMenu/index.d.ts.map +1 -1
- package/dist/components/RowActionsMenu/index.js +22 -11
- package/dist/components/Sidebar/index.d.ts +4 -1
- package/dist/components/Sidebar/index.d.ts.map +1 -1
- package/dist/components/Sidebar/index.js +4 -2
- package/dist/components/SidebarItem/sidebarItemClasses.d.ts +3 -2
- package/dist/components/SidebarItem/sidebarItemClasses.d.ts.map +1 -1
- package/dist/components/SidebarItem/sidebarItemClasses.js +3 -2
- package/dist/components/SidebarRail/SidebarRailSeparator.d.ts +3 -3
- package/dist/components/SidebarRail/SidebarRailSeparator.js +3 -3
- package/dist/components/SidebarSection/SectionItem.js +1 -1
- package/dist/components/TabBar/index.d.ts.map +1 -1
- package/dist/components/TabBar/index.js +1 -1
- package/dist/components/VariableInput/index.d.ts +14 -1
- package/dist/components/VariableInput/index.d.ts.map +1 -1
- package/dist/components/VariableInput/index.js +4 -2
- package/dist/components/rowActionsMenuHelpers.d.ts +4 -0
- package/dist/components/rowActionsMenuHelpers.d.ts.map +1 -1
- package/dist/components/rowActionsMenuHelpers.js +6 -1
- package/dist/runtime/createBridgedPluginContext.js +87 -0
- package/dist/runtime/reactHost.d.ts +32 -0
- package/dist/runtime/webpageHandle.d.ts +50 -0
- package/dist/runtime/webpageHandle.js +273 -0
- package/dist/snippets.d.ts +67 -0
- package/dist/types.d.ts +105 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.3.9 - 2026-07-30
|
|
8
|
+
|
|
9
|
+
- Implement "Copy to chat" feature in browser context menu. (`617b273f`)
|
|
10
|
+
- Enhance browser functionality and introduce webpage scripting support. (`e4be8c89`)
|
|
11
|
+
|
|
7
12
|
## 1.3.8 - 2026-07-30
|
|
8
13
|
|
|
9
14
|
- Add browser-related features and tests. (`2f8eb307`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AnchorMenuPanel/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAGhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAqB,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAU7F,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,SAAS,EACT,MAAsB,EACtB,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AnchorMenuPanel/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAGhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAqB,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAU7F,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,IAAI,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EACN,SAAS,EACT,MAAsB,EACtB,SAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAyd5B"}
|
|
@@ -175,10 +175,17 @@ export function AnchorMenuPanel({ groups, anchor, onDismiss, menuId = 'anchor-me
|
|
|
175
175
|
setMenuPosition(anchor);
|
|
176
176
|
}, [anchor]);
|
|
177
177
|
/**
|
|
178
|
-
* Focuses the first enabled item after mount
|
|
178
|
+
* Focuses the first enabled item after mount, or the panel itself when the
|
|
179
|
+
* menu only contains disabled placeholders (empty-state rows).
|
|
179
180
|
*/
|
|
180
181
|
useEffect(() => {
|
|
182
|
+
if (flatItems.length === 0) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
181
185
|
if (!hasEnabledItems) {
|
|
186
|
+
requestAnimationFrame(() => {
|
|
187
|
+
panelRef.current?.focus();
|
|
188
|
+
});
|
|
182
189
|
return;
|
|
183
190
|
}
|
|
184
191
|
const edgeIndex = findEdgeEnabledIndex(flatItems, false);
|
|
@@ -253,12 +260,13 @@ export function AnchorMenuPanel({ groups, anchor, onDismiss, menuId = 'anchor-me
|
|
|
253
260
|
* @param event - Keyboard event from the menu panel.
|
|
254
261
|
*/
|
|
255
262
|
const handleMenuKeyDown = (event) => {
|
|
256
|
-
if (!hasEnabledItems)
|
|
257
|
-
return;
|
|
258
263
|
if (event.key === 'Tab') {
|
|
259
264
|
dismiss();
|
|
260
265
|
return;
|
|
261
266
|
}
|
|
267
|
+
if (!hasEnabledItems) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
262
270
|
if (event.key === 'ArrowRight') {
|
|
263
271
|
const candidate = flatItems[focusedIndex];
|
|
264
272
|
if (candidate?.submenu) {
|
|
@@ -313,12 +321,12 @@ export function AnchorMenuPanel({ groups, anchor, onDismiss, menuId = 'anchor-me
|
|
|
313
321
|
focusItem(typeahead.index);
|
|
314
322
|
}
|
|
315
323
|
};
|
|
316
|
-
if (
|
|
324
|
+
if (flatItems.length === 0) {
|
|
317
325
|
return null;
|
|
318
326
|
}
|
|
319
327
|
const openSubmenuItem = openSubmenuIndex != null ? flatItems[openSubmenuIndex] : undefined;
|
|
320
328
|
const openSubmenuAnchorRect = openSubmenuIndex != null ? itemRefs.current[openSubmenuIndex]?.getBoundingClientRect() : null;
|
|
321
|
-
const menuPanel = (_jsx("div", { ref: panelRef, id: menuElementId, role: "menu", className: cn('hc-anchor-menu-panel hc-row-actions-menu-panel app-no-drag fixed z-50 min-w-[200px] rounded-md border border-separator bg-surface py-1 shadow-md', className), style: { left: menuPosition.x, top: menuPosition.y }, onKeyDown: handleMenuKeyDown, onMouseLeave: () => {
|
|
329
|
+
const menuPanel = (_jsx("div", { ref: panelRef, id: menuElementId, role: "menu", tabIndex: hasEnabledItems ? undefined : -1, className: cn('hc-anchor-menu-panel hc-row-actions-menu-panel app-no-drag fixed z-50 min-w-[200px] rounded-md border border-separator bg-surface py-1 shadow-md', className), style: { left: menuPosition.x, top: menuPosition.y }, onKeyDown: handleMenuKeyDown, onMouseLeave: () => {
|
|
322
330
|
if (openSubmenuIndex != null) {
|
|
323
331
|
scheduleCloseSubmenu();
|
|
324
332
|
}
|
|
@@ -19,6 +19,19 @@ interface UseAutocompleteOptions {
|
|
|
19
19
|
* Optional ref for the anchor input; created internally when omitted.
|
|
20
20
|
*/
|
|
21
21
|
anchorRef?: RefObject<HTMLInputElement | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Optional async gate run after suggestions load and before the popup opens.
|
|
24
|
+
*
|
|
25
|
+
* Use this to prepare host UI (for example covering a native Electron guest)
|
|
26
|
+
* so the portaled list is not painted behind an opaque layer.
|
|
27
|
+
*/
|
|
28
|
+
beforeOpen?: () => void | Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Called when the suggestion popup open state changes.
|
|
31
|
+
*
|
|
32
|
+
* @param open - Whether suggestions are open.
|
|
33
|
+
*/
|
|
34
|
+
onOpenChange?: (open: boolean) => void;
|
|
22
35
|
}
|
|
23
36
|
interface UseAutocompleteResult {
|
|
24
37
|
/**
|
|
@@ -86,6 +99,6 @@ export declare function filterAutocompleteItems(items: string[], value: string |
|
|
|
86
99
|
*
|
|
87
100
|
* @param options - Source, value, and selection callback.
|
|
88
101
|
*/
|
|
89
|
-
export declare function useAutocomplete({ source, value, onSelect, anchorRef: externalAnchorRef }: UseAutocompleteOptions): UseAutocompleteResult;
|
|
102
|
+
export declare function useAutocomplete({ source, value, onSelect, anchorRef: externalAnchorRef, beforeOpen, onOpenChange }: UseAutocompleteOptions): UseAutocompleteResult;
|
|
90
103
|
export {};
|
|
91
104
|
//# sourceMappingURL=useAutocomplete.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/Autocomplete/useAutocomplete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,UAAU,sBAAsB;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAE5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useAutocomplete.d.ts","sourceRoot":"","sources":["../../../src/components/Autocomplete/useAutocomplete.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,UAAU,sBAAsB;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAE5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAE/C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,UAAU,qBAAqB;IAC7B;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB;;;;OAIG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,OAAO,CAAC;IAEpE;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB;;OAEG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,EAAE,CAaV;AAcD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,SAAS,EAAE,iBAAiB,EAC5B,UAAU,EACV,YAAY,EACb,EAAE,sBAAsB,GAAG,qBAAqB,CAuQhD"}
|
|
@@ -34,7 +34,7 @@ function normalizeSourceList(list) {
|
|
|
34
34
|
*
|
|
35
35
|
* @param options - Source, value, and selection callback.
|
|
36
36
|
*/
|
|
37
|
-
export function useAutocomplete({ source, value, onSelect, anchorRef: externalAnchorRef }) {
|
|
37
|
+
export function useAutocomplete({ source, value, onSelect, anchorRef: externalAnchorRef, beforeOpen, onOpenChange }) {
|
|
38
38
|
const internalAnchorRef = useRef(null);
|
|
39
39
|
const anchorRef = externalAnchorRef ?? internalAnchorRef;
|
|
40
40
|
const cacheRef = useRef([]);
|
|
@@ -42,11 +42,20 @@ export function useAutocomplete({ source, value, onSelect, anchorRef: externalAn
|
|
|
42
42
|
const loadPromiseRef = useRef(null);
|
|
43
43
|
const openRequestRef = useRef(0);
|
|
44
44
|
const mountedRef = useRef(true);
|
|
45
|
+
const beforeOpenRef = useRef(beforeOpen);
|
|
46
|
+
const onOpenChangeRef = useRef(onOpenChange);
|
|
45
47
|
const listboxId = useId();
|
|
46
48
|
const safeValue = value ?? '';
|
|
47
49
|
const [open, setOpen] = useState(false);
|
|
48
50
|
const [items, setItems] = useState([]);
|
|
49
51
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
52
|
+
/**
|
|
53
|
+
* Keeps optional open-gate and open-change callbacks current without retriggering open logic.
|
|
54
|
+
*/
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
beforeOpenRef.current = beforeOpen;
|
|
57
|
+
onOpenChangeRef.current = onOpenChange;
|
|
58
|
+
}, [beforeOpen, onOpenChange]);
|
|
50
59
|
/**
|
|
51
60
|
* Clears the mounted flag when the hook unmounts so async work cannot set state.
|
|
52
61
|
*/
|
|
@@ -127,6 +136,9 @@ export function useAutocomplete({ source, value, onSelect, anchorRef: externalAn
|
|
|
127
136
|
}, [source, safeValue]);
|
|
128
137
|
/**
|
|
129
138
|
* Opens the suggestion list and loads items when a source is configured.
|
|
139
|
+
*
|
|
140
|
+
* Awaits {@link UseAutocompleteOptions.beforeOpen} (when provided) even if the first
|
|
141
|
+
* filter pass is empty, so hosts can reserve layout before items appear via refresh.
|
|
130
142
|
*/
|
|
131
143
|
const openSuggestions = useCallback(async () => {
|
|
132
144
|
if (!source) {
|
|
@@ -138,6 +150,15 @@ export function useAutocomplete({ source, value, onSelect, anchorRef: externalAn
|
|
|
138
150
|
return;
|
|
139
151
|
}
|
|
140
152
|
const filtered = filterAutocompleteItems(cacheRef.current, safeValue);
|
|
153
|
+
const gate = beforeOpenRef.current;
|
|
154
|
+
// Always run beforeOpen when provided — filtered may be empty on focus (exact match
|
|
155
|
+
// excluded) and then fill in via refresh while open; hosts still need layout prepared.
|
|
156
|
+
if (gate) {
|
|
157
|
+
await gate();
|
|
158
|
+
if (!mountedRef.current || requestId !== openRequestRef.current) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
141
162
|
setItems(filtered);
|
|
142
163
|
setActiveIndex(filtered.length > 0 ? 0 : -1);
|
|
143
164
|
setOpen(true);
|
|
@@ -153,6 +174,12 @@ export function useAutocomplete({ source, value, onSelect, anchorRef: externalAn
|
|
|
153
174
|
setOpen(false);
|
|
154
175
|
setActiveIndex(-1);
|
|
155
176
|
}, []);
|
|
177
|
+
/**
|
|
178
|
+
* Notifies the host when suggestion open state changes.
|
|
179
|
+
*/
|
|
180
|
+
useEffect(() => {
|
|
181
|
+
onOpenChangeRef.current?.(open);
|
|
182
|
+
}, [open]);
|
|
156
183
|
/**
|
|
157
184
|
* Applies a suggestion and closes the list without calling add().
|
|
158
185
|
*
|
|
@@ -13,10 +13,14 @@ interface Props extends Omit<ComponentPropsWithoutRef<'button'>, 'children' | 'a
|
|
|
13
13
|
* Optional tooltip text. Defaults to `ariaLabel`.
|
|
14
14
|
*/
|
|
15
15
|
title?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional Tailwind classes for the icon size. Defaults to `h-3.5 w-3.5`.
|
|
18
|
+
*/
|
|
19
|
+
iconClassName?: string;
|
|
16
20
|
}
|
|
17
21
|
/**
|
|
18
22
|
* Round icon button for compact toolbars and panel chrome.
|
|
19
23
|
*/
|
|
20
|
-
export declare function RoundButton({ icon, ariaLabel, title, className, onClick, ...props }: Props): JSX.Element;
|
|
24
|
+
export declare function RoundButton({ icon, ariaLabel, title, className, iconClassName, onClick, ...props }: Props): JSX.Element;
|
|
21
25
|
export {};
|
|
22
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RoundButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAK3D,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACzF;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RoundButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAK3D,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACzF;;OAEG;IACH,IAAI,EAAE,cAAc,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,EACb,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAiBrB"}
|
|
@@ -5,6 +5,6 @@ import { cn } from '../utils.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* Round icon button for compact toolbars and panel chrome.
|
|
7
7
|
*/
|
|
8
|
-
export function RoundButton({ icon, ariaLabel, title, className, onClick, ...props }) {
|
|
9
|
-
return (_jsx("button", { ...props, type: "button", className: cn('hc-round-button focus-visible:bg-selection focus-visible:text-text', footerPanelCloseButtonClassName, className), onClick: onClick, "aria-label": ariaLabel, title: title ?? ariaLabel, children: _jsx(FaIcon, { icon: icon, className:
|
|
8
|
+
export function RoundButton({ icon, ariaLabel, title, className, iconClassName, onClick, ...props }) {
|
|
9
|
+
return (_jsx("button", { ...props, type: "button", className: cn('hc-round-button focus-visible:bg-selection focus-visible:text-text', footerPanelCloseButtonClassName, className), onClick: onClick, "aria-label": ariaLabel, title: title ?? ariaLabel, children: _jsx(FaIcon, { icon: icon, className: cn('hc-round-button-icon h-3.5 w-3.5', iconClassName) }) }));
|
|
10
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RowActionsMenu/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAUxE,OAAO,KAAK,EACV,wBAAwB,EACxB,GAAG,EAGH,SAAS,EACV,MAAM,OAAO,CAAC;AACf,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAmBlF,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAChB,CAAC,YAAY,GAAG;IAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,GAC9D,CAAC,YAAY,GAAG;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC;CACvB,CAAC,CAAC;AAEP,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;;OAGG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAUD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,MAAM,EACN,UAAU,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,WAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,SAAkB,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RowActionsMenu/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAUxE,OAAO,KAAK,EACV,wBAAwB,EACxB,GAAG,EAGH,SAAS,EACV,MAAM,OAAO,CAAC;AACf,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAmBlF,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAChB,CAAC,YAAY,GAAG;IAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,GAC9D,CAAC,YAAY,GAAG;IACd,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC;CACvB,CAAC,CAAC;AAEP,UAAU,KAAM,SAAQ,IAAI,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACvE;;;OAGG;IACH,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B;;OAEG;IACH,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAE1C;;OAEG;IACH,cAAc,CAAC,EAAE,aAAa,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB;;OAEG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAUD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,MAAM,EACN,UAAU,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,WAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,SAAkB,EAClB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAolBrB"}
|
|
@@ -162,15 +162,19 @@ export function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange, trigg
|
|
|
162
162
|
});
|
|
163
163
|
}, []);
|
|
164
164
|
/**
|
|
165
|
-
* Opens the menu and focuses the first or last item.
|
|
165
|
+
* Opens the menu and focuses the first or last enabled item.
|
|
166
|
+
* Disabled-only menus (empty-state placeholders) still open so the message is visible.
|
|
166
167
|
*/
|
|
167
168
|
const openMenu = useCallback((focusLast = false) => {
|
|
168
|
-
if (
|
|
169
|
+
if (flatItems.length === 0) {
|
|
169
170
|
return;
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
}
|
|
172
|
+
if (hasEnabledItems) {
|
|
173
|
+
const edgeIndex = findEdgeEnabledIndex(flatItems, focusLast);
|
|
174
|
+
if (edgeIndex != null) {
|
|
175
|
+
setFocusedIndex(edgeIndex);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
174
178
|
onOpenChange(menuId);
|
|
175
179
|
}, [flatItems, hasEnabledItems, menuId, onOpenChange]);
|
|
176
180
|
/**
|
|
@@ -196,15 +200,21 @@ export function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange, trigg
|
|
|
196
200
|
}, [placement]);
|
|
197
201
|
/**
|
|
198
202
|
* Moves focus into the menu after it opens and item refs are mounted.
|
|
203
|
+
* When every item is disabled, focuses the panel so Escape / Tab still work.
|
|
199
204
|
*/
|
|
200
205
|
useEffect(() => {
|
|
201
206
|
if (isOpen && !wasOpenRef.current) {
|
|
202
207
|
requestAnimationFrame(() => {
|
|
203
|
-
|
|
208
|
+
if (hasEnabledItems) {
|
|
209
|
+
itemRefs.current[focusedIndex]?.focus();
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
panelRef.current?.focus();
|
|
213
|
+
}
|
|
204
214
|
});
|
|
205
215
|
}
|
|
206
216
|
wasOpenRef.current = isOpen;
|
|
207
|
-
}, [focusedIndex, isOpen]);
|
|
217
|
+
}, [focusedIndex, hasEnabledItems, isOpen]);
|
|
208
218
|
/**
|
|
209
219
|
* Resets item refs and submenu state when the menu closes.
|
|
210
220
|
*/
|
|
@@ -297,12 +307,13 @@ export function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange, trigg
|
|
|
297
307
|
* for the keys it handles itself.
|
|
298
308
|
*/
|
|
299
309
|
const handleMenuKeyDown = (event) => {
|
|
300
|
-
if (!hasEnabledItems)
|
|
301
|
-
return;
|
|
302
310
|
if (event.key === 'Tab') {
|
|
303
311
|
closeMenu();
|
|
304
312
|
return;
|
|
305
313
|
}
|
|
314
|
+
if (!hasEnabledItems) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
306
317
|
if (event.key === 'ArrowRight') {
|
|
307
318
|
const candidate = flatItems[focusedIndex];
|
|
308
319
|
if (candidate?.submenu) {
|
|
@@ -359,7 +370,7 @@ export function RowActionsMenu({ groups, menuId, openMenuId, onOpenChange, trigg
|
|
|
359
370
|
};
|
|
360
371
|
const openSubmenuItem = openSubmenuIndex != null ? flatItems[openSubmenuIndex] : undefined;
|
|
361
372
|
const openSubmenuAnchorRect = openSubmenuIndex != null ? itemRefs.current[openSubmenuIndex]?.getBoundingClientRect() : null;
|
|
362
|
-
const menuPanel = isOpen ? (_jsx("div", { ref: panelRef, id: menuElementId, role: "menu", className: "hc-row-actions-menu-panel app-no-drag fixed z-50 min-w-[200px] rounded-md border border-separator bg-surface py-1 shadow-md", style: { left: menuPosition.x, top: menuPosition.y }, onKeyDown: handleMenuKeyDown, onMouseLeave: () => {
|
|
373
|
+
const menuPanel = isOpen ? (_jsx("div", { ref: panelRef, id: menuElementId, role: "menu", tabIndex: hasEnabledItems ? undefined : -1, className: "hc-row-actions-menu-panel app-no-drag fixed z-50 min-w-[200px] rounded-md border border-separator bg-surface py-1 shadow-md", style: { left: menuPosition.x, top: menuPosition.y }, onKeyDown: handleMenuKeyDown, onMouseLeave: () => {
|
|
363
374
|
if (openSubmenuIndex != null) {
|
|
364
375
|
scheduleCloseSubmenu();
|
|
365
376
|
}
|
|
@@ -33,7 +33,10 @@ interface Props {
|
|
|
33
33
|
*/
|
|
34
34
|
scrollbarAutoHide?: boolean;
|
|
35
35
|
/**
|
|
36
|
-
* Additional classes for the scrollable body
|
|
36
|
+
* Additional classes for the scrollable body content (padding, etc.).
|
|
37
|
+
* Applied to the inner content wrapper — not the OverlayScrollbars host —
|
|
38
|
+
* so section-header negative margins can cancel body padding and keep
|
|
39
|
+
* header actions aligned with row hamburgers.
|
|
37
40
|
*/
|
|
38
41
|
bodyClassName?: string;
|
|
39
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Sidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Sidebar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKjD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,UAAU,KAAK;IACb;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;IAEhD;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;IAE1B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,SAAS,EACT,MAAM,EACN,QAAQ,EACR,MAAa,EACb,UAAuB,EACvB,iBAAwB,EACxB,aAAa,EACb,MAAM,EACN,QAAQ,EACR,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACX,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA0FrB"}
|
|
@@ -21,9 +21,11 @@ export function Sidebar({ side, ariaLabel, header, children, scroll = true, scro
|
|
|
21
21
|
/**
|
|
22
22
|
* Stretch wrapper so short body content (e.g. centered empty states) fills the
|
|
23
23
|
* scroll viewport height while still allowing overflow scroll when content grows.
|
|
24
|
+
* Body padding lives here (not on the Scrollbars host) so OverlayScrollbars
|
|
25
|
+
* does not absorb it and section-header `-mr-*` cancel math keeps working.
|
|
24
26
|
*/
|
|
25
|
-
const scrollBody = _jsx("div", { className:
|
|
26
|
-
const body = scroll ? (_jsx(Scrollbars, { id: bodyId, role: bodyRole, axis: scrollAxis, autoHide: scrollbarAutoHide, className:
|
|
27
|
+
const scrollBody = (_jsx("div", { className: cn('flex min-h-full min-w-0 flex-col', bodyClassName), children: children }));
|
|
28
|
+
const body = scroll ? (_jsx(Scrollbars, { id: bodyId, role: bodyRole, axis: scrollAxis, autoHide: scrollbarAutoHide, className: "min-h-0 flex-1", children: scrollBody })) : (_jsx("div", { id: bodyId, role: bodyRole, className: cn('flex min-h-0 flex-1 flex-col', bodyClassName), children: children }));
|
|
27
29
|
const aside = (_jsxs("aside", { className: cn('hc-sidebar flex shrink-0 flex-col overflow-x-hidden bg-sidebar', side === 'right' && 'h-full min-h-0', asideClassName), style: { width }, "aria-label": ariaLabel, children: [header, body] }));
|
|
28
30
|
if (side === 'left') {
|
|
29
31
|
return (_jsxs(_Fragment, { children: [aside, handle] }));
|
|
@@ -4,8 +4,9 @@ import type { StatusDotVariant } from '../StatusDot/index.js';
|
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* Tailwind classes for a sidebar source row (collection, folder, request, etc.).
|
|
7
|
-
* Uses left padding only so trailing hamburger menus
|
|
8
|
-
* Add/Erase actions (
|
|
7
|
+
* Uses left padding only so trailing hamburger menus can share a right column
|
|
8
|
+
* with section header Add/Erase actions (host CSS insets hamburgers slightly
|
|
9
|
+
* right of header actions).
|
|
9
10
|
*
|
|
10
11
|
* @param selected - Whether this row is the active selection.
|
|
11
12
|
* @param compact - When true, uses tighter vertical padding for top-level list rows.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebarItemClasses.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/sidebarItemClasses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D;;GAEG;AAEH
|
|
1
|
+
{"version":3,"file":"sidebarItemClasses.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/sidebarItemClasses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D;;GAEG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,UAAQ,GAAG,MAAM,CAKpE;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQjD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,UAAO,GAAG,MAAM,CAK5E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,UAAO,GAAG,MAAM,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAMjE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,+HACwF,CAAC;AAE/H;;GAEG;AACH,eAAO,MAAM,yBAAyB,oVAC6S,CAAC;AAEpV;;;GAGG;AACH,eAAO,MAAM,4BAA4B,0JACgH,CAAC;AAE1J;;;GAGG;AACH,eAAO,MAAM,0BAA0B,cAAc,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,kEAC0B,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,kCAAkC,WAAW,CAAC"}
|
|
@@ -4,8 +4,9 @@ import { statusDotVariantClass } from '../StatusDot/index.js';
|
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* Tailwind classes for a sidebar source row (collection, folder, request, etc.).
|
|
7
|
-
* Uses left padding only so trailing hamburger menus
|
|
8
|
-
* Add/Erase actions (
|
|
7
|
+
* Uses left padding only so trailing hamburger menus can share a right column
|
|
8
|
+
* with section header Add/Erase actions (host CSS insets hamburgers slightly
|
|
9
|
+
* right of header actions).
|
|
9
10
|
*
|
|
10
11
|
* @param selected - Whether this row is the active selection.
|
|
11
12
|
* @param compact - When true, uses tighter vertical padding for top-level list rows.
|
|
@@ -3,9 +3,9 @@ import type { JSX } from 'react';
|
|
|
3
3
|
* Horizontal hairline divider between {@link SidebarRail} navigation items.
|
|
4
4
|
*
|
|
5
5
|
* Spans the full rail width (no horizontal inset) so separators read as
|
|
6
|
-
* section boundaries. Uses `sidebar-rail-separator
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* section boundaries. Uses the `sidebar-rail-separator` theme color token
|
|
7
|
+
* (defaults to a soft mix of rail fill and rail text). Decorative only —
|
|
8
|
+
* hidden from the accessibility tree so focus stays on tabs.
|
|
9
9
|
*/
|
|
10
10
|
export declare function SidebarRailSeparator(): JSX.Element;
|
|
11
11
|
//# sourceMappingURL=SidebarRailSeparator.d.ts.map
|
|
@@ -3,9 +3,9 @@ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
|
|
|
3
3
|
* Horizontal hairline divider between {@link SidebarRail} navigation items.
|
|
4
4
|
*
|
|
5
5
|
* Spans the full rail width (no horizontal inset) so separators read as
|
|
6
|
-
* section boundaries. Uses `sidebar-rail-separator
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* section boundaries. Uses the `sidebar-rail-separator` theme color token
|
|
7
|
+
* (defaults to a soft mix of rail fill and rail text). Decorative only —
|
|
8
|
+
* hidden from the accessibility tree so focus stays on tabs.
|
|
9
9
|
*/
|
|
10
10
|
export function SidebarRailSeparator() {
|
|
11
11
|
return (_jsx("div", { className: "hc-sidebar-rail-separator h-px w-full shrink-0 bg-sidebar-rail-separator", "aria-hidden": true }));
|
|
@@ -15,7 +15,7 @@ const SectionItem = memo(function SectionItem({ forwardedRef, itemRef, state, to
|
|
|
15
15
|
const [transitionStyle, panelRef] = useHeightTransition(state);
|
|
16
16
|
const itemElementRef = useMergeRef(forwardedRef, itemRef);
|
|
17
17
|
const { status, isMounted, isEnter } = state;
|
|
18
|
-
return (_jsxs("div", { ref: itemElementRef, className: "
|
|
18
|
+
return (_jsxs("div", { ref: itemElementRef, className: "mb-1", children: [_jsxs("div", { className: `hc-sidebar-section-header flex min-h-8 items-center justify-between gap-2 border-y border-sidebar-rail-separator bg-sidebar-section py-1 pl-0.5 ${flushBody ? 'mb-0' : 'mb-1'}`, children: [_jsxs("button", { ...buttonProps, type: "button", className: "app-no-drag inline-flex min-w-0 flex-1 cursor-pointer items-center gap-2.5 border-none bg-transparent p-0 text-left", children: [_jsx("span", { className: SIDEBAR_CHEVRON_SLOT_CLASS, children: _jsx(FaIcon, { icon: isEnter ? faChevronDown : faChevronRight, className: `${SIDEBAR_CHEVRON_ICON_CLASS} text-sidebar-section-text` }) }), _jsx("h2", { className: "m-0 text-[15px] leading-none font-medium tracking-wide text-sidebar-section-text uppercase", children: title })] }), (headerActions || onAdd) && (_jsxs("div", { className: "hc-sidebar-section-header-actions flex shrink-0 items-center gap-1", children: [headerActions, onAdd ? (_jsx("button", { type: "button", className: "hc-sidebar-add-button app-no-drag inline-flex shrink-0 cursor-pointer items-center justify-center border-none bg-transparent text-muted hover:bg-selection hover:text-text focus-visible:bg-selection focus-visible:text-text", title: addLabel ?? 'Add', "aria-label": addLabel ?? 'Add', onClick: onAdd, children: _jsx(FaIcon, { icon: faPlus, className: "h-3.5 w-3.5" }) })) : null] }))] }), isMounted ? (_jsx("div", { style: {
|
|
19
19
|
display: status === 'exited' ? 'none' : undefined,
|
|
20
20
|
...transitionStyle
|
|
21
21
|
}, className: "transition-[height] duration-200 ease-out motion-reduce:transition-none", children: _jsx("div", { ...panelProps, ref: panelRef, children: children }) })) : null] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TabBar/index.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAkB,GAAG,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAgCjF,UAAU,KAAK,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM;IACzC;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC;IAEd;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE5B;;OAEG;IACH,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE3B;;OAEG;IACH,SAAS,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,EAAE,CAAC;IAE5E;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE/B;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,SAAS,CAAC;IAEtD;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqDD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,EAClD,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,MAAM,EACN,QAAQ,EACR,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,SAAS,EACV,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TabBar/index.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAkB,GAAG,EAA6B,SAAS,EAAE,MAAM,OAAO,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAM3D,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAgCjF,UAAU,KAAK,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM;IACzC;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAExB;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC;IAEd;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE5B;;OAEG;IACH,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE3B;;OAEG;IACH,SAAS,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,EAAE,CAAC;IAE5E;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC;IAE5C;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAE/B;;OAEG;IACH,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,SAAS,CAAC;IAEtD;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqDD;;;GAGG;AACH,wBAAgB,MAAM,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,EAClD,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,MAAM,EACN,QAAQ,EACR,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,SAAS,EACV,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,CAuT1B;AAED,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,0BAA0B,CAAC"}
|
|
@@ -214,7 +214,7 @@ export function TabBar({ tabs, activeId, wrap, ariaLabel, tabIdPrefix, panelIdPr
|
|
|
214
214
|
}) }, exitingTab.exitKey)))] }), wrap ? newTabButton : null] }), _jsx(DragOverlay, { children: activeDragTab ? (_jsx("div", { className: "rounded-t-lg border border-separator bg-surface px-3 py-2 text-[14px] font-medium shadow-md", children: activeDragTab.dragLabel })) : null })] }), wrap ? null : newTabButton] }));
|
|
215
215
|
const defaultScrollContainer = (row) => (_jsx("div", { className: "min-w-0 flex-1 overflow-x-auto", children: row }));
|
|
216
216
|
const scrollContainer = renderScrollContainer ?? defaultScrollContainer;
|
|
217
|
-
const containerClassName = cn('app-no-drag flex shrink-0 items-end bg-sidebar
|
|
217
|
+
const containerClassName = cn('app-no-drag flex shrink-0 items-end bg-sidebar pr-2 pl-0', className);
|
|
218
218
|
return (_jsxs("div", { className: containerClassName, children: [wrap ? _jsx("div", { className: "min-w-0 flex-1", children: tabRow }) : scrollContainer(tabRow), contextMenu != null && buildContextMenuGroups != null && (_jsx(TabContextMenu, { groups: contextMenuGroups, position: { x: contextMenu.x, y: contextMenu.y }, onClose: () => setContextMenu(null) }))] }));
|
|
219
219
|
}
|
|
220
220
|
export { TabNewButton } from './TabNewButton.js';
|
|
@@ -52,6 +52,19 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
|
|
|
52
52
|
* Optional async source for value autocomplete suggestions.
|
|
53
53
|
*/
|
|
54
54
|
source?: AutocompleteSource;
|
|
55
|
+
/**
|
|
56
|
+
* Optional async gate run after suggestions load and before the popup opens.
|
|
57
|
+
*
|
|
58
|
+
* Hosts can use this to cover native layers (for example Electron WebContentsView)
|
|
59
|
+
* so the portaled suggestion list is not painted behind them.
|
|
60
|
+
*/
|
|
61
|
+
beforeSuggestionsOpen?: () => void | Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Called when the autocomplete suggestion popup open state changes.
|
|
64
|
+
*
|
|
65
|
+
* @param open - Whether suggestions are open.
|
|
66
|
+
*/
|
|
67
|
+
onSuggestionsOpenChange?: (open: boolean) => void;
|
|
55
68
|
}
|
|
56
69
|
/**
|
|
57
70
|
* Text input that highlights {{variable}} tokens and shows resolved values on hover.
|
|
@@ -59,5 +72,5 @@ export interface Props extends Omit<ComponentPropsWithoutRef<'div'>, 'children'
|
|
|
59
72
|
* Token highlight color (`text-[#32D2E2]`) and the tooltip `app-no-drag` class rely on
|
|
60
73
|
* host styling in HarborClient `styles.css`.
|
|
61
74
|
*/
|
|
62
|
-
export declare function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className, wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source, ...props }: Props): JSX.Element;
|
|
75
|
+
export declare function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className, wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source, beforeSuggestionsOpen, onSuggestionsOpenChange, ...props }: Props): JSX.Element;
|
|
63
76
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAwBnE,MAAM,WAAW,KAAM,SAAQ,IAAI,CACjC,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,YAAY,GAAG,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAC9F;IACC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/VariableInput/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,aAAa,EAAc,MAAM,OAAO,CAAC;AACtF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAwBnE,MAAM,WAAW,KAAM,SAAQ,IAAI,CACjC,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,YAAY,GAAG,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAC9F;IACC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC;;OAEG;IACH,SAAS,EAAE,QAAQ,EAAE,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAE5B;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAc,EACd,gBAAgB,EAChB,cAAc,EACd,EAAE,EACF,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,MAAM,EACN,qBAAqB,EACrB,uBAAuB,EACvB,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA8lBrB"}
|
|
@@ -18,7 +18,7 @@ const TOOLTIP_HIDE_DELAY_MS = 400;
|
|
|
18
18
|
* Token highlight color (`text-[#32D2E2]`) and the tooltip `app-no-drag` class rely on
|
|
19
19
|
* host styling in HarborClient `styles.css`.
|
|
20
20
|
*/
|
|
21
|
-
export function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className = '', wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source, ...props }) {
|
|
21
|
+
export function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className = '', wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source, beforeSuggestionsOpen, onSuggestionsOpenChange, ...props }) {
|
|
22
22
|
const safeValue = value ?? '';
|
|
23
23
|
const wrapperRef = useRef(null);
|
|
24
24
|
const inputRef = useRef(null);
|
|
@@ -40,7 +40,9 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
|
|
|
40
40
|
source,
|
|
41
41
|
value: safeValue,
|
|
42
42
|
onSelect: onChange,
|
|
43
|
-
anchorRef: inputRef
|
|
43
|
+
anchorRef: inputRef,
|
|
44
|
+
beforeOpen: beforeSuggestionsOpen,
|
|
45
|
+
onOpenChange: onSuggestionsOpenChange
|
|
44
46
|
});
|
|
45
47
|
/**
|
|
46
48
|
* Splits the input value into plain text and {{variable}} token spans for highlighting.
|
|
@@ -14,6 +14,10 @@ export declare function isMenuItemEnabled(item: MenuItem): boolean;
|
|
|
14
14
|
export declare function findAdjacentEnabledIndex(items: MenuItem[], fromIndex: number, direction: -1 | 1): number | null;
|
|
15
15
|
/**
|
|
16
16
|
* Returns the first or last enabled flat item index.
|
|
17
|
+
*
|
|
18
|
+
* @param items - Flat menu items to search.
|
|
19
|
+
* @param fromEnd - When true, returns the last enabled index; otherwise the first.
|
|
20
|
+
* @returns Enabled index, or `null` when every item is disabled / the list is empty.
|
|
17
21
|
*/
|
|
18
22
|
export declare function findEdgeEnabledIndex(items: MenuItem[], fromEnd: boolean): number | null;
|
|
19
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rowActionsMenuHelpers.d.ts","sourceRoot":"","sources":["../../src/components/rowActionsMenuHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAatF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAChB,MAAM,GAAG,IAAI,CAWf;AAED
|
|
1
|
+
{"version":3,"file":"rowActionsMenuHelpers.d.ts","sourceRoot":"","sources":["../../src/components/rowActionsMenuHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAatF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAChB,MAAM,GAAG,IAAI,CAWf;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYvF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,GACzC,QAAQ,EAAE,EAAE,CAsBd"}
|
|
@@ -33,6 +33,10 @@ export function findAdjacentEnabledIndex(items, fromIndex, direction) {
|
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Returns the first or last enabled flat item index.
|
|
36
|
+
*
|
|
37
|
+
* @param items - Flat menu items to search.
|
|
38
|
+
* @param fromEnd - When true, returns the last enabled index; otherwise the first.
|
|
39
|
+
* @returns Enabled index, or `null` when every item is disabled / the list is empty.
|
|
36
40
|
*/
|
|
37
41
|
export function findEdgeEnabledIndex(items, fromEnd) {
|
|
38
42
|
if (fromEnd) {
|
|
@@ -43,7 +47,8 @@ export function findEdgeEnabledIndex(items, fromEnd) {
|
|
|
43
47
|
}
|
|
44
48
|
return null;
|
|
45
49
|
}
|
|
46
|
-
|
|
50
|
+
const index = items.findIndex((item) => isMenuItemEnabled(item));
|
|
51
|
+
return index >= 0 ? index : null;
|
|
47
52
|
}
|
|
48
53
|
/**
|
|
49
54
|
* Builds an optional reorder group for move-up/move-down row actions.
|