@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.
Files changed (36) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/components/AnchorMenuPanel/index.d.ts.map +1 -1
  3. package/dist/components/AnchorMenuPanel/index.js +13 -5
  4. package/dist/components/Autocomplete/useAutocomplete.d.ts +14 -1
  5. package/dist/components/Autocomplete/useAutocomplete.d.ts.map +1 -1
  6. package/dist/components/Autocomplete/useAutocomplete.js +28 -1
  7. package/dist/components/RoundButton/index.d.ts +5 -1
  8. package/dist/components/RoundButton/index.d.ts.map +1 -1
  9. package/dist/components/RoundButton/index.js +2 -2
  10. package/dist/components/RowActionsMenu/index.d.ts.map +1 -1
  11. package/dist/components/RowActionsMenu/index.js +22 -11
  12. package/dist/components/Sidebar/index.d.ts +4 -1
  13. package/dist/components/Sidebar/index.d.ts.map +1 -1
  14. package/dist/components/Sidebar/index.js +4 -2
  15. package/dist/components/SidebarItem/sidebarItemClasses.d.ts +3 -2
  16. package/dist/components/SidebarItem/sidebarItemClasses.d.ts.map +1 -1
  17. package/dist/components/SidebarItem/sidebarItemClasses.js +3 -2
  18. package/dist/components/SidebarRail/SidebarRailSeparator.d.ts +3 -3
  19. package/dist/components/SidebarRail/SidebarRailSeparator.js +3 -3
  20. package/dist/components/SidebarSection/SectionItem.js +1 -1
  21. package/dist/components/TabBar/index.d.ts.map +1 -1
  22. package/dist/components/TabBar/index.js +1 -1
  23. package/dist/components/VariableInput/index.d.ts +14 -1
  24. package/dist/components/VariableInput/index.d.ts.map +1 -1
  25. package/dist/components/VariableInput/index.js +4 -2
  26. package/dist/components/rowActionsMenuHelpers.d.ts +4 -0
  27. package/dist/components/rowActionsMenuHelpers.d.ts.map +1 -1
  28. package/dist/components/rowActionsMenuHelpers.js +6 -1
  29. package/dist/runtime/createBridgedPluginContext.js +87 -0
  30. package/dist/runtime/reactHost.d.ts +32 -0
  31. package/dist/runtime/webpageHandle.d.ts +50 -0
  32. package/dist/runtime/webpageHandle.js +273 -0
  33. package/dist/snippets.d.ts +67 -0
  34. package/dist/types.d.ts +105 -1
  35. package/dist/types.d.ts.map +1 -1
  36. 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,CA+c5B"}
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 (!hasEnabledItems) {
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;CAChD;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,EAC7B,EAAE,sBAAsB,GAAG,qBAAqB,CAyOhD"}
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;CAChB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,SAAS,EACT,KAAK,EACL,SAAS,EACT,OAAO,EACP,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAiBrB"}
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: "hc-round-button-icon h-3.5 w-3.5" }) }));
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,CAskBrB"}
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 (!hasEnabledItems)
169
+ if (flatItems.length === 0) {
169
170
  return;
170
- const edgeIndex = findEdgeEnabledIndex(flatItems, focusLast);
171
- if (edgeIndex == null)
172
- return;
173
- setFocusedIndex(edgeIndex);
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
- itemRefs.current[focusedIndex]?.focus();
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 wrapper.
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;;OAEG;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,CAsFrB"}
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: "flex min-h-full min-w-0 flex-col", children: children });
26
- const body = scroll ? (_jsx(Scrollbars, { id: bodyId, role: bodyRole, axis: scrollAxis, autoHide: scrollbarAutoHide, className: cn('min-h-0 flex-1', bodyClassName), children: scrollBody })) : (_jsx("div", { id: bodyId, role: bodyRole, className: cn('flex min-h-0 flex-1 flex-col', bodyClassName), children: children }));
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 align with section header
8
- * Add/Erase actions (which sit at the sidebar body's `pr-2` inset).
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;;;;;;;;GAQG;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"}
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 align with section header
8
- * Add/Erase actions (which sit at the sidebar body's `pr-2` inset).
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`, a soft mix of rail fill
7
- * and rail text so dividers stay close to the background in every theme.
8
- * Decorative only — hidden from the accessibility tree so focus stays on tabs.
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`, a soft mix of rail fill
7
- * and rail text so dividers stay close to the background in every theme.
8
- * Decorative only — hidden from the accessibility tree so focus stays on tabs.
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: "-mr-2 mb-1", children: [_jsxs("div", { className: `hc-sidebar-section-header flex min-h-8 items-center justify-between gap-2 bg-sidebar-section py-0.5 pr-2 ${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: {
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,CAoT1B;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"}
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 px-2', className);
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;CAC7B;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,GAAG,KAAK,EACT,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA4lBrB"}
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;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAWvF;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"}
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
- return items.findIndex((item) => isMenuItemEnabled(item));
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.