@homebound/beam 4.42.1 → 4.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,95 +16,95 @@ import {
16
16
 
17
17
  // src/Css.ts
18
18
  import { __invertTrussMediaQuery, trussProps, useRuntimeStyle as _useRuntimeStyle } from "@homebound/truss/runtime";
19
- var Tokens = /* @__PURE__ */ ((Tokens65) => {
20
- Tokens65["AiFieldBg"] = "--b-ai-field-bg";
21
- Tokens65["AiFieldFg"] = "--b-ai-field-fg";
22
- Tokens65["ButtonCautionDisabledBg"] = "--b-button-caution-disabled-bg";
23
- Tokens65["ButtonCautionDisabledFg"] = "--b-button-caution-disabled-fg";
24
- Tokens65["ButtonDangerDisabledBg"] = "--b-button-danger-disabled-bg";
25
- Tokens65["ButtonDangerDisabledFg"] = "--b-button-danger-disabled-fg";
26
- Tokens65["ButtonGhostDisabledFg"] = "--b-button-ghost-disabled-fg";
27
- Tokens65["ButtonGhostFg"] = "--b-button-ghost-fg";
28
- Tokens65["ButtonPrimaryDisabledBg"] = "--b-button-primary-disabled-bg";
29
- Tokens65["ButtonPrimaryDisabledFg"] = "--b-button-primary-disabled-fg";
30
- Tokens65["ButtonSecondaryFg"] = "--b-button-secondary-fg";
31
- Tokens65["ButtonTertiaryFg"] = "--b-button-tertiary-fg";
32
- Tokens65["ButtonTertiaryFgPressed"] = "--b-button-tertiary-fg-pressed";
33
- Tokens65["ChoiceDisabled"] = "--b-choice-disabled";
34
- Tokens65["ChoiceSelected"] = "--b-choice-selected";
35
- Tokens65["Danger"] = "--b-danger";
36
- Tokens65["DangerPressed"] = "--b-danger-pressed";
37
- Tokens65["EnvBrandDev"] = "--b-env-brand-dev";
38
- Tokens65["EnvBrandLocalProd"] = "--b-env-brand-local-prod";
39
- Tokens65["EnvBrandProd"] = "--b-env-brand-prod";
40
- Tokens65["EnvBrandQa"] = "--b-env-brand-qa";
41
- Tokens65["FieldBgDefault"] = "--b-field-bg-default";
42
- Tokens65["FieldBgDisabled"] = "--b-field-bg-disabled";
43
- Tokens65["FieldBgHover"] = "--b-field-bg-hover";
44
- Tokens65["FieldBorderDefault"] = "--b-field-border-default";
45
- Tokens65["FieldBorderError"] = "--b-field-border-error";
46
- Tokens65["FieldBorderFocus"] = "--b-field-border-focus";
47
- Tokens65["FieldBorderHover"] = "--b-field-border-hover";
48
- Tokens65["FieldTextDisabled"] = "--b-field-text-disabled";
49
- Tokens65["FocusRingInset"] = "--b-focus-ring-inset";
50
- Tokens65["FocusRingMuted"] = "--b-focus-ring-muted";
51
- Tokens65["LoaderFill"] = "--b-loader-fill";
52
- Tokens65["LoaderSpinner"] = "--b-loader-spinner";
53
- Tokens65["LoaderTrack"] = "--b-loader-track";
54
- Tokens65["NavGlobalItemBgActive"] = "--b-nav-global-item-bg-active";
55
- Tokens65["NavGlobalItemBgHover"] = "--b-nav-global-item-bg-hover";
56
- Tokens65["NavGlobalItemBgPressed"] = "--b-nav-global-item-bg-pressed";
57
- Tokens65["NavGlobalText"] = "--b-nav-global-text";
58
- Tokens65["NavGlobalTextActive"] = "--b-nav-global-text-active";
59
- Tokens65["NavGlobalTextDisabled"] = "--b-nav-global-text-disabled";
60
- Tokens65["NavItemBgActive"] = "--b-nav-item-bg-active";
61
- Tokens65["NavItemBgHover"] = "--b-nav-item-bg-hover";
62
- Tokens65["NavItemBgPressed"] = "--b-nav-item-bg-pressed";
63
- Tokens65["NavText"] = "--b-nav-text";
64
- Tokens65["NavTextActive"] = "--b-nav-text-active";
65
- Tokens65["NavTextDisabled"] = "--b-nav-text-disabled";
66
- Tokens65["NavTextFocusVisible"] = "--b-nav-text-focus-visible";
67
- Tokens65["NavTextPressed"] = "--b-nav-text-pressed";
68
- Tokens65["NeutralFillHover"] = "--b-neutral-fill-hover";
69
- Tokens65["NeutralFillHoverStrong"] = "--b-neutral-fill-hover-strong";
70
- Tokens65["NeutralFillHoverSubtle"] = "--b-neutral-fill-hover-subtle";
71
- Tokens65["NeutralFillPressed"] = "--b-neutral-fill-pressed";
72
- Tokens65["NeutralSurfacePressed"] = "--b-neutral-surface-pressed";
73
- Tokens65["OnPrimary"] = "--b-on-primary";
74
- Tokens65["OnSurface"] = "--b-on-surface";
75
- Tokens65["OnSurfaceActive"] = "--b-on-surface-active";
76
- Tokens65["OnSurfaceActiveDisabled"] = "--b-on-surface-active-disabled";
77
- Tokens65["OnSurfaceDisabled"] = "--b-on-surface-disabled";
78
- Tokens65["OnSurfaceMuted"] = "--b-on-surface-muted";
79
- Tokens65["OnSurfaceRaisedHover"] = "--b-on-surface-raised-hover";
80
- Tokens65["OnSurfaceRaisedPressed"] = "--b-on-surface-raised-pressed";
81
- Tokens65["Primary"] = "--b-primary";
82
- Tokens65["PrimaryHover"] = "--b-primary-hover";
83
- Tokens65["PrimaryPressed"] = "--b-primary-pressed";
84
- Tokens65["Scrim"] = "--b-scrim";
85
- Tokens65["SelectionFill"] = "--b-selection-fill";
86
- Tokens65["SelectionIndicator"] = "--b-selection-indicator";
87
- Tokens65["Surface"] = "--b-surface";
88
- Tokens65["SurfaceActive"] = "--b-surface-active";
89
- Tokens65["SurfaceActiveBorder"] = "--b-surface-active-border";
90
- Tokens65["SurfaceActiveHover"] = "--b-surface-active-hover";
91
- Tokens65["SurfaceDisabled"] = "--b-surface-disabled";
92
- Tokens65["SurfaceHover"] = "--b-surface-hover";
93
- Tokens65["SurfaceRaised"] = "--b-surface-raised";
94
- Tokens65["SurfaceRaisedHover"] = "--b-surface-raised-hover";
95
- Tokens65["SurfaceRaisedPressed"] = "--b-surface-raised-pressed";
96
- Tokens65["SurfaceSeparator"] = "--b-surface-separator";
97
- Tokens65["SurfaceSubtle"] = "--b-surface-subtle";
98
- Tokens65["TextDisabled"] = "--b-text-disabled";
99
- Tokens65["TextHelper"] = "--b-text-helper";
100
- Tokens65["TextLabel"] = "--b-text-label";
101
- Tokens65["TextLinkDefault"] = "--b-text-link-default";
102
- Tokens65["TextLinkDisabled"] = "--b-text-link-disabled";
103
- Tokens65["TextLinkHover"] = "--b-text-link-hover";
104
- Tokens65["TextLinkPressed"] = "--b-text-link-pressed";
105
- Tokens65["TextPlaceholder"] = "--b-text-placeholder";
106
- Tokens65["TextSelection"] = "--b-text-selection";
107
- return Tokens65;
19
+ var Tokens = /* @__PURE__ */ ((Tokens69) => {
20
+ Tokens69["AiFieldBg"] = "--b-ai-field-bg";
21
+ Tokens69["AiFieldFg"] = "--b-ai-field-fg";
22
+ Tokens69["ButtonCautionDisabledBg"] = "--b-button-caution-disabled-bg";
23
+ Tokens69["ButtonCautionDisabledFg"] = "--b-button-caution-disabled-fg";
24
+ Tokens69["ButtonDangerDisabledBg"] = "--b-button-danger-disabled-bg";
25
+ Tokens69["ButtonDangerDisabledFg"] = "--b-button-danger-disabled-fg";
26
+ Tokens69["ButtonGhostDisabledFg"] = "--b-button-ghost-disabled-fg";
27
+ Tokens69["ButtonGhostFg"] = "--b-button-ghost-fg";
28
+ Tokens69["ButtonPrimaryDisabledBg"] = "--b-button-primary-disabled-bg";
29
+ Tokens69["ButtonPrimaryDisabledFg"] = "--b-button-primary-disabled-fg";
30
+ Tokens69["ButtonSecondaryFg"] = "--b-button-secondary-fg";
31
+ Tokens69["ButtonTertiaryFg"] = "--b-button-tertiary-fg";
32
+ Tokens69["ButtonTertiaryFgPressed"] = "--b-button-tertiary-fg-pressed";
33
+ Tokens69["ChoiceDisabled"] = "--b-choice-disabled";
34
+ Tokens69["ChoiceSelected"] = "--b-choice-selected";
35
+ Tokens69["Danger"] = "--b-danger";
36
+ Tokens69["DangerPressed"] = "--b-danger-pressed";
37
+ Tokens69["EnvBrandDev"] = "--b-env-brand-dev";
38
+ Tokens69["EnvBrandLocalProd"] = "--b-env-brand-local-prod";
39
+ Tokens69["EnvBrandProd"] = "--b-env-brand-prod";
40
+ Tokens69["EnvBrandQa"] = "--b-env-brand-qa";
41
+ Tokens69["FieldBgDefault"] = "--b-field-bg-default";
42
+ Tokens69["FieldBgDisabled"] = "--b-field-bg-disabled";
43
+ Tokens69["FieldBgHover"] = "--b-field-bg-hover";
44
+ Tokens69["FieldBorderDefault"] = "--b-field-border-default";
45
+ Tokens69["FieldBorderError"] = "--b-field-border-error";
46
+ Tokens69["FieldBorderFocus"] = "--b-field-border-focus";
47
+ Tokens69["FieldBorderHover"] = "--b-field-border-hover";
48
+ Tokens69["FieldTextDisabled"] = "--b-field-text-disabled";
49
+ Tokens69["FocusRingInset"] = "--b-focus-ring-inset";
50
+ Tokens69["FocusRingMuted"] = "--b-focus-ring-muted";
51
+ Tokens69["LoaderFill"] = "--b-loader-fill";
52
+ Tokens69["LoaderSpinner"] = "--b-loader-spinner";
53
+ Tokens69["LoaderTrack"] = "--b-loader-track";
54
+ Tokens69["NavGlobalItemBgActive"] = "--b-nav-global-item-bg-active";
55
+ Tokens69["NavGlobalItemBgHover"] = "--b-nav-global-item-bg-hover";
56
+ Tokens69["NavGlobalItemBgPressed"] = "--b-nav-global-item-bg-pressed";
57
+ Tokens69["NavGlobalText"] = "--b-nav-global-text";
58
+ Tokens69["NavGlobalTextActive"] = "--b-nav-global-text-active";
59
+ Tokens69["NavGlobalTextDisabled"] = "--b-nav-global-text-disabled";
60
+ Tokens69["NavItemBgActive"] = "--b-nav-item-bg-active";
61
+ Tokens69["NavItemBgHover"] = "--b-nav-item-bg-hover";
62
+ Tokens69["NavItemBgPressed"] = "--b-nav-item-bg-pressed";
63
+ Tokens69["NavText"] = "--b-nav-text";
64
+ Tokens69["NavTextActive"] = "--b-nav-text-active";
65
+ Tokens69["NavTextDisabled"] = "--b-nav-text-disabled";
66
+ Tokens69["NavTextFocusVisible"] = "--b-nav-text-focus-visible";
67
+ Tokens69["NavTextPressed"] = "--b-nav-text-pressed";
68
+ Tokens69["NeutralFillHover"] = "--b-neutral-fill-hover";
69
+ Tokens69["NeutralFillHoverStrong"] = "--b-neutral-fill-hover-strong";
70
+ Tokens69["NeutralFillHoverSubtle"] = "--b-neutral-fill-hover-subtle";
71
+ Tokens69["NeutralFillPressed"] = "--b-neutral-fill-pressed";
72
+ Tokens69["NeutralSurfacePressed"] = "--b-neutral-surface-pressed";
73
+ Tokens69["OnPrimary"] = "--b-on-primary";
74
+ Tokens69["OnSurface"] = "--b-on-surface";
75
+ Tokens69["OnSurfaceActive"] = "--b-on-surface-active";
76
+ Tokens69["OnSurfaceActiveDisabled"] = "--b-on-surface-active-disabled";
77
+ Tokens69["OnSurfaceDisabled"] = "--b-on-surface-disabled";
78
+ Tokens69["OnSurfaceMuted"] = "--b-on-surface-muted";
79
+ Tokens69["OnSurfaceRaisedHover"] = "--b-on-surface-raised-hover";
80
+ Tokens69["OnSurfaceRaisedPressed"] = "--b-on-surface-raised-pressed";
81
+ Tokens69["Primary"] = "--b-primary";
82
+ Tokens69["PrimaryHover"] = "--b-primary-hover";
83
+ Tokens69["PrimaryPressed"] = "--b-primary-pressed";
84
+ Tokens69["Scrim"] = "--b-scrim";
85
+ Tokens69["SelectionFill"] = "--b-selection-fill";
86
+ Tokens69["SelectionIndicator"] = "--b-selection-indicator";
87
+ Tokens69["Surface"] = "--b-surface";
88
+ Tokens69["SurfaceActive"] = "--b-surface-active";
89
+ Tokens69["SurfaceActiveBorder"] = "--b-surface-active-border";
90
+ Tokens69["SurfaceActiveHover"] = "--b-surface-active-hover";
91
+ Tokens69["SurfaceDisabled"] = "--b-surface-disabled";
92
+ Tokens69["SurfaceHover"] = "--b-surface-hover";
93
+ Tokens69["SurfaceRaised"] = "--b-surface-raised";
94
+ Tokens69["SurfaceRaisedHover"] = "--b-surface-raised-hover";
95
+ Tokens69["SurfaceRaisedPressed"] = "--b-surface-raised-pressed";
96
+ Tokens69["SurfaceSeparator"] = "--b-surface-separator";
97
+ Tokens69["SurfaceSubtle"] = "--b-surface-subtle";
98
+ Tokens69["TextDisabled"] = "--b-text-disabled";
99
+ Tokens69["TextHelper"] = "--b-text-helper";
100
+ Tokens69["TextLabel"] = "--b-text-label";
101
+ Tokens69["TextLinkDefault"] = "--b-text-link-default";
102
+ Tokens69["TextLinkDisabled"] = "--b-text-link-disabled";
103
+ Tokens69["TextLinkHover"] = "--b-text-link-hover";
104
+ Tokens69["TextLinkPressed"] = "--b-text-link-pressed";
105
+ Tokens69["TextPlaceholder"] = "--b-text-placeholder";
106
+ Tokens69["TextSelection"] = "--b-text-selection";
107
+ return Tokens69;
108
108
  })(Tokens || {});
109
109
  var Keyframes = /* @__PURE__ */ ((Keyframes2) => {
110
110
  Keyframes2["LoadingDots"] = "loadingDots";
@@ -7838,7 +7838,7 @@ function CompanionRowImpl(props) {
7838
7838
  companion,
7839
7839
  position = "trailing",
7840
7840
  levelIndent,
7841
- rowCss,
7841
+ rowCss: rowCss2,
7842
7842
  cellCss
7843
7843
  } = props;
7844
7844
  const RowTag = as === "table" ? "tr" : "div";
@@ -7871,7 +7871,7 @@ function CompanionRowImpl(props) {
7871
7871
  }]
7872
7872
  },
7873
7873
  ...isLastBodyRow && style.lastRowCss,
7874
- ...rowCss
7874
+ ...rowCss2
7875
7875
  }), "data-gridrow": true, ...tid[rowId], children: /* @__PURE__ */ jsx19(CellTag, { ...trussProps12({
7876
7876
  ...style.cellCss,
7877
7877
  ...style.betweenRowsCss,
@@ -10519,7 +10519,7 @@ function RowImpl(props) {
10519
10519
  }
10520
10520
  };
10521
10521
  const rowHoverBg = maybeCssVar(aiMode && !reservedRowKinds.includes(row.kind) ? "rgba(237, 233, 254, 1)" /* Purple100 */ : style.rowHoverColor !== void 0 && style.rowHoverColor !== "none" ? style.rowHoverColor : "--b-surface-hover" /* SurfaceHover */);
10522
- const rowCss = {
10522
+ const rowCss2 = {
10523
10523
  ...!reservedRowKinds.includes(row.kind) && style.nonHeaderRowCss,
10524
10524
  ...isFirstBodyRow && style.firstBodyRowCss,
10525
10525
  ...isFirstHeadRow && style.firstRowCss,
@@ -10559,7 +10559,7 @@ function RowImpl(props) {
10559
10559
  const ref = useRef12(null);
10560
10560
  const dragOverCallback = useCallback10((row2, evt) => onDragOver?.(row2, evt), [onDragOver]);
10561
10561
  const onDragOverDebounced = useDebouncedCallback3(dragOverCallback, 100);
10562
- const RowContent = () => /* @__PURE__ */ jsx32(RowTag, { ...mergeProps_12(`${BorderHoverParent}${showRowHoverColor ? ` ${RowHoverClass}` : ""}`, void 0, rowCss), ...others, "data-gridrow": true, ...getCount(row.id), ref, children: isKeptGroupRow ? /* @__PURE__ */ jsx32(KeptGroupRow, { as, style, columnSizes, row, colSpan: columns.length, isLastBodyRow }) : columns.map((column2, columnIndex) => {
10562
+ const RowContent = () => /* @__PURE__ */ jsx32(RowTag, { ...mergeProps_12(`${BorderHoverParent}${showRowHoverColor ? ` ${RowHoverClass}` : ""}`, void 0, rowCss2), ...others, "data-gridrow": true, ...getCount(row.id), ref, children: isKeptGroupRow ? /* @__PURE__ */ jsx32(KeptGroupRow, { as, style, columnSizes, row, colSpan: columns.length, isLastBodyRow }) : columns.map((column2, columnIndex) => {
10563
10563
  const maybeExpandedColumn = expandColumnHidden ? columns[columnIndex - 1] : column2;
10564
10564
  const isExpanded = tableState.isExpandedColumn(maybeExpandedColumn.id);
10565
10565
  if (column2.hideOnExpand && isExpanded) {
@@ -32340,12 +32340,1011 @@ function Autocomplete(props) {
32340
32340
  ] });
32341
32341
  }
32342
32342
 
32343
+ // src/inputs/MenuSelectField/internal/AnchoredOverlay.tsx
32344
+ import { useRef as useRef80 } from "react";
32345
+ import { FocusScope as FocusScope6 } from "react-aria";
32346
+
32347
+ // src/inputs/MenuSelectField/internal/useAnchoredPosition.ts
32348
+ import { useLayoutEffect as useLayoutEffect21 } from "react";
32349
+ import { useOverlayPosition as useOverlayPosition7 } from "react-aria";
32350
+ function useAnchoredPosition(triggerRef, popoverRef, isOpen2) {
32351
+ const { overlayProps, updatePosition } = useOverlayPosition7({
32352
+ targetRef: triggerRef,
32353
+ overlayRef: popoverRef,
32354
+ isOpen: isOpen2,
32355
+ shouldFlip: true,
32356
+ placement: "bottom start",
32357
+ offset: overlayOffset,
32358
+ containerPadding: viewportPadding,
32359
+ maxHeight: menuMaxHeight
32360
+ });
32361
+ useLayoutEffect21(() => {
32362
+ if (!isOpen2) return;
32363
+ const onScroll = (event) => {
32364
+ const target = event.target;
32365
+ if (!(target instanceof Node) || !triggerRef.current || !target.contains(triggerRef.current)) return;
32366
+ updatePosition();
32367
+ };
32368
+ window.addEventListener("scroll", onScroll, true);
32369
+ return () => window.removeEventListener("scroll", onScroll, true);
32370
+ }, [isOpen2, updatePosition, triggerRef]);
32371
+ useLayoutEffect21(() => {
32372
+ if (!isOpen2) return;
32373
+ applyMenuFrame(popoverRef.current, triggerRef.current);
32374
+ });
32375
+ return {
32376
+ ...overlayProps,
32377
+ style: {
32378
+ ...overlayProps.style,
32379
+ zIndex: zIndices.popover
32380
+ }
32381
+ };
32382
+ }
32383
+ var overlayOffset = 4;
32384
+ var viewportPadding = 8;
32385
+ var menuMaxHeight = 512;
32386
+ function applyMenuFrame(overlay, trigger) {
32387
+ if (!overlay) return;
32388
+ const height = overlay.style.maxHeight;
32389
+ if (height && overlay.style.getPropertyValue("--menu-max-height") !== height) {
32390
+ overlay.style.setProperty("--menu-max-height", height);
32391
+ }
32392
+ if (!trigger) return;
32393
+ const width2 = `${trigger.offsetWidth}px`;
32394
+ if (overlay.style.minWidth !== width2) overlay.style.minWidth = width2;
32395
+ }
32396
+
32397
+ // src/inputs/MenuSelectField/internal/AnchoredOverlay.tsx
32398
+ import { jsx as jsx265 } from "react/jsx-runtime";
32399
+ function AnchoredOverlay(props) {
32400
+ const { triggerRef, isOpen: isOpen2, onClose, children } = props;
32401
+ const popoverRef = useRef80(null);
32402
+ const tid = useTestIds(props, "anchoredOverlay");
32403
+ const positionProps = useAnchoredPosition(triggerRef, popoverRef, isOpen2);
32404
+ if (!isOpen2) return null;
32405
+ return /* @__PURE__ */ jsx265(
32406
+ Popover,
32407
+ {
32408
+ triggerRef,
32409
+ popoverRef,
32410
+ positionProps: { ...positionProps, ...tid.overlay },
32411
+ onClose,
32412
+ isOpen: isOpen2,
32413
+ shouldCloseOnInteractOutside: (el) => {
32414
+ if (!triggerRef.current?.contains(el) && shouldDismissOverlay(el, triggerRef.current)) onClose();
32415
+ return false;
32416
+ },
32417
+ children: /* @__PURE__ */ jsx265(FocusScope6, { children })
32418
+ }
32419
+ );
32420
+ }
32421
+
32422
+ // src/inputs/MenuSelectField/internal/BottomSheet.tsx
32423
+ import { useLayoutEffect as useLayoutEffect22, useRef as useRef81 } from "react";
32424
+ import { FocusScope as FocusScope7, mergeProps as mergeProps47, useDialog as useDialog2, useOverlay as useOverlay3, usePreventScroll as usePreventScroll4 } from "react-aria";
32425
+ import { createPortal as createPortal11 } from "react-dom";
32426
+ import { trussProps as trussProps151, maybeCssVar as maybeCssVar74 } from "@homebound/truss/runtime";
32427
+ import { jsx as jsx266, jsxs as jsxs142 } from "react/jsx-runtime";
32428
+ function BottomSheet(props) {
32429
+ const {
32430
+ isOpen: isOpen2,
32431
+ onClose,
32432
+ label,
32433
+ children
32434
+ } = props;
32435
+ const frameRef = useRef81(null);
32436
+ const sheetRef = useRef81(null);
32437
+ const contrast = useContrastScope();
32438
+ const tid = useTestIds(props, "bottomSheet");
32439
+ useVisualViewportFrame(frameRef, isOpen2);
32440
+ usePreventScroll4({
32441
+ isDisabled: !isOpen2
32442
+ });
32443
+ const {
32444
+ overlayProps,
32445
+ underlayProps
32446
+ } = useOverlay3({
32447
+ isOpen: isOpen2,
32448
+ onClose,
32449
+ isDismissable: true
32450
+ }, sheetRef);
32451
+ const {
32452
+ dialogProps
32453
+ } = useDialog2({
32454
+ "aria-label": label
32455
+ }, sheetRef);
32456
+ if (!isOpen2) return null;
32457
+ return createPortal11(/* @__PURE__ */ jsxs142("div", { ref: frameRef, ...trussProps151(frameCss), "data-theme": contrast ? contrastDataTheme : void 0, children: [
32458
+ /* @__PURE__ */ jsx266("div", { ...underlayProps, ...trussProps151(scrimCss), ...tid.sheetScrim }),
32459
+ /* @__PURE__ */ jsx266(FocusScope7, { contain: true, restoreFocus: true, children: /* @__PURE__ */ jsxs142("div", { ...mergeProps47(overlayProps, dialogProps), ref: sheetRef, ...trussProps151(sheetCss), ...tid.sheet, children: [
32460
+ /* @__PURE__ */ jsxs142("div", { ...trussProps151({
32461
+ display: "df",
32462
+ alignItems: "aic",
32463
+ justifyContent: "jcsb",
32464
+ gap: "g_1",
32465
+ paddingLeft: "pl2",
32466
+ paddingRight: "pr2",
32467
+ height: ["h_var", {
32468
+ "--height": `${sheetHeaderHeight}px`
32469
+ }],
32470
+ borderBottomStyle: "bbs_solid",
32471
+ borderBottomWidth: "bbw_1px",
32472
+ borderColor: ["bc_var", {
32473
+ "--borderColor": "var(--b-surface-separator)"
32474
+ }]
32475
+ }), children: [
32476
+ /* @__PURE__ */ jsx266("span", { className: "fw6 fz_14px lh_20px wsnw oh to_ellipsis", children: label }),
32477
+ /* @__PURE__ */ jsx266(Button, { label: "Done", variant: "tertiary", onClick: onClose, ...tid.sheetDone })
32478
+ ] }),
32479
+ children
32480
+ ] }) })
32481
+ ] }), document.body);
32482
+ }
32483
+ function useVisualViewportFrame(frameRef, isOpen2) {
32484
+ useLayoutEffect22(() => {
32485
+ const frame = frameRef.current;
32486
+ if (!isOpen2 || !frame) return;
32487
+ let raf = 0;
32488
+ const apply = () => {
32489
+ raf = 0;
32490
+ const vv = window.visualViewport;
32491
+ const top = vv?.offsetTop ?? 0;
32492
+ const height = vv?.height ?? window.innerHeight;
32493
+ frame.style.top = `${top}px`;
32494
+ frame.style.height = `${height}px`;
32495
+ frame.style.setProperty("--menu-max-height", `${Math.max(0, Math.round(height * sheetMaxRatio) - sheetHeaderHeight)}px`);
32496
+ };
32497
+ const schedule = () => {
32498
+ if (!raf) raf = requestAnimationFrame(apply);
32499
+ };
32500
+ apply();
32501
+ window.visualViewport?.addEventListener("resize", schedule);
32502
+ window.visualViewport?.addEventListener("scroll", schedule);
32503
+ window.addEventListener("resize", schedule);
32504
+ return () => {
32505
+ if (raf) cancelAnimationFrame(raf);
32506
+ window.visualViewport?.removeEventListener("resize", schedule);
32507
+ window.visualViewport?.removeEventListener("scroll", schedule);
32508
+ window.removeEventListener("resize", schedule);
32509
+ };
32510
+ }, [frameRef, isOpen2]);
32511
+ }
32512
+ var sheetHeaderHeight = 48;
32513
+ var sheetMaxRatio = 0.85;
32514
+ var frameCss = {
32515
+ position: "fixed",
32516
+ left: "l_0",
32517
+ width: "w100",
32518
+ top: "top0",
32519
+ display: "df",
32520
+ flexDirection: "fdc",
32521
+ justifyContent: "jcfe",
32522
+ zIndex: ["z_var", {
32523
+ "--zIndex": maybeCssVar74(zIndices.popover)
32524
+ }]
32525
+ };
32526
+ var scrimCss = {
32527
+ position: "absolute",
32528
+ inset: "ins_0",
32529
+ backgroundColor: ["bgColor_var", {
32530
+ "--backgroundColor": "var(--b-scrim)"
32531
+ }]
32532
+ };
32533
+ var sheetCss = {
32534
+ ...{
32535
+ position: "relative",
32536
+ display: "df",
32537
+ flexDirection: "fdc",
32538
+ width: "w100",
32539
+ backgroundColor: ["bgColor_var", {
32540
+ "--backgroundColor": "var(--b-surface-raised)"
32541
+ }],
32542
+ color: ["color_var", {
32543
+ "--color": "var(--b-on-surface)"
32544
+ }],
32545
+ boxShadow: "bshModal",
32546
+ outline: "ol_0",
32547
+ bottom: "bot_0px"
32548
+ },
32549
+ ...{
32550
+ borderTopLeftRadius: "btlr_12px",
32551
+ borderTopRightRadius: "btrr_12px",
32552
+ paddingBottom: "pb_env_safe_area_inset_bottom"
32553
+ }
32554
+ };
32555
+
32556
+ // src/inputs/MenuSelectField/internal/MenuPanel.tsx
32557
+ import { trussProps as trussProps152 } from "@homebound/truss/runtime";
32558
+ import { jsx as jsx267, jsxs as jsxs143 } from "react/jsx-runtime";
32559
+ function MenuPanel(props) {
32560
+ const {
32561
+ header,
32562
+ children,
32563
+ variant = "anchored"
32564
+ } = props;
32565
+ const tid = useTestIds(props, "menuPanel");
32566
+ return /* @__PURE__ */ jsxs143("div", { ...trussProps152({
32567
+ ...panelCss,
32568
+ ...variant === "anchored" ? anchoredCss : {}
32569
+ }), ...tid.menuPanel, children: [
32570
+ header && /* @__PURE__ */ jsx267("div", { ...trussProps152({
32571
+ flexShrink: "fs0",
32572
+ borderBottomStyle: "bbs_solid",
32573
+ borderBottomWidth: "bbw_1px",
32574
+ borderColor: ["bc_var", {
32575
+ "--borderColor": "var(--b-surface-separator)"
32576
+ }]
32577
+ }), children: header }),
32578
+ /* @__PURE__ */ jsx267("div", { className: "df fdc fg1 mh0", children })
32579
+ ] });
32580
+ }
32581
+ var panelCss = {
32582
+ display: "df",
32583
+ flexDirection: "fdc",
32584
+ width: "w100",
32585
+ overflow: "oh",
32586
+ color: ["color_var", {
32587
+ "--color": "var(--b-on-surface)"
32588
+ }],
32589
+ maxHeight: "maxh_var_menu_max_height_512px"
32590
+ };
32591
+ var anchoredCss = {
32592
+ backgroundColor: ["bgColor_var", {
32593
+ "--backgroundColor": "var(--b-surface-raised)"
32594
+ }],
32595
+ borderRadius: "br4",
32596
+ boxShadow: "bshBasic"
32597
+ };
32598
+
32599
+ // src/inputs/MenuSelectField/internal/MenuSearchInput.tsx
32600
+ import { trussProps as trussProps153 } from "@homebound/truss/runtime";
32601
+ import { jsx as jsx268, jsxs as jsxs144 } from "react/jsx-runtime";
32602
+ function MenuSearchInput(props) {
32603
+ const {
32604
+ search,
32605
+ inputRef,
32606
+ label,
32607
+ placeholder = "Search"
32608
+ } = props;
32609
+ const tid = useTestIds(props, "menuSearch");
32610
+ return /* @__PURE__ */ jsxs144("label", { className: "df aic g_1 pl2 pr2 h_48px cur_text", children: [
32611
+ /* @__PURE__ */ jsx268("span", { ...trussProps153({
32612
+ display: "df",
32613
+ alignItems: "aic",
32614
+ flexShrink: "fs0",
32615
+ color: ["color_var", {
32616
+ "--color": "var(--b-on-surface-muted)"
32617
+ }]
32618
+ }), children: /* @__PURE__ */ jsx268(Icon, { icon: "search" }) }),
32619
+ /* @__PURE__ */ jsx268("input", { ref: inputRef, type: "text", role: "combobox", "aria-label": label, "aria-autocomplete": "list", "aria-expanded": true, "aria-controls": search.listId, "aria-activedescendant": search.activeDescendant, autoComplete: "off", autoCorrect: "off", spellCheck: false, enterKeyHint: "done", placeholder, value: search.value, onChange: (e) => search.onChange(e.target.value), onKeyDown: search.onKeyDown, ...trussProps153(inputCss), ...tid.search })
32620
+ ] });
32621
+ }
32622
+ var inputCss = {
32623
+ ...{
32624
+ flexGrow: "fg1",
32625
+ minWidth: "mw0",
32626
+ outline: "ol_0",
32627
+ backgroundColor: "bgTransparent",
32628
+ fontWeight: "fw4",
32629
+ fontSize: "fz_14px",
32630
+ lineHeight: "lh_20px",
32631
+ color: ["color_var", {
32632
+ "--color": "var(--b-on-surface)"
32633
+ }]
32634
+ },
32635
+ // iOS zooms the page when a focused input is under 16px.
32636
+ ...{
32637
+ fontSize: "sm_fs_16px"
32638
+ }
32639
+ };
32640
+
32641
+ // src/inputs/MenuSelectField/internal/MenuSelectTrigger.tsx
32642
+ import { mergeProps as mergeProps48 } from "react-aria";
32643
+ import { trussProps as trussProps154, mergeProps as mergeProps_15, maybeCssVar as maybeCssVar75 } from "@homebound/truss/runtime";
32644
+ import { Fragment as Fragment56, jsx as jsx269, jsxs as jsxs145 } from "react/jsx-runtime";
32645
+ function MenuSelectTrigger(props) {
32646
+ const {
32647
+ label,
32648
+ required,
32649
+ errorMsg,
32650
+ helperText,
32651
+ disabled,
32652
+ readOnly,
32653
+ labelStyle: labelStyleProp,
32654
+ inputStylePalette,
32655
+ trigger,
32656
+ triggerRef
32657
+ } = props;
32658
+ const internalProps = props.internalProps ?? {};
32659
+ const {
32660
+ compound = false,
32661
+ forceFocus = false,
32662
+ forceHover = false
32663
+ } = internalProps;
32664
+ const tid = useTestIds(props, defaultTestId(label));
32665
+ const {
32666
+ fieldProps
32667
+ } = usePresentationContext();
32668
+ const labelStyle = labelStyleProp ?? fieldProps?.labelStyle ?? "above";
32669
+ const compact = props.compact ?? fieldProps?.compact ?? false;
32670
+ const borderless = props.borderless ?? fieldProps?.borderless ?? false;
32671
+ const borderOnHover = props.borderOnHover ?? fieldProps?.borderOnHover ?? false;
32672
+ const fullWidth = props.fullWidth ?? fieldProps?.fullWidth ?? false;
32673
+ const visuallyDisabled = props.visuallyDisabled ?? fieldProps?.visuallyDisabled ?? true;
32674
+ const errorInTooltip = props.errorInTooltip ?? fieldProps?.errorInTooltip ?? false;
32675
+ const typeScale = fieldProps?.typeScale ?? "sm";
32676
+ const labelSuffix = useLabelSuffix(required, trigger.isReadOnly);
32677
+ const showFocus = (trigger.isFocusVisible || trigger.isOpen) && !trigger.isDisabled && !trigger.isReadOnly || forceFocus;
32678
+ const showHover = trigger.isHovered && !trigger.isDisabled && !trigger.isReadOnly && !showFocus || forceHover;
32679
+ const showErrorAndHelper = !compound && !trigger.isDisabled && !trigger.isReadOnly;
32680
+ const {
32681
+ proposedValue: proposedText,
32682
+ originalValue: originalText
32683
+ } = trigger.proposalProps;
32684
+ const showProposal = proposedText !== void 0;
32685
+ const originalBelow = originalText && !trigger.isReadOnly ? originalText : void 0;
32686
+ const fieldChrome = getFieldChrome({
32687
+ typeScale,
32688
+ labelStyle,
32689
+ labelLeftFieldWidth: fieldProps?.labelLeftFieldWidth,
32690
+ compact,
32691
+ borderless,
32692
+ borderOnHover,
32693
+ fullWidth,
32694
+ compound,
32695
+ visuallyDisabled,
32696
+ isHovered: trigger.isHovered || forceHover,
32697
+ showProposal,
32698
+ inputStylePalette
32699
+ });
32700
+ const fieldStateCss = {
32701
+ ...fieldChrome.control,
32702
+ ...trigger.isDisabled ? fieldChrome.disabled : {},
32703
+ ...showFocus ? fieldChrome.focus : {},
32704
+ ...showHover ? fieldChrome.hover : {},
32705
+ ...errorMsg && !trigger.isDisabled ? fieldChrome.error : {},
32706
+ ...{
32707
+ textAlign: "tal",
32708
+ outline: "ol_0",
32709
+ appearance: "app_none",
32710
+ font: "fnt_inherit",
32711
+ ...!trigger.isDisabled ? {
32712
+ cursor: "cur_pointer"
32713
+ } : {}
32714
+ }
32715
+ };
32716
+ const supporting = /* @__PURE__ */ jsxs145(Fragment56, { children: [
32717
+ originalBelow && /* @__PURE__ */ jsx269(OriginalValue, { originalValue: originalBelow, ...tid.originalValue }),
32718
+ showErrorAndHelper && errorMsg && !errorInTooltip && /* @__PURE__ */ jsx269(ErrorMessage, { id: trigger.errorId, errorMsg, ...tid.errorMsg }),
32719
+ showErrorAndHelper && helperText && /* @__PURE__ */ jsx269(HelperText, { helperText, ...tid.helperText })
32720
+ ] });
32721
+ const hasSupporting = !!(originalBelow || showErrorAndHelper && (errorMsg || helperText));
32722
+ const valueNode = /* @__PURE__ */ jsxs145(Fragment56, { children: [
32723
+ labelStyle === "inline" && /* @__PURE__ */ jsxs145("span", { id: trigger.labelId, ...trussProps154({
32724
+ fontWeight: "fw4",
32725
+ fontSize: "fz_14px",
32726
+ lineHeight: "lh_20px",
32727
+ whiteSpace: "wsnw",
32728
+ paddingRight: "pr_4px",
32729
+ color: ["color_var", {
32730
+ "--color": maybeCssVar75(trigger.isDisabled && visuallyDisabled ? "currentColor" : "--b-text-label" /* TextLabel */)
32731
+ }]
32732
+ }), children: [
32733
+ label,
32734
+ ":"
32735
+ ] }),
32736
+ /* @__PURE__ */ jsx269("span", { id: trigger.valueId, className: "df aic fg1 mw0 oh", children: trigger.isReadOnly && showProposal ? /* @__PURE__ */ jsx269("span", { className: "fg1 wsnw oh to_ellipsis", children: /* @__PURE__ */ jsx269(ProposedValue, { original: originalText, proposed: proposedText, ...tid.proposedValue }) }) : /* @__PURE__ */ jsx269("span", { ...trussProps154({
32737
+ ...{
32738
+ flexGrow: "fg1",
32739
+ whiteSpace: "wsnw",
32740
+ overflow: "oh",
32741
+ textOverflow: "to_ellipsis",
32742
+ color: ["color_var", {
32743
+ "--color": maybeCssVar75(trigger.isPlaceholder ? inputPlaceholderColor : void 0)
32744
+ }]
32745
+ },
32746
+ // A placeholder reads as hint text, so it stays at the field's regular weight.
32747
+ ...!trigger.isPlaceholder ? selectedValueCss(labelStyle, trigger.isReadOnly) : {},
32748
+ ...showProposal ? {
32749
+ fontWeight: "fw6",
32750
+ color: ["color_var", {
32751
+ "--color": "var(--b-ai-field-fg)"
32752
+ }]
32753
+ } : {}
32754
+ }), children: trigger.displayText }) }),
32755
+ errorInTooltip && errorMsg && showErrorAndHelper && /* @__PURE__ */ jsx269("span", { className: "df aic fs0 pl1", children: /* @__PURE__ */ jsx269(Icon, { icon: "error", color: "--b-danger" /* Danger */, tooltip: errorMsg }) }),
32756
+ !trigger.isReadOnly && /* @__PURE__ */ jsx269("span", { ...trussProps154({
32757
+ display: "df",
32758
+ alignItems: "aic",
32759
+ flexShrink: "fs0",
32760
+ paddingLeft: "pl1",
32761
+ color: ["color_var", {
32762
+ "--color": maybeCssVar75(trigger.isDisabled ? "--b-field-text-disabled" /* FieldTextDisabled */ : "--b-text-placeholder" /* TextPlaceholder */)
32763
+ }]
32764
+ }), ...tid.toggle, children: /* @__PURE__ */ jsx269(Icon, { icon: trigger.isOpen ? "chevronUp" : "chevronDown" }) })
32765
+ ] });
32766
+ return /* @__PURE__ */ jsxs145(Fragment56, { children: [
32767
+ /* @__PURE__ */ jsxs145("div", { ...trussProps154(fieldChrome.container), children: [
32768
+ label && labelStyle !== "inline" && /* @__PURE__ */ jsx269(Label, { labelProps: {
32769
+ id: trigger.labelId,
32770
+ htmlFor: trigger.isReadOnly ? void 0 : trigger.triggerId,
32771
+ onClick: (event) => {
32772
+ event.preventDefault();
32773
+ if (trigger.isDisabled || trigger.isReadOnly || trigger.isOpen) return;
32774
+ triggerRef.current?.focus();
32775
+ trigger.open();
32776
+ }
32777
+ }, hidden: labelStyle === "hidden", label, inline: labelStyle === "left", suffix: labelSuffix, ...tid.label }),
32778
+ maybeTooltip({
32779
+ title: resolveTooltip(disabled, void 0, readOnly),
32780
+ placement: "top",
32781
+ children: trigger.isReadOnly ? /* @__PURE__ */ jsx269("div", { ...trussProps154(fieldChrome.readOnly), "data-readonly": "true", "data-ai-mode": showProposal ? "true" : void 0, ...tid, children: valueNode }) : /* @__PURE__ */ jsx269("button", { ...mergeProps48(trigger.hoverProps, trigger.focusProps, {
32782
+ id: trigger.triggerId,
32783
+ type: "button",
32784
+ disabled: trigger.isDisabled,
32785
+ "aria-haspopup": "listbox",
32786
+ "aria-expanded": trigger.isOpen,
32787
+ "aria-controls": trigger.listId,
32788
+ "aria-labelledby": `${trigger.labelId} ${trigger.valueId}`,
32789
+ "aria-invalid": errorMsg ? true : void 0,
32790
+ "aria-errormessage": errorMsg ? trigger.errorId : void 0,
32791
+ "data-ai-mode": showProposal ? "true" : void 0,
32792
+ onKeyDown: trigger.onKeyDown,
32793
+ onClick: () => trigger.isOpen ? trigger.close({
32794
+ restoreFocus: true
32795
+ }) : trigger.open(),
32796
+ onFocus: trigger.onFocus,
32797
+ onBlur: trigger.onBlur
32798
+ }), ref: triggerRef, ...mergeProps_15(BorderHoverChild, void 0, fieldStateCss), ...tid, children: valueNode })
32799
+ }),
32800
+ labelStyle !== "left" && supporting
32801
+ ] }),
32802
+ labelStyle === "left" && hasSupporting && /* @__PURE__ */ jsx269("div", { className: "mt_neg1 ml_50", children: supporting })
32803
+ ] });
32804
+ }
32805
+ var inputPlaceholderColor = "#9ca3af";
32806
+
32807
+ // src/inputs/MenuSelectField/internal/OptionList.tsx
32808
+ import { getInteractionModality as getInteractionModality2 } from "@react-aria/interactions";
32809
+ import { useEffect as useEffect42, useLayoutEffect as useLayoutEffect23, useRef as useRef83, useState as useState70 } from "react";
32810
+ import { useListBox as useListBox2 } from "react-aria";
32811
+ import { Virtuoso as Virtuoso3 } from "react-virtuoso";
32812
+
32813
+ // src/inputs/MenuSelectField/internal/OptionRow.tsx
32814
+ import { useRef as useRef82 } from "react";
32815
+ import { mergeProps as mergeProps49, useHover as useHover26, useOption as useOption3 } from "react-aria";
32816
+ import { trussProps as trussProps155 } from "@homebound/truss/runtime";
32817
+ import { jsx as jsx270, jsxs as jsxs146 } from "react/jsx-runtime";
32818
+ function OptionRow(props) {
32819
+ const {
32820
+ item,
32821
+ state,
32822
+ id,
32823
+ disabledReason
32824
+ } = props;
32825
+ const ref = useRef82(null);
32826
+ const tid = useTestIds(props, "option");
32827
+ const {
32828
+ hoverProps,
32829
+ isHovered
32830
+ } = useHover26({});
32831
+ const {
32832
+ optionProps,
32833
+ isDisabled,
32834
+ isFocused,
32835
+ isSelected
32836
+ } = useOption3({
32837
+ key: item.key,
32838
+ shouldSelectOnPressUp: true,
32839
+ shouldFocusOnHover: false
32840
+ }, state, ref);
32841
+ const highlighted = !isDisabled && (isHovered || isFocused);
32842
+ return maybeTooltip({
32843
+ title: disabledReason,
32844
+ placement: "top",
32845
+ children: /* @__PURE__ */ jsxs146(
32846
+ "div",
32847
+ {
32848
+ ...mergeProps49(optionProps, hoverProps),
32849
+ id,
32850
+ "data-key": item.key,
32851
+ "data-label": item.textValue,
32852
+ ref,
32853
+ ...trussProps155({
32854
+ ...rowCss,
32855
+ ...highlighted ? {
32856
+ backgroundColor: ["bgColor_var", {
32857
+ "--backgroundColor": "var(--b-surface-raised-hover)"
32858
+ }]
32859
+ } : {},
32860
+ ...isDisabled ? {
32861
+ cursor: "cur_not_allowed",
32862
+ color: ["color_var", {
32863
+ "--color": "var(--b-text-disabled)"
32864
+ }]
32865
+ } : {}
32866
+ }),
32867
+ ...tid.option,
32868
+ children: [
32869
+ /* @__PURE__ */ jsx270("span", { className: "wsnw oh to_ellipsis fg1 mw0", children: item.rendered }),
32870
+ isSelected && /* @__PURE__ */ jsx270("span", { className: "df aic fs0", children: /* @__PURE__ */ jsx270(Icon, { icon: "check", color: isDisabled ? "--b-text-disabled" /* TextDisabled */ : "--b-selection-indicator" /* SelectionIndicator */ }) })
32871
+ ]
32872
+ }
32873
+ )
32874
+ });
32875
+ }
32876
+ var menuRowHeight = 40;
32877
+ var rowCss = {
32878
+ display: "df",
32879
+ alignItems: "aic",
32880
+ gap: "g_1",
32881
+ paddingLeft: "pl2",
32882
+ paddingRight: "pr2",
32883
+ height: ["h_var", {
32884
+ "--height": `${menuRowHeight}px`
32885
+ }],
32886
+ outline: "ol_0",
32887
+ cursor: "cur_pointer",
32888
+ fontWeight: "fw4",
32889
+ fontSize: "fz_14px",
32890
+ lineHeight: "lh_20px",
32891
+ color: ["color_var", {
32892
+ "--color": "var(--b-on-surface)"
32893
+ }]
32894
+ };
32895
+
32896
+ // src/inputs/MenuSelectField/internal/OptionList.tsx
32897
+ import { trussProps as trussProps156 } from "@homebound/truss/runtime";
32898
+ import { Fragment as Fragment57, jsx as jsx271, jsxs as jsxs147 } from "react/jsx-runtime";
32899
+ function OptionList(props) {
32900
+ const {
32901
+ menu,
32902
+ listRef,
32903
+ label,
32904
+ onKeyDown,
32905
+ activeDescendant
32906
+ } = props;
32907
+ const {
32908
+ state,
32909
+ listId: id,
32910
+ disabledReasons,
32911
+ initialIndex,
32912
+ loading
32913
+ } = menu;
32914
+ const tid = useTestIds(props, "optionList");
32915
+ const virtuosoRef = useRef83(null);
32916
+ const {
32917
+ listBoxProps
32918
+ } = useListBox2({
32919
+ id,
32920
+ "aria-label": label,
32921
+ autoFocus: false,
32922
+ shouldUseVirtualFocus: true,
32923
+ shouldFocusOnHover: false,
32924
+ shouldSelectOnPressUp: true,
32925
+ isVirtualized: true
32926
+ }, state, listRef);
32927
+ const items = [...state.collection];
32928
+ const focusedKey = state.selectionManager.focusedKey;
32929
+ useEffect42(() => {
32930
+ if (focusedKey == null || getInteractionModality2() !== "keyboard") return;
32931
+ const index = state.collection.getItem(focusedKey)?.index;
32932
+ if (index !== void 0) virtuosoRef.current?.scrollIntoView({
32933
+ index,
32934
+ behavior: "auto"
32935
+ });
32936
+ }, [focusedKey, state.collection]);
32937
+ const [{
32938
+ initialTop,
32939
+ initialCount
32940
+ }] = useState70(() => ({
32941
+ initialTop: Math.max(0, Math.min(initialIndex, items.length - 1)),
32942
+ initialCount: items.length
32943
+ }));
32944
+ const syncScroll = initialTop + initialRenderCount <= maxSyncRenderCount;
32945
+ useLayoutEffect23(() => {
32946
+ const scroller = listRef.current?.firstElementChild;
32947
+ if (!syncScroll || !scroller) return;
32948
+ const maxTop = Math.max(0, initialCount * menuRowHeight - scroller.clientHeight);
32949
+ setScrollTop(scroller, Math.min(initialTop * menuRowHeight, maxTop));
32950
+ }, [listRef, syncScroll, initialTop, initialCount]);
32951
+ const isTest = process.env.NODE_ENV === "test";
32952
+ return /* @__PURE__ */ jsx271("div", { ...listBoxProps, ...onKeyDown ? {
32953
+ onKeyDown,
32954
+ tabIndex: -1,
32955
+ "aria-activedescendant": activeDescendant
32956
+ } : {}, ref: listRef, className: "df fdc fg1 mh0 ol_0", ...tid.listbox, children: items.length === 0 && !loading ? /* @__PURE__ */ jsx271("div", { role: "presentation", ...trussProps156(emptyCss), ...tid.empty, children: "No results" }) : /* @__PURE__ */ jsxs147(Fragment57, { children: [
32957
+ items.length > 0 && /* @__PURE__ */ jsx271(Virtuoso3, { ref: virtuosoRef, style: {
32958
+ height: items.length * menuRowHeight,
32959
+ flexShrink: 1,
32960
+ minHeight: 0,
32961
+ overscrollBehavior: "contain"
32962
+ }, totalCount: items.length, fixedItemHeight: menuRowHeight, computeItemKey: (index) => String(items[index]?.key ?? index), ...isTest ? {
32963
+ initialItemCount: items.length
32964
+ } : syncScroll ? {
32965
+ initialItemCount: Math.min(items.length, initialTop + initialRenderCount)
32966
+ } : {
32967
+ initialTopMostItemIndex: initialTop
32968
+ }, itemContent: (index) => {
32969
+ const item = items[index];
32970
+ if (!item) return null;
32971
+ return /* @__PURE__ */ jsx271(OptionRow, { item, state, id: optionDomId(id, index), disabledReason: disabledReasons[String(item.key)], ...tid });
32972
+ } }, isTest ? items.length : "virtuoso"),
32973
+ loading && /* @__PURE__ */ jsx271(LoadingDots, {})
32974
+ ] }) });
32975
+ }
32976
+ function optionDomId(listId, index) {
32977
+ return `${listId}-option-${index}`;
32978
+ }
32979
+ function setScrollTop(el, top) {
32980
+ el.scrollTop = top;
32981
+ }
32982
+ var initialRenderCount = 13;
32983
+ var maxSyncRenderCount = 60;
32984
+ var emptyCss = {
32985
+ display: "df",
32986
+ alignItems: "aic",
32987
+ paddingLeft: "pl2",
32988
+ paddingRight: "pr2",
32989
+ height: ["h_var", {
32990
+ "--height": `${menuRowHeight}px`
32991
+ }],
32992
+ fontWeight: "fw4",
32993
+ fontSize: "fz_14px",
32994
+ lineHeight: "lh_20px",
32995
+ color: ["color_var", {
32996
+ "--color": "var(--b-on-surface-muted)"
32997
+ }]
32998
+ };
32999
+
33000
+ // src/inputs/MenuSelectField/internal/useMenuSelectField.tsx
33001
+ import { useId as useId6, useLayoutEffect as useLayoutEffect24, useMemo as useMemo61, useRef as useRef84, useState as useState71 } from "react";
33002
+ import { ListKeyboardDelegate, useFilter as useFilter5, useFocusRing as useFocusRing23, useHover as useHover27 } from "react-aria";
33003
+ import { Item as Item6, useListState } from "react-stately";
33004
+ import { jsx as jsx272 } from "react/jsx-runtime";
33005
+ function useMenuSelectField(props) {
33006
+ const {
33007
+ options: optionsProp,
33008
+ getOptionValue = defaultOptionValue,
33009
+ getOptionLabel = defaultOptionLabel,
33010
+ getOptionMenuLabel,
33011
+ getOptionSearchText,
33012
+ disabledOptions,
33013
+ nothingSelectedText = "",
33014
+ placeholder,
33015
+ disabled,
33016
+ readOnly,
33017
+ onFocus,
33018
+ onBlur,
33019
+ value: propValue,
33020
+ proposedValue,
33021
+ onSelect
33022
+ } = props;
33023
+ const isDisabled = !!disabled;
33024
+ const isReadOnly = !!readOnly;
33025
+ const fieldId = useId6();
33026
+ const listId = `${fieldId}-listbox`;
33027
+ const triggerId = `${fieldId}-trigger`;
33028
+ const labelId = `${fieldId}-label`;
33029
+ const valueId = `${fieldId}-value`;
33030
+ const errorId = `${fieldId}-error`;
33031
+ const triggerRef = useRef84(null);
33032
+ const searchRef = useRef84(null);
33033
+ const listRef = useRef84(null);
33034
+ const hasFocusRef = useRef84(false);
33035
+ const [isOpen2, setIsOpen] = useState71(false);
33036
+ const [search, setSearch] = useState71("");
33037
+ const [optionsLoading, setOptionsLoading] = useState71(false);
33038
+ const didRequestOptionsRef = useRef84(false);
33039
+ const options = useMemo61(
33040
+ () => initializeOptions(optionsProp, getOptionValue, getOptionLabel, void 0, false),
33041
+ // getOptionValue and getOptionLabel are typically inline lambdas
33042
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33043
+ [optionsProp]
33044
+ );
33045
+ const { hoverProps, isHovered } = useHover27({});
33046
+ const { focusProps, isFocusVisible } = useFocusRing23();
33047
+ const { contains } = useFilter5({ sensitivity: "base" });
33048
+ const optionsByKey = useMemo61(
33049
+ () => new Map(options.map((o) => [valueToKey(getOptionValue(o)), o])),
33050
+ // getOptionValue is typically an inline lambda
33051
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33052
+ [options]
33053
+ );
33054
+ const { effectiveValue: value, proposalProps } = useAiProposal(propValue, proposedValue, (v) => {
33055
+ const option = optionsByKey.get(valueToKey(v));
33056
+ return option === void 0 ? void 0 : getOptionLabel(option);
33057
+ });
33058
+ const selectedKeys = useMemo61(() => new Set(value === void 0 ? [] : [valueToKey(value)]), [value]);
33059
+ const filteredOptions = useMemo61(
33060
+ () => search ? options.filter((o) => matchesSearch(o, search, getOptionLabel, getOptionSearchText, contains)) : options,
33061
+ // getOptionLabel and getOptionSearchText are typically inline lambdas
33062
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33063
+ [options, search, contains]
33064
+ );
33065
+ const [disabledKeys, disabledReasons] = useMemo61(() => {
33066
+ const tuples = (disabledOptions ?? []).map(disabledOptionToKeyedTuple);
33067
+ return [tuples.map(([k]) => String(k)), Object.fromEntries(tuples.map(([k, r]) => [String(k), r]))];
33068
+ }, [disabledOptions]);
33069
+ function onSelectionChange(keys) {
33070
+ if (keys === "all") return;
33071
+ const [key] = [...keys];
33072
+ if (key === void 0) {
33073
+ close({ restoreFocus: true });
33074
+ return;
33075
+ }
33076
+ const opt = optionsByKey.get(String(key));
33077
+ proposalProps.onUserEdit?.();
33078
+ onSelect(opt === void 0 ? void 0 : getOptionValue(opt), opt);
33079
+ close({ restoreFocus: true });
33080
+ }
33081
+ const state = useListState({
33082
+ items: filteredOptions,
33083
+ children: (o) => /* @__PURE__ */ jsx272(Item6, { textValue: getOptionLabel(o), children: getOptionMenuLabel ? getOptionMenuLabel(o) : getOptionLabel(o) }, valueToKey(getOptionValue(o))),
33084
+ selectionMode: "single",
33085
+ selectedKeys,
33086
+ disabledKeys,
33087
+ onSelectionChange
33088
+ });
33089
+ const { selectionManager } = state;
33090
+ const keyboardDelegate = useMemo61(
33091
+ () => new MenuSelectKeyboardDelegate({
33092
+ collection: state.collection,
33093
+ disabledKeys: state.disabledKeys,
33094
+ ref: listRef
33095
+ }),
33096
+ [state.collection, state.disabledKeys]
33097
+ );
33098
+ function open() {
33099
+ if (isDisabled || isReadOnly) return;
33100
+ setSearch("");
33101
+ setIsOpen(true);
33102
+ if (didRequestOptionsRef.current || Array.isArray(optionsProp)) return;
33103
+ didRequestOptionsRef.current = true;
33104
+ setOptionsLoading(true);
33105
+ void optionsProp.load().finally(() => setOptionsLoading(false));
33106
+ }
33107
+ function close(opts) {
33108
+ setIsOpen(false);
33109
+ setSearch("");
33110
+ if (opts.restoreFocus) {
33111
+ triggerRef.current?.focus({ preventScroll: true });
33112
+ } else if (hasFocusRef.current) {
33113
+ settleBlur();
33114
+ }
33115
+ }
33116
+ function settleBlur() {
33117
+ hasFocusRef.current = false;
33118
+ maybeCall(proposalProps.onUserBlur);
33119
+ maybeCall(onBlur);
33120
+ }
33121
+ const showSearch = options.length > searchOptionLimit;
33122
+ useLayoutEffect24(() => {
33123
+ if (!isOpen2) return;
33124
+ const keyTarget = showSearch ? searchRef.current : listRef.current;
33125
+ keyTarget?.focus({ preventScroll: true });
33126
+ selectionManager.setFocusedKey(null);
33127
+ selectionManager.setFocused(false);
33128
+ }, [isOpen2, showSearch]);
33129
+ function onSearchChange(value2) {
33130
+ setSearch(value2);
33131
+ selectionManager.setFocusedKey(null);
33132
+ selectionManager.setFocused(false);
33133
+ }
33134
+ function focusKey(key) {
33135
+ if (key == null) return;
33136
+ selectionManager.setFocused(true);
33137
+ selectionManager.setFocusedKey(key);
33138
+ }
33139
+ function onMenuKeyDown(e) {
33140
+ const current2 = selectionManager.focusedKey;
33141
+ switch (e.key) {
33142
+ case "ArrowDown":
33143
+ e.preventDefault();
33144
+ focusKey(
33145
+ current2 == null ? keyboardDelegate.getFirstKey() : keyboardDelegate.getKeyBelow(current2) ?? keyboardDelegate.getFirstKey()
33146
+ );
33147
+ break;
33148
+ case "ArrowUp":
33149
+ e.preventDefault();
33150
+ focusKey(
33151
+ current2 == null ? keyboardDelegate.getLastKey() : keyboardDelegate.getKeyAbove(current2) ?? keyboardDelegate.getLastKey()
33152
+ );
33153
+ break;
33154
+ case "PageDown":
33155
+ e.preventDefault();
33156
+ focusKey(current2 == null ? keyboardDelegate.getFirstKey() : keyboardDelegate.getKeyPageBelow(current2));
33157
+ break;
33158
+ case "PageUp":
33159
+ e.preventDefault();
33160
+ focusKey(current2 == null ? keyboardDelegate.getLastKey() : keyboardDelegate.getKeyPageAbove(current2));
33161
+ break;
33162
+ case "Home":
33163
+ e.preventDefault();
33164
+ focusKey(keyboardDelegate.getFirstKey());
33165
+ break;
33166
+ case "End":
33167
+ e.preventDefault();
33168
+ focusKey(keyboardDelegate.getLastKey());
33169
+ break;
33170
+ case "Enter": {
33171
+ e.preventDefault();
33172
+ const key = selectionManager.focusedKey;
33173
+ if (key != null && !state.disabledKeys.has(key)) selectionManager.select(key);
33174
+ break;
33175
+ }
33176
+ case "Escape":
33177
+ e.preventDefault();
33178
+ e.stopPropagation();
33179
+ close({ restoreFocus: true });
33180
+ break;
33181
+ case "Tab":
33182
+ e.preventDefault();
33183
+ close({ restoreFocus: true });
33184
+ break;
33185
+ default:
33186
+ break;
33187
+ }
33188
+ }
33189
+ function onTriggerKeyDown(e) {
33190
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
33191
+ e.preventDefault();
33192
+ open();
33193
+ }
33194
+ }
33195
+ function onTriggerFocus() {
33196
+ if (hasFocusRef.current) return;
33197
+ hasFocusRef.current = true;
33198
+ maybeCall(onFocus);
33199
+ }
33200
+ function onTriggerBlur() {
33201
+ if (isOpen2) return;
33202
+ settleBlur();
33203
+ }
33204
+ const focusedKey = selectionManager.focusedKey;
33205
+ const focusedIndex = focusedKey != null ? state.collection.getItem(focusedKey)?.index : void 0;
33206
+ const activeDescendant = isOpen2 && focusedIndex !== void 0 ? optionDomId(listId, focusedIndex) : void 0;
33207
+ const initialIndex = Math.max(
33208
+ 0,
33209
+ filteredOptions.findIndex((o) => selectedKeys.has(valueToKey(getOptionValue(o))))
33210
+ );
33211
+ const selectedOption = value === void 0 ? void 0 : optionsByKey.get(valueToKey(value));
33212
+ const selectedText = selectedOption === void 0 ? "" : getOptionLabel(selectedOption);
33213
+ const displayText = selectedText || nothingSelectedText || placeholder || "";
33214
+ const isPlaceholder = !selectedText && !nothingSelectedText && !!placeholder;
33215
+ const triggerProps = {
33216
+ isDisabled,
33217
+ isReadOnly,
33218
+ isOpen: isOpen2,
33219
+ listId,
33220
+ triggerId,
33221
+ labelId,
33222
+ valueId,
33223
+ errorId,
33224
+ hoverProps,
33225
+ focusProps,
33226
+ isFocusVisible,
33227
+ isHovered,
33228
+ open,
33229
+ close,
33230
+ onKeyDown: onTriggerKeyDown,
33231
+ onFocus: onTriggerFocus,
33232
+ onBlur: onTriggerBlur,
33233
+ displayText,
33234
+ isPlaceholder,
33235
+ proposalProps
33236
+ };
33237
+ const searchProps = {
33238
+ show: showSearch,
33239
+ value: search,
33240
+ onChange: onSearchChange,
33241
+ listId,
33242
+ activeDescendant,
33243
+ onKeyDown: onMenuKeyDown
33244
+ };
33245
+ const menuProps = {
33246
+ isOpen: isOpen2,
33247
+ close,
33248
+ listId,
33249
+ state,
33250
+ loading: optionsLoading,
33251
+ disabledReasons,
33252
+ initialIndex,
33253
+ onKeyDown: onMenuKeyDown,
33254
+ activeDescendant
33255
+ };
33256
+ return { triggerRef, trigger: triggerProps, searchRef, search: searchProps, listRef, menu: menuProps };
33257
+ }
33258
+ function matchesSearch(option, query, getOptionLabel, getOptionSearchText, contains) {
33259
+ if (contains(getOptionLabel(option), query)) return true;
33260
+ const extra = getOptionSearchText?.(option);
33261
+ const terms = typeof extra === "string" ? [extra] : extra;
33262
+ return terms?.some((term) => contains(term, query)) ?? false;
33263
+ }
33264
+ var searchOptionLimit = 8;
33265
+ var MenuSelectKeyboardDelegate = class _MenuSelectKeyboardDelegate extends ListKeyboardDelegate {
33266
+ /** Rows skipped by Page Up / Page Down. */
33267
+ static pageSize = 10;
33268
+ getKeyPageBelow(key) {
33269
+ return this.stepKeys(key, "below");
33270
+ }
33271
+ getKeyPageAbove(key) {
33272
+ return this.stepKeys(key, "above");
33273
+ }
33274
+ stepKeys(key, direction) {
33275
+ let next = key;
33276
+ for (let index = 0; index < _MenuSelectKeyboardDelegate.pageSize; index += 1) {
33277
+ if (next == null) return next;
33278
+ const candidate = direction === "below" ? this.getKeyBelow(next) : this.getKeyAbove(next);
33279
+ if (candidate == null) return next;
33280
+ next = candidate;
33281
+ }
33282
+ return next;
33283
+ }
33284
+ };
33285
+
33286
+ // src/inputs/MenuSelectField/internal/BaseMenuSelectField.tsx
33287
+ import { Fragment as Fragment58, jsx as jsx273, jsxs as jsxs148 } from "react/jsx-runtime";
33288
+ function BaseMenuSelectField(props) {
33289
+ const { label, searchPlaceholder } = props;
33290
+ const { triggerRef, trigger, searchRef, search, listRef, menu } = useMenuSelectField(props);
33291
+ const tid = useTestIds(props, defaultTestId(label));
33292
+ const { sm: isMobile } = useBreakpoint();
33293
+ const panel = /* @__PURE__ */ jsx273(
33294
+ MenuPanel,
33295
+ {
33296
+ variant: isMobile ? "sheet" : "anchored",
33297
+ header: search.show ? /* @__PURE__ */ jsx273(
33298
+ MenuSearchInput,
33299
+ {
33300
+ search,
33301
+ inputRef: searchRef,
33302
+ label: `Search ${label}`,
33303
+ placeholder: searchPlaceholder,
33304
+ ...tid
33305
+ }
33306
+ ) : void 0,
33307
+ ...tid,
33308
+ children: /* @__PURE__ */ jsx273(
33309
+ OptionList,
33310
+ {
33311
+ menu,
33312
+ listRef,
33313
+ label,
33314
+ onKeyDown: search.show ? void 0 : menu.onKeyDown,
33315
+ activeDescendant: search.show ? void 0 : menu.activeDescendant,
33316
+ ...tid
33317
+ }
33318
+ )
33319
+ }
33320
+ );
33321
+ return /* @__PURE__ */ jsxs148(Fragment58, { children: [
33322
+ /* @__PURE__ */ jsx273(MenuSelectTrigger, { ...props, trigger, triggerRef }),
33323
+ isMobile ? /* @__PURE__ */ jsx273(BottomSheet, { isOpen: menu.isOpen, onClose: () => menu.close({ restoreFocus: true }), label, ...tid, children: panel }) : /* @__PURE__ */ jsx273(
33324
+ AnchoredOverlay,
33325
+ {
33326
+ triggerRef,
33327
+ isOpen: menu.isOpen,
33328
+ onClose: () => menu.close({ restoreFocus: false }),
33329
+ ...tid,
33330
+ children: panel
33331
+ }
33332
+ )
33333
+ ] });
33334
+ }
33335
+
33336
+ // src/inputs/MenuSelectField/MenuSelectField.tsx
33337
+ import { jsx as jsx274 } from "react/jsx-runtime";
33338
+ function MenuSelectField(props) {
33339
+ return /* @__PURE__ */ jsx274(BaseMenuSelectField, { ...props });
33340
+ }
33341
+
32343
33342
  // src/inputs/ToggleButton.tsx
32344
- import { useRef as useRef80, useState as useState70 } from "react";
32345
- import { useFocusRing as useFocusRing23, useHover as useHover26, usePress as usePress3, useSwitch as useSwitch2, VisuallyHidden as VisuallyHidden12 } from "react-aria";
33343
+ import { useRef as useRef85, useState as useState72 } from "react";
33344
+ import { useFocusRing as useFocusRing24, useHover as useHover28, usePress as usePress3, useSwitch as useSwitch2, VisuallyHidden as VisuallyHidden12 } from "react-aria";
32346
33345
  import { useToggleState as useToggleState2 } from "react-stately";
32347
- import { trussProps as trussProps151 } from "@homebound/truss/runtime";
32348
- import { jsx as jsx265, jsxs as jsxs142 } from "react/jsx-runtime";
33346
+ import { trussProps as trussProps157 } from "@homebound/truss/runtime";
33347
+ import { jsx as jsx275, jsxs as jsxs149 } from "react/jsx-runtime";
32349
33348
  function ToggleButton(props) {
32350
33349
  const {
32351
33350
  selected: isSelected = false,
@@ -32356,7 +33355,7 @@ function ToggleButton(props) {
32356
33355
  __storyState,
32357
33356
  ...otherProps
32358
33357
  } = props;
32359
- const [asyncInProgress, setAsyncInProgress] = useState70(false);
33358
+ const [asyncInProgress, setAsyncInProgress] = useState72(false);
32360
33359
  const isDisabled = !!disabled || asyncInProgress;
32361
33360
  const ariaProps = {
32362
33361
  "aria-label": label,
@@ -32375,8 +33374,8 @@ function ToggleButton(props) {
32375
33374
  return result;
32376
33375
  }
32377
33376
  });
32378
- const labelRef = useRef80(null);
32379
- const ref = useRef80(null);
33377
+ const labelRef = useRef85(null);
33378
+ const ref = useRef85(null);
32380
33379
  const tid = useTestIds(otherProps, label);
32381
33380
  const {
32382
33381
  isPressed: isPressedFromEvents,
@@ -32391,14 +33390,14 @@ function ToggleButton(props) {
32391
33390
  const {
32392
33391
  isFocusVisible: isFocusVisibleFromEvents,
32393
33392
  focusProps
32394
- } = useFocusRing23({
33393
+ } = useFocusRing24({
32395
33394
  ...otherProps,
32396
33395
  within: true
32397
33396
  });
32398
33397
  const {
32399
33398
  hoverProps,
32400
33399
  isHovered: isHoveredFromEvents
32401
- } = useHover26({
33400
+ } = useHover28({
32402
33401
  isDisabled
32403
33402
  });
32404
33403
  const isHovered = __storyState?.hovered ?? isHoveredFromEvents;
@@ -32409,7 +33408,7 @@ function ToggleButton(props) {
32409
33408
  ...focusProps,
32410
33409
  ...hoverProps,
32411
33410
  ...pressProps,
32412
- ...trussProps151({
33411
+ ...trussProps157({
32413
33412
  // Gray500 off-state has no semantic match — keep palette (OnSurfaceMuted is Gray700).
32414
33413
  ...{
32415
33414
  borderRadius: "br4",
@@ -32449,10 +33448,10 @@ function ToggleButton(props) {
32449
33448
  return maybeTooltip({
32450
33449
  title: tooltip,
32451
33450
  placement: "top",
32452
- children: /* @__PURE__ */ jsxs142("label", { ...labelAttrs, children: [
32453
- icon && /* @__PURE__ */ jsx265(Icon, { icon }),
33451
+ children: /* @__PURE__ */ jsxs149("label", { ...labelAttrs, children: [
33452
+ icon && /* @__PURE__ */ jsx275(Icon, { icon }),
32454
33453
  label,
32455
- /* @__PURE__ */ jsx265(VisuallyHidden12, { children: /* @__PURE__ */ jsx265("input", { ref, ...inputProps, ...tid.value }) })
33454
+ /* @__PURE__ */ jsx275(VisuallyHidden12, { children: /* @__PURE__ */ jsx275("input", { ref, ...inputProps, ...tid.value }) })
32456
33455
  ] })
32457
33456
  });
32458
33457
  }
@@ -32592,6 +33591,7 @@ export {
32592
33591
  Loader,
32593
33592
  LoadingSkeleton,
32594
33593
  MaxLines,
33594
+ MenuSelectField,
32595
33595
  ModalBanner,
32596
33596
  ModalBody,
32597
33597
  ModalFilterItem,