@harborclient/sdk 1.1.11 → 1.1.13

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.
@@ -0,0 +1,49 @@
1
+ import type { ComponentPropsWithoutRef, JSX, ReactNode } from 'react';
2
+ /**
3
+ * Visual tone for compact sidebar badges.
4
+ */
5
+ export type SidebarBadgeVariant = 'info' | 'recessed';
6
+ type BaseProps = {
7
+ /**
8
+ * Badge label content.
9
+ */
10
+ children: ReactNode;
11
+ /**
12
+ * Color and background preset.
13
+ */
14
+ variant?: SidebarBadgeVariant;
15
+ /**
16
+ * Additional Tailwind classes merged onto the badge.
17
+ */
18
+ className?: string;
19
+ /**
20
+ * Tooltip text for the badge.
21
+ */
22
+ title?: string;
23
+ };
24
+ type SpanProps = BaseProps & Omit<ComponentPropsWithoutRef<'span'>, 'children' | 'className' | 'title'> & {
25
+ /**
26
+ * Renders a non-interactive badge. Default for storage location labels.
27
+ */
28
+ as?: 'span';
29
+ };
30
+ type ButtonProps = BaseProps & Omit<ComponentPropsWithoutRef<'button'>, 'children' | 'className' | 'type' | 'title'> & {
31
+ /**
32
+ * Renders an interactive badge for branch switches and count actions.
33
+ */
34
+ as: 'button';
35
+ /**
36
+ * Button type attribute. Defaults to `button` so badges do not submit forms.
37
+ */
38
+ type?: 'button';
39
+ };
40
+ type Props = SpanProps | ButtonProps;
41
+ /**
42
+ * Compact sidebar badge for storage locations, git branches, and count indicators.
43
+ *
44
+ * Use `variant="info"` for connection or branch labels and `variant="recessed"` for
45
+ * numeric count badges. Pass `as="button"` when the badge triggers an action.
46
+ */
47
+ export declare function SidebarBadge(props: Props): JSX.Element;
48
+ export {};
49
+ //# sourceMappingURL=SidebarBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SidebarBadge.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtD,KAAK,SAAS,GAAG;IACf;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAE9B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,SAAS,GAAG,SAAS,GACxB,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,GAAG;IAC3E;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEJ,KAAK,WAAW,GAAG,SAAS,GAC1B,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG;IACtF;;OAEG;IACH,EAAE,EAAE,QAAQ,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,CAAC;AAEJ,KAAK,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC;AAmDrC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAoBtD"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx } from "@harborclient/sdk/jsx-runtime";
2
+ import { cn } from '../utils.js';
3
+ const SIDEBAR_BADGE_OWN_PROPS = new Set([
4
+ 'children',
5
+ 'variant',
6
+ 'className',
7
+ 'as',
8
+ 'title',
9
+ 'type'
10
+ ]);
11
+ /**
12
+ * Returns props safe to spread onto the rendered DOM element.
13
+ *
14
+ * @param props - Full SidebarBadge props including component-only fields.
15
+ * @returns DOM props without SidebarBadge-specific keys.
16
+ */
17
+ function sidebarBadgeDomProps(props) {
18
+ return Object.fromEntries(Object.entries(props).filter(([key]) => !SIDEBAR_BADGE_OWN_PROPS.has(key)));
19
+ }
20
+ /**
21
+ * Returns variant and interaction classes for a sidebar badge.
22
+ *
23
+ * @param variant - Color and background preset.
24
+ * @param interactive - Whether the badge is rendered as a button.
25
+ * @returns Tailwind classes for the badge element.
26
+ */
27
+ function variantClasses(variant, interactive) {
28
+ const base = 'hc-sidebar-badge inline-flex h-[18px] shrink-0 items-center text-[14px] leading-none';
29
+ if (variant === 'recessed') {
30
+ return cn(base, 'min-w-[22px] justify-center rounded-full bg-selection px-2 font-normal text-muted shadow-[inset_0_0.5px_1px_rgba(0,0,0,0.06)]', interactive &&
31
+ 'app-no-drag cursor-pointer hover:text-text focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none');
32
+ }
33
+ return cn(base, 'rounded bg-info/15 px-1.5 font-medium text-info', interactive &&
34
+ 'app-no-drag cursor-pointer hover:bg-info/25 focus-visible:ring-2 focus-visible:ring-accent focus-visible:outline-none');
35
+ }
36
+ /**
37
+ * Compact sidebar badge for storage locations, git branches, and count indicators.
38
+ *
39
+ * Use `variant="info"` for connection or branch labels and `variant="recessed"` for
40
+ * numeric count badges. Pass `as="button"` when the badge triggers an action.
41
+ */
42
+ export function SidebarBadge(props) {
43
+ const { children, variant = 'info', className, as = 'span', title } = props;
44
+ const interactive = as === 'button';
45
+ const classes = cn(variantClasses(variant, interactive), className);
46
+ const domProps = sidebarBadgeDomProps(props);
47
+ if (as === 'button') {
48
+ const type = props.type ?? 'button';
49
+ return (_jsx("button", { type: type, className: classes, title: title, ...domProps, children: children }));
50
+ }
51
+ return (_jsx("span", { className: classes, title: title, ...domProps, children: children }));
52
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"SidebarRunItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarRunItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMxD,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,QAAgB,EAChB,KAAK,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,sBAAsB,EACtB,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CA2CrB"}
1
+ {"version":3,"file":"SidebarRunItem.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/SidebarRunItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOxD,UAAU,KAAK;IACb;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEzD;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,QAAgB,EAChB,KAAK,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,OAAO,EACP,OAAO,EACP,sBAAsB,EACtB,EAAS,EACV,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAwCrB"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
+ import { SidebarBadge } from './SidebarBadge.js';
2
3
  import { SidebarItem } from './SidebarItem.js';
3
4
  import { SidebarMethodBadge } from './SidebarMethodBadge.js';
4
5
  import { SidebarStatusDot } from './SidebarStatusDot.js';
@@ -20,5 +21,5 @@ export function SidebarRunItem({ method, label, connectionBadge, statusDotClassN
20
21
  }
21
22
  : undefined, children: _jsxs("span", { className: `${SIDEBAR_ITEM_BUTTON_CLASS} py-0.5`, title: title, ...(dataSidebarRunResultId != null
22
23
  ? { 'data-sidebar-run-result-id': String(dataSidebarRunResultId) }
23
- : {}), children: [method != null && method !== '' ? _jsx(SidebarMethodBadge, { method: method, uppercase: true }) : null, _jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "min-w-0 truncate text-text", children: label }), connectionBadge != null ? (_jsx("span", { className: "shrink-0 rounded bg-info/15 px-1.5 py-0.5 text-[14px] font-medium text-info", title: `Stored in ${connectionBadge}`, children: connectionBadge })) : null] }), _jsx(SidebarStatusDot, { className: statusDotClassName, srOnlyLabel: statusSummary })] }) }));
24
+ : {}), children: [method != null && method !== '' ? _jsx(SidebarMethodBadge, { method: method, uppercase: true }) : null, _jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [_jsx("span", { className: "min-w-0 truncate text-text", children: label }), connectionBadge != null ? (_jsx(SidebarBadge, { variant: "info", title: `Stored in ${connectionBadge}`, children: connectionBadge })) : null] }), _jsx(SidebarStatusDot, { className: statusDotClassName, srOnlyLabel: statusSummary })] }) }));
24
25
  }
@@ -6,6 +6,7 @@ export { handleSidebarOptionKeyDown } from './sidebarListOption.js';
6
6
  export { SortableSidebarItem } from './SortableSidebarItem.js';
7
7
  export { stopSortableDragPointerDown } from './stopSortableDragPointerDown.js';
8
8
  export { SidebarColorDot } from './SidebarColorDot.js';
9
+ export { SidebarBadge, type SidebarBadgeVariant } from './SidebarBadge.js';
9
10
  export { sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
10
11
  export { SidebarMethodBadge } from './SidebarMethodBadge.js';
11
12
  export { SidebarStatusDot } from './SidebarStatusDot.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EACL,SAAS,EACT,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SidebarItem/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,cAAc,EACd,cAAc,EACd,yBAAyB,EAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -6,6 +6,7 @@ export { handleSidebarOptionKeyDown } from './sidebarListOption.js';
6
6
  export { SortableSidebarItem } from './SortableSidebarItem.js';
7
7
  export { stopSortableDragPointerDown } from './stopSortableDragPointerDown.js';
8
8
  export { SidebarColorDot } from './SidebarColorDot.js';
9
+ export { SidebarBadge } from './SidebarBadge.js';
9
10
  export { sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS } from './sidebarItemClasses.js';
10
11
  export { SidebarMethodBadge } from './SidebarMethodBadge.js';
11
12
  export { SidebarStatusDot } from './SidebarStatusDot.js';
@@ -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;AAqBnE,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,CAgVrB"}
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"}
@@ -6,6 +6,7 @@ import { useAutocomplete } from '../Autocomplete/useAutocomplete.js';
6
6
  import { Button } from '../Button/index.js';
7
7
  import { VariableTooltipValue } from '../VariableTooltip/index.js';
8
8
  import { Input } from '../forms/index.js';
9
+ import { getFocusableElements } from '../useDialogFocus.js';
9
10
  import { cn } from '../utils.js';
10
11
  /** Delay after the pointer stops moving before a hover tooltip is shown. */
11
12
  const TOOLTIP_SHOW_DELAY_MS = 500;
@@ -19,12 +20,21 @@ const TOOLTIP_HIDE_DELAY_MS = 400;
19
20
  */
20
21
  export function VariableInput({ value, onChange, variables, placeholder, onKeyDown, className = '', wrapperClassName, onEditVariable, id, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, source, ...props }) {
21
22
  const safeValue = value ?? '';
23
+ const wrapperRef = useRef(null);
22
24
  const inputRef = useRef(null);
23
25
  const backdropRef = useRef(null);
24
- const spanRefs = useRef(new Map());
26
+ const tokenButtonRefs = useRef(new Map());
27
+ const tooltipRef = useRef(null);
25
28
  const hideTimer = useRef(null);
26
29
  const showTimer = useRef(null);
30
+ const suppressReopen = useRef(false);
31
+ const pendingEnterFocus = useRef(false);
32
+ const tooltipEntered = useRef(false);
33
+ const tooltipSourceRef = useRef(null);
34
+ const activeTokenIndexRef = useRef(null);
27
35
  const [tooltip, setTooltip] = useState(null);
36
+ const [tooltipSource, setTooltipSource] = useState(null);
37
+ const [activeTokenIndex, setActiveTokenIndex] = useState(null);
28
38
  const tooltipId = useId();
29
39
  const { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, listboxId, onFocus: openAutocomplete, onBlur: closeAutocomplete, onInputKeyDown, selectItem, setActiveIndex, closeSuggestions } = useAutocomplete({
30
40
  source,
@@ -36,6 +46,13 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
36
46
  * Splits the input value into plain text and {{variable}} token spans for highlighting.
37
47
  */
38
48
  const tokens = useMemo(() => tokenizeVariables(safeValue), [safeValue]);
49
+ /**
50
+ * Keeps tooltip refs aligned with React state for timer and document handlers.
51
+ */
52
+ useEffect(() => {
53
+ tooltipSourceRef.current = tooltipSource;
54
+ activeTokenIndexRef.current = activeTokenIndex;
55
+ }, [tooltipSource, activeTokenIndex]);
39
56
  /**
40
57
  * Clears any pending tooltip hide timer.
41
58
  */
@@ -45,12 +62,55 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
45
62
  hideTimer.current = null;
46
63
  }
47
64
  };
65
+ /**
66
+ * Clears tooltip state regardless of source.
67
+ */
68
+ const dismissTooltip = () => {
69
+ pendingEnterFocus.current = false;
70
+ tooltipEntered.current = false;
71
+ setTooltip(null);
72
+ setTooltipSource(null);
73
+ setActiveTokenIndex(null);
74
+ };
75
+ /**
76
+ * Clears tooltip state and optionally refocuses the triggering token.
77
+ *
78
+ * @param refocusToken - When true, moves focus back to the active token without reopening.
79
+ */
80
+ const dismissFocusTooltip = (refocusToken = false) => {
81
+ const index = activeTokenIndexRef.current;
82
+ dismissTooltip();
83
+ if (refocusToken && index != null) {
84
+ suppressReopen.current = true;
85
+ tokenButtonRefs.current.get(index)?.focus();
86
+ }
87
+ };
88
+ /**
89
+ * Moves focus to the first control inside the open focus tooltip.
90
+ */
91
+ const focusFirstTooltipControl = () => {
92
+ const tooltipEl = tooltipRef.current;
93
+ if (!tooltipEl) {
94
+ return;
95
+ }
96
+ getFocusableElements(tooltipEl)[0]?.focus();
97
+ tooltipEntered.current = true;
98
+ };
48
99
  /**
49
100
  * Hides the tooltip after a short grace period so the pointer can reach it.
50
101
  */
51
102
  const scheduleHide = () => {
103
+ if (tooltipSourceRef.current === 'focus') {
104
+ return;
105
+ }
52
106
  cancelHide();
53
- hideTimer.current = window.setTimeout(() => setTooltip(null), TOOLTIP_HIDE_DELAY_MS);
107
+ hideTimer.current = window.setTimeout(() => {
108
+ hideTimer.current = null;
109
+ if (tooltipSourceRef.current === 'focus') {
110
+ return;
111
+ }
112
+ dismissTooltip();
113
+ }, TOOLTIP_HIDE_DELAY_MS);
54
114
  };
55
115
  /**
56
116
  * Clears any pending tooltip show timer.
@@ -64,7 +124,7 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
64
124
  /**
65
125
  * Shows a tooltip for a variable token at the given screen position.
66
126
  */
67
- const showTooltipForKey = (key, top, left) => {
127
+ const showTooltipForKey = (key, top, left, source, tokenIndex = null) => {
68
128
  setTooltip({
69
129
  key,
70
130
  value: resolveVariable(key, variables),
@@ -72,6 +132,8 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
72
132
  top,
73
133
  left
74
134
  });
135
+ setTooltipSource(source);
136
+ setActiveTokenIndex(tokenIndex);
75
137
  };
76
138
  /**
77
139
  * Shows the tooltip once the pointer has stopped moving for {@link TOOLTIP_SHOW_DELAY_MS}.
@@ -84,7 +146,7 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
84
146
  cancelShow();
85
147
  showTimer.current = window.setTimeout(() => {
86
148
  showTimer.current = null;
87
- showTooltipForKey(key, top, left);
149
+ showTooltipForKey(key, top, left, 'hover', null);
88
150
  }, TOOLTIP_SHOW_DELAY_MS);
89
151
  };
90
152
  /**
@@ -94,6 +156,65 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
94
156
  cancelHide();
95
157
  cancelShow();
96
158
  }, []);
159
+ /**
160
+ * Traps Tab within the tooltip controls once focus has entered the tooltip.
161
+ *
162
+ * While focus is still on the token (tooltip open but not entered), Tab is left
163
+ * alone so it moves naturally between variable tokens; only pressing Enter moves
164
+ * focus into the tooltip and engages this trap.
165
+ */
166
+ useEffect(() => {
167
+ if (tooltipSource !== 'focus' || activeTokenIndex == null || !tooltip) {
168
+ return;
169
+ }
170
+ /**
171
+ * Cycles Tab and Shift+Tab within the tooltip controls while focus is inside it.
172
+ *
173
+ * @param event - Document keydown event.
174
+ */
175
+ const handleKeyDown = (event) => {
176
+ if (event.key === 'Escape') {
177
+ event.preventDefault();
178
+ dismissFocusTooltip(true);
179
+ return;
180
+ }
181
+ if (event.key !== 'Tab' || !tooltipEntered.current) {
182
+ return;
183
+ }
184
+ const tooltipEl = tooltipRef.current;
185
+ if (!tooltipEl) {
186
+ return;
187
+ }
188
+ const controls = getFocusableElements(tooltipEl);
189
+ if (controls.length === 0) {
190
+ event.preventDefault();
191
+ return;
192
+ }
193
+ event.preventDefault();
194
+ const active = document.activeElement;
195
+ const index = active ? controls.indexOf(active) : -1;
196
+ if (index === -1) {
197
+ controls[0].focus();
198
+ return;
199
+ }
200
+ const nextIndex = event.shiftKey
201
+ ? (index - 1 + controls.length) % controls.length
202
+ : (index + 1) % controls.length;
203
+ controls[nextIndex]?.focus();
204
+ };
205
+ document.addEventListener('keydown', handleKeyDown);
206
+ return () => document.removeEventListener('keydown', handleKeyDown);
207
+ }, [tooltipSource, activeTokenIndex, tooltip]);
208
+ /**
209
+ * Moves focus into the tooltip after Enter opens it.
210
+ */
211
+ useEffect(() => {
212
+ if (!pendingEnterFocus.current || tooltipSource !== 'focus' || !tooltip) {
213
+ return;
214
+ }
215
+ pendingEnterFocus.current = false;
216
+ focusFirstTooltipControl();
217
+ }, [tooltip, tooltipSource]);
97
218
  /**
98
219
  * Keeps the colored backdrop aligned with horizontal scroll in the input.
99
220
  */
@@ -108,13 +229,22 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
108
229
  * Updates the tooltip based on the current text caret position.
109
230
  */
110
231
  const updateTooltipFromCaret = () => {
232
+ if (tooltipSourceRef.current === 'focus') {
233
+ return;
234
+ }
111
235
  const input = inputRef.current;
112
236
  if (!input)
113
237
  return;
114
- const offset = input.selectionStart ?? 0;
238
+ const selectionStart = input.selectionStart ?? 0;
239
+ const selectionEnd = input.selectionEnd ?? 0;
240
+ if (selectionStart !== selectionEnd) {
241
+ dismissTooltip();
242
+ return;
243
+ }
244
+ const offset = selectionStart;
115
245
  const match = getVariableTokenAtOffset(safeValue, offset);
116
246
  if (!match) {
117
- setTooltip(null);
247
+ dismissTooltip();
118
248
  return;
119
249
  }
120
250
  let tokenIndex = -1;
@@ -126,27 +256,77 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
126
256
  }
127
257
  position += token.text.length;
128
258
  }
129
- const span = tokenIndex >= 0 ? spanRefs.current.get(tokenIndex) : undefined;
130
- if (span) {
131
- const rect = span.getBoundingClientRect();
132
- showTooltipForKey(match.key, rect.top, rect.left + rect.width / 2);
259
+ const tokenButton = tokenIndex >= 0 ? tokenButtonRefs.current.get(tokenIndex) : undefined;
260
+ if (tokenButton) {
261
+ const rect = tokenButton.getBoundingClientRect();
262
+ showTooltipForKey(match.key, rect.top, rect.left + rect.width / 2, 'hover', null);
133
263
  return;
134
264
  }
135
265
  const rect = input.getBoundingClientRect();
136
- showTooltipForKey(match.key, rect.top, rect.left + rect.width / 2);
266
+ showTooltipForKey(match.key, rect.top, rect.left + rect.width / 2, 'hover', null);
267
+ };
268
+ /**
269
+ * Opens a focus-trapped tooltip for a keyboard-focused variable token.
270
+ *
271
+ * @param index - Token index within the rendered token list.
272
+ * @param key - Variable name from the {{key}} token.
273
+ * @param button - Focused token button element.
274
+ */
275
+ const handleTokenFocus = (index, key, button) => {
276
+ if (suppressReopen.current) {
277
+ suppressReopen.current = false;
278
+ return;
279
+ }
280
+ cancelHide();
281
+ cancelShow();
282
+ tooltipEntered.current = false;
283
+ const rect = button.getBoundingClientRect();
284
+ showTooltipForKey(key, rect.top, rect.left + rect.width / 2, 'focus', index);
285
+ };
286
+ /**
287
+ * Handles keyboard interaction on a variable token button.
288
+ */
289
+ const handleTokenKeyDown = (event, index, key) => {
290
+ if (event.key === 'Escape' && tooltipSource === 'focus' && activeTokenIndex != null) {
291
+ event.preventDefault();
292
+ event.stopPropagation();
293
+ dismissFocusTooltip(false);
294
+ return;
295
+ }
296
+ if (event.key !== 'Enter') {
297
+ return;
298
+ }
299
+ event.preventDefault();
300
+ if (tooltipSource === 'focus' && activeTokenIndex === index && tooltipRef.current) {
301
+ focusFirstTooltipControl();
302
+ return;
303
+ }
304
+ pendingEnterFocus.current = true;
305
+ const button = tokenButtonRefs.current.get(index);
306
+ if (!button) {
307
+ pendingEnterFocus.current = false;
308
+ return;
309
+ }
310
+ cancelHide();
311
+ cancelShow();
312
+ const rect = button.getBoundingClientRect();
313
+ showTooltipForKey(key, rect.top, rect.left + rect.width / 2, 'focus', index);
137
314
  };
138
315
  /**
139
316
  * Shows a tooltip when the pointer rests over a variable token span.
140
317
  */
141
318
  const handleMouseMove = (e) => {
319
+ if (tooltipSourceRef.current === 'focus') {
320
+ return;
321
+ }
142
322
  cancelHide();
143
323
  for (const [index, token] of tokens.entries()) {
144
324
  if (!token.key)
145
325
  continue;
146
- const span = spanRefs.current.get(index);
147
- if (!span)
326
+ const tokenButton = tokenButtonRefs.current.get(index);
327
+ if (!tokenButton)
148
328
  continue;
149
- const rect = span.getBoundingClientRect();
329
+ const rect = tokenButton.getBoundingClientRect();
150
330
  if (e.clientX >= rect.left &&
151
331
  e.clientX <= rect.right &&
152
332
  e.clientY >= rect.top &&
@@ -162,9 +342,28 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
162
342
  * Cancels a pending show and hides the tooltip when the pointer leaves the input.
163
343
  */
164
344
  const handleMouseLeave = () => {
345
+ if (tooltipSourceRef.current === 'focus') {
346
+ return;
347
+ }
165
348
  cancelShow();
166
349
  scheduleHide();
167
350
  };
351
+ /**
352
+ * Closes any open tooltip when focus leaves the field.
353
+ */
354
+ const handleWrapperBlur = () => {
355
+ const wrapper = wrapperRef.current;
356
+ if (!wrapper) {
357
+ return;
358
+ }
359
+ queueMicrotask(() => {
360
+ if (!wrapper.contains(document.activeElement)) {
361
+ cancelHide();
362
+ cancelShow();
363
+ dismissTooltip();
364
+ }
365
+ });
366
+ };
168
367
  /**
169
368
  * Handles keyboard events on the input, including tooltip dismissal.
170
369
  */
@@ -172,9 +371,9 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
172
371
  if (onInputKeyDown(event)) {
173
372
  return;
174
373
  }
175
- if (event.key === 'Escape' && tooltip) {
374
+ if (event.key === 'Escape' && tooltip && tooltipSource !== 'focus') {
176
375
  event.preventDefault();
177
- setTooltip(null);
376
+ dismissTooltip();
178
377
  return;
179
378
  }
180
379
  onKeyDown?.(event);
@@ -193,21 +392,36 @@ export function VariableInput({ value, onChange, variables, placeholder, onKeyDo
193
392
  }
194
393
  };
195
394
  const tooltipContent = tooltip ? getVariableTooltipContent(tooltip.key, variables) : null;
196
- return (_jsxs("div", { ...props, className: cn('hc-variable-input relative min-w-0', wrapperClassName ?? 'flex-1'), children: [_jsx("div", { ref: backdropRef, "aria-hidden": true, className: "hc-variable-input-backdrop pointer-events-none absolute inset-0 overflow-hidden px-2.5 py-1.5 whitespace-nowrap text-inherit", children: safeValue ? (tokens.map((token, index) => token.key ? (_jsx("span", { ref: (el) => {
395
+ const focusTooltipOpen = tooltipSource === 'focus' && tooltip != null;
396
+ return (_jsxs("div", { ...props, ref: wrapperRef, className: cn('hc-variable-input relative min-w-0', wrapperClassName ?? 'flex-1'), onBlurCapture: handleWrapperBlur, children: [_jsx("div", { ref: backdropRef, className: "hc-variable-input-backdrop pointer-events-none absolute inset-0 overflow-hidden px-2.5 py-1.5 whitespace-nowrap text-inherit", children: safeValue ? (tokens.map((token, index) => token.key ? (_jsx("button", { type: "button", ref: (el) => {
197
397
  if (el)
198
- spanRefs.current.set(index, el);
398
+ tokenButtonRefs.current.set(index, el);
199
399
  else
200
- spanRefs.current.delete(index);
201
- }, className: "hc-variable-input-token hc-variable-input-token-variable text-[#32D2E2]", children: token.text }, index)) : (_jsx("span", { className: "hc-variable-input-token", children: token.text }, index)))) : (_jsx("span", { className: "hc-variable-input-placeholder text-muted", children: placeholder })) }), _jsx(Input, { ref: inputRef, id: id, variant: "plain", role: source ? 'combobox' : undefined, "aria-autocomplete": source ? 'list' : undefined, "aria-expanded": source ? autocompleteOpen : undefined, "aria-controls": source && autocompleteOpen ? listboxId : undefined, "aria-activedescendant": source && autocompleteOpen && autocompleteActiveIndex >= 0
400
+ tokenButtonRefs.current.delete(index);
401
+ }, tabIndex: 0, "aria-label": `Variable ${token.key}`, "aria-expanded": focusTooltipOpen && activeTokenIndex === index ? true : undefined, "aria-describedby": focusTooltipOpen && activeTokenIndex === index ? tooltipId : undefined, className: cn('hc-variable-input-token hc-variable-input-token-variable font-inherit inline border-none bg-transparent p-0 text-[#32D2E2] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-accent'), onFocus: (event) => handleTokenFocus(index, token.key, event.currentTarget), onKeyDown: (event) => handleTokenKeyDown(event, index, token.key), children: token.text }, `${index}-${token.text}`)) : (_jsx("span", { "aria-hidden": true, className: "hc-variable-input-token", children: token.text }, `${index}-${token.text}`)))) : (_jsx("span", { "aria-hidden": true, className: "hc-variable-input-placeholder text-muted", children: placeholder })) }), _jsx(Input, { ref: inputRef, id: id, variant: "plain", role: source ? 'combobox' : undefined, "aria-autocomplete": source ? 'list' : undefined, "aria-expanded": source ? autocompleteOpen : undefined, "aria-controls": source && autocompleteOpen ? listboxId : undefined, "aria-activedescendant": source && autocompleteOpen && autocompleteActiveIndex >= 0
202
402
  ? `${listboxId}-option-${autocompleteActiveIndex}`
203
- : undefined, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": tooltip ? tooltipId : undefined, className: cn('hc-variable-input-field relative w-full min-w-0 border-none bg-transparent px-2.5 py-1.5 text-transparent caret-text focus-visible:shadow-none', className), type: "text", placeholder: placeholder, value: safeValue, onChange: (e) => {
403
+ : undefined, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": tooltip && tooltipSource !== 'focus' ? tooltipId : undefined, className: cn('hc-variable-input-field relative w-full min-w-0 border-none bg-transparent px-2.5 py-1.5 text-transparent caret-text focus-visible:shadow-none', className), type: "text", placeholder: placeholder, value: safeValue, onChange: (e) => {
204
404
  onChange(e.target.value);
205
405
  queueMicrotask(updateTooltipFromCaret);
206
406
  }, onFocus: () => {
407
+ if (tooltipSourceRef.current === 'focus') {
408
+ dismissTooltip();
409
+ }
207
410
  openAutocomplete();
208
- updateTooltipFromCaret();
209
- }, onBlur: closeAutocomplete, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onSelect: updateTooltipFromCaret, onClick: updateTooltipFromCaret, onScroll: syncScroll, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave }), source && (_jsx(SuggestionList, { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, anchorRef: inputRef, listboxId: listboxId, onSelect: selectItem, onActiveIndexChange: setActiveIndex, onClose: closeSuggestions })), tooltip && tooltipContent && (_jsxs("div", { id: tooltipId, role: "tooltip", className: "hc-variable-input-tooltip pointer-events-auto fixed z-50 flex max-w-sm -translate-x-1/2 -translate-y-full flex-col gap-2 rounded-lg border border-separator bg-surface px-4 py-3 text-text shadow-md after:pointer-events-auto after:absolute after:right-0 after:-bottom-2 after:left-0 after:h-2 after:content-['']", style: { top: tooltip.top - 4, left: tooltip.left }, onMouseEnter: cancelHide, onMouseLeave: scheduleHide, children: [_jsx(VariableTooltipValue, { value: tooltipContent.text, variableKey: tooltip.key, muted: tooltipContent.muted }), onEditVariable && (_jsx(Button, { variant: "secondary", className: "hc-variable-input-tooltip-edit self-start", "aria-label": `Edit value for ${tooltip.key}`, onClick: () => {
411
+ }, onBlur: closeAutocomplete, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onSelect: updateTooltipFromCaret, onClick: updateTooltipFromCaret, onScroll: syncScroll, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave }), source && (_jsx(SuggestionList, { open: autocompleteOpen, items: autocompleteItems, activeIndex: autocompleteActiveIndex, anchorRef: inputRef, listboxId: listboxId, onSelect: selectItem, onActiveIndexChange: setActiveIndex, onClose: closeSuggestions })), tooltip && tooltipContent && (_jsxs("div", { ref: tooltipRef, id: tooltipId, role: "tooltip", className: "hc-variable-input-tooltip pointer-events-auto fixed z-50 flex max-w-sm -translate-x-1/2 -translate-y-full flex-col gap-2 rounded-lg border border-separator bg-surface px-4 py-3 text-text shadow-md after:pointer-events-auto after:absolute after:right-0 after:-bottom-2 after:left-0 after:h-2 after:content-['']", style: { position: 'fixed', top: tooltip.top - 4, left: tooltip.left }, onMouseEnter: cancelHide, onMouseLeave: scheduleHide, children: [_jsx(VariableTooltipValue, { value: tooltipContent.text, variableKey: tooltip.key, muted: tooltipContent.muted, onClose: () => {
412
+ if (tooltipSource === 'focus') {
413
+ dismissFocusTooltip(true);
414
+ }
415
+ else {
416
+ dismissTooltip();
417
+ }
418
+ } }), onEditVariable && (_jsx(Button, { variant: "secondary", className: "hc-variable-input-tooltip-edit self-start", "aria-label": `Edit value for ${tooltip.key}`, onClick: () => {
210
419
  onEditVariable(tooltip.key);
211
- setTooltip(null);
420
+ if (tooltipSource === 'focus') {
421
+ dismissFocusTooltip(true);
422
+ }
423
+ else {
424
+ dismissTooltip();
425
+ }
212
426
  }, children: "Edit value" }))] }))] }));
213
427
  }
@@ -12,10 +12,14 @@ interface Props {
12
12
  * When true, styles the value as muted placeholder text.
13
13
  */
14
14
  muted?: boolean;
15
+ /**
16
+ * When provided, renders a close control to the right of the copy button.
17
+ */
18
+ onClose?: () => void;
15
19
  }
16
20
  /**
17
- * Readonly resolved-value field with a copy control for variable tooltips.
21
+ * Readonly resolved-value field with copy and optional close controls for variable tooltips.
18
22
  */
19
- export declare function VariableTooltipValue({ value, variableKey, muted }: Props): JSX.Element;
23
+ export declare function VariableTooltipValue({ value, variableKey, muted, onClose }: Props): JSX.Element;
20
24
  export {};
21
25
  //# sourceMappingURL=VariableTooltipValue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"VariableTooltipValue.d.ts","sourceRoot":"","sources":["../../../src/components/VariableTooltip/VariableTooltipValue.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAMjC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAkCtF"}
1
+ {"version":3,"file":"VariableTooltipValue.d.ts","sourceRoot":"","sources":["../../../src/components/VariableTooltip/VariableTooltipValue.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAMjC,UAAU,KAAK;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAgD/F"}
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
- import { faCircleCheck, faCopy } from '@fortawesome/free-solid-svg-icons';
2
+ import { faCircleCheck, faCopy, faXmark } from '@fortawesome/free-solid-svg-icons';
3
3
  import { useState } from '@harborclient/sdk/react';
4
4
  import { Button } from '../Button/index.js';
5
5
  import { FaIcon } from '../FaIcon/index.js';
6
6
  import { Input } from '../forms/index.js';
7
7
  import { cn } from '../utils.js';
8
8
  /**
9
- * Readonly resolved-value field with a copy control for variable tooltips.
9
+ * Readonly resolved-value field with copy and optional close controls for variable tooltips.
10
10
  */
11
- export function VariableTooltipValue({ value, variableKey, muted }) {
11
+ export function VariableTooltipValue({ value, variableKey, muted, onClose }) {
12
12
  const [copied, setCopied] = useState(false);
13
13
  /**
14
14
  * Copies the resolved value to the clipboard and briefly confirms success in the icon.
@@ -21,5 +21,7 @@ export function VariableTooltipValue({ value, variableKey, muted }) {
21
21
  };
22
22
  return (_jsxs("div", { className: "hc-variable-tooltip-value-row flex items-center gap-1.5", children: [_jsx(Input, { readOnly: true, value: value, "aria-label": `Resolved value for ${variableKey}`, className: cn('min-w-0 flex-1', muted && 'text-muted') }), _jsx(Button, { type: "button", variant: "icon", "aria-label": copied ? `Copied value for ${variableKey}` : `Copy value for ${variableKey}`, onMouseDown: (event) => {
23
23
  event.preventDefault();
24
- }, onClick: handleCopy, children: _jsx(FaIcon, { icon: copied ? faCircleCheck : faCopy, className: "h-4 w-4" }) })] }));
24
+ }, onClick: handleCopy, children: _jsx(FaIcon, { icon: copied ? faCircleCheck : faCopy, className: "h-4 w-4" }) }), onClose && (_jsx(Button, { type: "button", variant: "icon", className: "hc-variable-tooltip-close", "aria-label": `Close tooltip for ${variableKey}`, onMouseDown: (event) => {
25
+ event.preventDefault();
26
+ }, onClick: onClose, children: _jsx(FaIcon, { icon: faXmark, className: "h-4 w-4" }) }))] }));
25
27
  }
@@ -76,6 +76,6 @@ export { cleanVariables, resolveTabListKeyAction } from './utils.js';
76
76
  export type { TabListKeyOptions } from './utils.js';
77
77
  export { useDialogFocus, getFocusableElements } from './useDialogFocus.js';
78
78
  export { segment, segmentGroup, tabItem } from './classes.js';
79
- export { SidebarItem, SidebarListbox, SidebarList, SidebarTree, SidebarTreeGroup, handleSidebarOptionKeyDown, type SidebarItemListboxOption, type SidebarItemTreeItem, SortableSidebarItem, stopSortableDragPointerDown, SidebarColorDot, sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS, SidebarMethodBadge, SidebarStatusDot, SidebarStatusMarker, SidebarRequestItem, SidebarDocumentItem, SidebarFolderItem, SidebarRunItem, SidebarHistoryItem, SidebarEnvironmentItem, SidebarTabGroupItem, SidebarCommitItem, type SidebarItemSortableConfig } from './SidebarItem/index.js';
79
+ export { SidebarItem, SidebarListbox, SidebarList, SidebarTree, SidebarTreeGroup, handleSidebarOptionKeyDown, type SidebarItemListboxOption, type SidebarItemTreeItem, SortableSidebarItem, stopSortableDragPointerDown, SidebarColorDot, SidebarBadge, sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS, SidebarMethodBadge, SidebarStatusDot, SidebarStatusMarker, SidebarRequestItem, SidebarDocumentItem, SidebarFolderItem, SidebarRunItem, SidebarHistoryItem, SidebarEnvironmentItem, SidebarTabGroupItem, SidebarCommitItem, type SidebarItemSortableConfig, type SidebarBadgeVariant } from './SidebarItem/index.js';
80
80
  export type { FormDataPart, FormDataPartType, HttpMethod, KeyValue, Variable } from '../types.js';
81
81
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
@@ -57,4 +57,4 @@ export { VisibilityMenu } from './VisibilityMenu/index.js';
57
57
  export { cleanVariables, resolveTabListKeyAction } from './utils.js';
58
58
  export { useDialogFocus, getFocusableElements } from './useDialogFocus.js';
59
59
  export { segment, segmentGroup, tabItem } from './classes.js';
60
- export { SidebarItem, SidebarListbox, SidebarList, SidebarTree, SidebarTreeGroup, handleSidebarOptionKeyDown, SortableSidebarItem, stopSortableDragPointerDown, SidebarColorDot, sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS, SidebarMethodBadge, SidebarStatusDot, SidebarStatusMarker, SidebarRequestItem, SidebarDocumentItem, SidebarFolderItem, SidebarRunItem, SidebarHistoryItem, SidebarEnvironmentItem, SidebarTabGroupItem, SidebarCommitItem } from './SidebarItem/index.js';
60
+ export { SidebarItem, SidebarListbox, SidebarList, SidebarTree, SidebarTreeGroup, handleSidebarOptionKeyDown, SortableSidebarItem, stopSortableDragPointerDown, SidebarColorDot, SidebarBadge, sourceRow, METHOD_CLASSES, statusDotClass, SIDEBAR_ITEM_BUTTON_CLASS, SidebarMethodBadge, SidebarStatusDot, SidebarStatusMarker, SidebarRequestItem, SidebarDocumentItem, SidebarFolderItem, SidebarRunItem, SidebarHistoryItem, SidebarEnvironmentItem, SidebarTabGroupItem, SidebarCommitItem } from './SidebarItem/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"useDialogFocus.d.ts","sourceRoot":"","sources":["../../src/components/useDialogFocus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA8DvC;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,EAAE,CAU1E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CA8D5E"}
1
+ {"version":3,"file":"useDialogFocus.d.ts","sourceRoot":"","sources":["../../src/components/useDialogFocus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAuFvC;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,EAAE,CAI1E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,IAAI,CA8D5E"}
@@ -53,6 +53,27 @@ function unlockOverlaySiblings(siblings) {
53
53
  setInertLocked(sibling, false);
54
54
  }
55
55
  }
56
+ /**
57
+ * Returns whether a focusable element is visible enough to receive keyboard focus.
58
+ *
59
+ * @param element - Candidate focusable element.
60
+ */
61
+ function isFocusableVisible(element) {
62
+ if (element.closest('[aria-hidden="true"]')) {
63
+ return false;
64
+ }
65
+ if (element.offsetParent !== null || getComputedStyle(element).position === 'fixed') {
66
+ return true;
67
+ }
68
+ let parent = element.parentElement;
69
+ while (parent) {
70
+ if (getComputedStyle(parent).position === 'fixed') {
71
+ return true;
72
+ }
73
+ parent = parent.parentElement;
74
+ }
75
+ return false;
76
+ }
56
77
  /**
57
78
  * Returns visible, enabled focusable descendants of a container, excluding
58
79
  * elements inside `aria-hidden` subtrees.
@@ -62,14 +83,7 @@ function unlockOverlaySiblings(siblings) {
62
83
  */
63
84
  export function getFocusableElements(container) {
64
85
  const candidates = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
65
- return candidates.filter((element) => {
66
- if (element.closest('[aria-hidden="true"]'))
67
- return false;
68
- if (element.offsetParent === null && getComputedStyle(element).position !== 'fixed') {
69
- return false;
70
- }
71
- return true;
72
- });
86
+ return candidates.filter(isFocusableVisible);
73
87
  }
74
88
  /**
75
89
  * Traps keyboard focus within a dialog panel, inerts background siblings,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harborclient/sdk",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "TypeScript SDK for HarborClient development.",
5
5
  "keywords": [
6
6
  "harborclient",