@homebound/beam 4.42.1 → 4.44.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.cjs CHANGED
@@ -152,6 +152,8 @@ __export(index_exports, {
152
152
  Loader: () => Loader,
153
153
  LoadingSkeleton: () => LoadingSkeleton,
154
154
  MaxLines: () => MaxLines,
155
+ MenuMultiSelectField: () => MenuMultiSelectField,
156
+ MenuSelectField: () => MenuSelectField,
155
157
  ModalBanner: () => ModalBanner,
156
158
  ModalBody: () => ModalBody,
157
159
  ModalFilterItem: () => ModalFilterItem,
@@ -464,95 +466,95 @@ module.exports = __toCommonJS(index_exports);
464
466
 
465
467
  // src/Css.ts
466
468
  var import_runtime = require("@homebound/truss/runtime");
467
- var Tokens = /* @__PURE__ */ ((Tokens65) => {
468
- Tokens65["AiFieldBg"] = "--b-ai-field-bg";
469
- Tokens65["AiFieldFg"] = "--b-ai-field-fg";
470
- Tokens65["ButtonCautionDisabledBg"] = "--b-button-caution-disabled-bg";
471
- Tokens65["ButtonCautionDisabledFg"] = "--b-button-caution-disabled-fg";
472
- Tokens65["ButtonDangerDisabledBg"] = "--b-button-danger-disabled-bg";
473
- Tokens65["ButtonDangerDisabledFg"] = "--b-button-danger-disabled-fg";
474
- Tokens65["ButtonGhostDisabledFg"] = "--b-button-ghost-disabled-fg";
475
- Tokens65["ButtonGhostFg"] = "--b-button-ghost-fg";
476
- Tokens65["ButtonPrimaryDisabledBg"] = "--b-button-primary-disabled-bg";
477
- Tokens65["ButtonPrimaryDisabledFg"] = "--b-button-primary-disabled-fg";
478
- Tokens65["ButtonSecondaryFg"] = "--b-button-secondary-fg";
479
- Tokens65["ButtonTertiaryFg"] = "--b-button-tertiary-fg";
480
- Tokens65["ButtonTertiaryFgPressed"] = "--b-button-tertiary-fg-pressed";
481
- Tokens65["ChoiceDisabled"] = "--b-choice-disabled";
482
- Tokens65["ChoiceSelected"] = "--b-choice-selected";
483
- Tokens65["Danger"] = "--b-danger";
484
- Tokens65["DangerPressed"] = "--b-danger-pressed";
485
- Tokens65["EnvBrandDev"] = "--b-env-brand-dev";
486
- Tokens65["EnvBrandLocalProd"] = "--b-env-brand-local-prod";
487
- Tokens65["EnvBrandProd"] = "--b-env-brand-prod";
488
- Tokens65["EnvBrandQa"] = "--b-env-brand-qa";
489
- Tokens65["FieldBgDefault"] = "--b-field-bg-default";
490
- Tokens65["FieldBgDisabled"] = "--b-field-bg-disabled";
491
- Tokens65["FieldBgHover"] = "--b-field-bg-hover";
492
- Tokens65["FieldBorderDefault"] = "--b-field-border-default";
493
- Tokens65["FieldBorderError"] = "--b-field-border-error";
494
- Tokens65["FieldBorderFocus"] = "--b-field-border-focus";
495
- Tokens65["FieldBorderHover"] = "--b-field-border-hover";
496
- Tokens65["FieldTextDisabled"] = "--b-field-text-disabled";
497
- Tokens65["FocusRingInset"] = "--b-focus-ring-inset";
498
- Tokens65["FocusRingMuted"] = "--b-focus-ring-muted";
499
- Tokens65["LoaderFill"] = "--b-loader-fill";
500
- Tokens65["LoaderSpinner"] = "--b-loader-spinner";
501
- Tokens65["LoaderTrack"] = "--b-loader-track";
502
- Tokens65["NavGlobalItemBgActive"] = "--b-nav-global-item-bg-active";
503
- Tokens65["NavGlobalItemBgHover"] = "--b-nav-global-item-bg-hover";
504
- Tokens65["NavGlobalItemBgPressed"] = "--b-nav-global-item-bg-pressed";
505
- Tokens65["NavGlobalText"] = "--b-nav-global-text";
506
- Tokens65["NavGlobalTextActive"] = "--b-nav-global-text-active";
507
- Tokens65["NavGlobalTextDisabled"] = "--b-nav-global-text-disabled";
508
- Tokens65["NavItemBgActive"] = "--b-nav-item-bg-active";
509
- Tokens65["NavItemBgHover"] = "--b-nav-item-bg-hover";
510
- Tokens65["NavItemBgPressed"] = "--b-nav-item-bg-pressed";
511
- Tokens65["NavText"] = "--b-nav-text";
512
- Tokens65["NavTextActive"] = "--b-nav-text-active";
513
- Tokens65["NavTextDisabled"] = "--b-nav-text-disabled";
514
- Tokens65["NavTextFocusVisible"] = "--b-nav-text-focus-visible";
515
- Tokens65["NavTextPressed"] = "--b-nav-text-pressed";
516
- Tokens65["NeutralFillHover"] = "--b-neutral-fill-hover";
517
- Tokens65["NeutralFillHoverStrong"] = "--b-neutral-fill-hover-strong";
518
- Tokens65["NeutralFillHoverSubtle"] = "--b-neutral-fill-hover-subtle";
519
- Tokens65["NeutralFillPressed"] = "--b-neutral-fill-pressed";
520
- Tokens65["NeutralSurfacePressed"] = "--b-neutral-surface-pressed";
521
- Tokens65["OnPrimary"] = "--b-on-primary";
522
- Tokens65["OnSurface"] = "--b-on-surface";
523
- Tokens65["OnSurfaceActive"] = "--b-on-surface-active";
524
- Tokens65["OnSurfaceActiveDisabled"] = "--b-on-surface-active-disabled";
525
- Tokens65["OnSurfaceDisabled"] = "--b-on-surface-disabled";
526
- Tokens65["OnSurfaceMuted"] = "--b-on-surface-muted";
527
- Tokens65["OnSurfaceRaisedHover"] = "--b-on-surface-raised-hover";
528
- Tokens65["OnSurfaceRaisedPressed"] = "--b-on-surface-raised-pressed";
529
- Tokens65["Primary"] = "--b-primary";
530
- Tokens65["PrimaryHover"] = "--b-primary-hover";
531
- Tokens65["PrimaryPressed"] = "--b-primary-pressed";
532
- Tokens65["Scrim"] = "--b-scrim";
533
- Tokens65["SelectionFill"] = "--b-selection-fill";
534
- Tokens65["SelectionIndicator"] = "--b-selection-indicator";
535
- Tokens65["Surface"] = "--b-surface";
536
- Tokens65["SurfaceActive"] = "--b-surface-active";
537
- Tokens65["SurfaceActiveBorder"] = "--b-surface-active-border";
538
- Tokens65["SurfaceActiveHover"] = "--b-surface-active-hover";
539
- Tokens65["SurfaceDisabled"] = "--b-surface-disabled";
540
- Tokens65["SurfaceHover"] = "--b-surface-hover";
541
- Tokens65["SurfaceRaised"] = "--b-surface-raised";
542
- Tokens65["SurfaceRaisedHover"] = "--b-surface-raised-hover";
543
- Tokens65["SurfaceRaisedPressed"] = "--b-surface-raised-pressed";
544
- Tokens65["SurfaceSeparator"] = "--b-surface-separator";
545
- Tokens65["SurfaceSubtle"] = "--b-surface-subtle";
546
- Tokens65["TextDisabled"] = "--b-text-disabled";
547
- Tokens65["TextHelper"] = "--b-text-helper";
548
- Tokens65["TextLabel"] = "--b-text-label";
549
- Tokens65["TextLinkDefault"] = "--b-text-link-default";
550
- Tokens65["TextLinkDisabled"] = "--b-text-link-disabled";
551
- Tokens65["TextLinkHover"] = "--b-text-link-hover";
552
- Tokens65["TextLinkPressed"] = "--b-text-link-pressed";
553
- Tokens65["TextPlaceholder"] = "--b-text-placeholder";
554
- Tokens65["TextSelection"] = "--b-text-selection";
555
- return Tokens65;
469
+ var Tokens = /* @__PURE__ */ ((Tokens69) => {
470
+ Tokens69["AiFieldBg"] = "--b-ai-field-bg";
471
+ Tokens69["AiFieldFg"] = "--b-ai-field-fg";
472
+ Tokens69["ButtonCautionDisabledBg"] = "--b-button-caution-disabled-bg";
473
+ Tokens69["ButtonCautionDisabledFg"] = "--b-button-caution-disabled-fg";
474
+ Tokens69["ButtonDangerDisabledBg"] = "--b-button-danger-disabled-bg";
475
+ Tokens69["ButtonDangerDisabledFg"] = "--b-button-danger-disabled-fg";
476
+ Tokens69["ButtonGhostDisabledFg"] = "--b-button-ghost-disabled-fg";
477
+ Tokens69["ButtonGhostFg"] = "--b-button-ghost-fg";
478
+ Tokens69["ButtonPrimaryDisabledBg"] = "--b-button-primary-disabled-bg";
479
+ Tokens69["ButtonPrimaryDisabledFg"] = "--b-button-primary-disabled-fg";
480
+ Tokens69["ButtonSecondaryFg"] = "--b-button-secondary-fg";
481
+ Tokens69["ButtonTertiaryFg"] = "--b-button-tertiary-fg";
482
+ Tokens69["ButtonTertiaryFgPressed"] = "--b-button-tertiary-fg-pressed";
483
+ Tokens69["ChoiceDisabled"] = "--b-choice-disabled";
484
+ Tokens69["ChoiceSelected"] = "--b-choice-selected";
485
+ Tokens69["Danger"] = "--b-danger";
486
+ Tokens69["DangerPressed"] = "--b-danger-pressed";
487
+ Tokens69["EnvBrandDev"] = "--b-env-brand-dev";
488
+ Tokens69["EnvBrandLocalProd"] = "--b-env-brand-local-prod";
489
+ Tokens69["EnvBrandProd"] = "--b-env-brand-prod";
490
+ Tokens69["EnvBrandQa"] = "--b-env-brand-qa";
491
+ Tokens69["FieldBgDefault"] = "--b-field-bg-default";
492
+ Tokens69["FieldBgDisabled"] = "--b-field-bg-disabled";
493
+ Tokens69["FieldBgHover"] = "--b-field-bg-hover";
494
+ Tokens69["FieldBorderDefault"] = "--b-field-border-default";
495
+ Tokens69["FieldBorderError"] = "--b-field-border-error";
496
+ Tokens69["FieldBorderFocus"] = "--b-field-border-focus";
497
+ Tokens69["FieldBorderHover"] = "--b-field-border-hover";
498
+ Tokens69["FieldTextDisabled"] = "--b-field-text-disabled";
499
+ Tokens69["FocusRingInset"] = "--b-focus-ring-inset";
500
+ Tokens69["FocusRingMuted"] = "--b-focus-ring-muted";
501
+ Tokens69["LoaderFill"] = "--b-loader-fill";
502
+ Tokens69["LoaderSpinner"] = "--b-loader-spinner";
503
+ Tokens69["LoaderTrack"] = "--b-loader-track";
504
+ Tokens69["NavGlobalItemBgActive"] = "--b-nav-global-item-bg-active";
505
+ Tokens69["NavGlobalItemBgHover"] = "--b-nav-global-item-bg-hover";
506
+ Tokens69["NavGlobalItemBgPressed"] = "--b-nav-global-item-bg-pressed";
507
+ Tokens69["NavGlobalText"] = "--b-nav-global-text";
508
+ Tokens69["NavGlobalTextActive"] = "--b-nav-global-text-active";
509
+ Tokens69["NavGlobalTextDisabled"] = "--b-nav-global-text-disabled";
510
+ Tokens69["NavItemBgActive"] = "--b-nav-item-bg-active";
511
+ Tokens69["NavItemBgHover"] = "--b-nav-item-bg-hover";
512
+ Tokens69["NavItemBgPressed"] = "--b-nav-item-bg-pressed";
513
+ Tokens69["NavText"] = "--b-nav-text";
514
+ Tokens69["NavTextActive"] = "--b-nav-text-active";
515
+ Tokens69["NavTextDisabled"] = "--b-nav-text-disabled";
516
+ Tokens69["NavTextFocusVisible"] = "--b-nav-text-focus-visible";
517
+ Tokens69["NavTextPressed"] = "--b-nav-text-pressed";
518
+ Tokens69["NeutralFillHover"] = "--b-neutral-fill-hover";
519
+ Tokens69["NeutralFillHoverStrong"] = "--b-neutral-fill-hover-strong";
520
+ Tokens69["NeutralFillHoverSubtle"] = "--b-neutral-fill-hover-subtle";
521
+ Tokens69["NeutralFillPressed"] = "--b-neutral-fill-pressed";
522
+ Tokens69["NeutralSurfacePressed"] = "--b-neutral-surface-pressed";
523
+ Tokens69["OnPrimary"] = "--b-on-primary";
524
+ Tokens69["OnSurface"] = "--b-on-surface";
525
+ Tokens69["OnSurfaceActive"] = "--b-on-surface-active";
526
+ Tokens69["OnSurfaceActiveDisabled"] = "--b-on-surface-active-disabled";
527
+ Tokens69["OnSurfaceDisabled"] = "--b-on-surface-disabled";
528
+ Tokens69["OnSurfaceMuted"] = "--b-on-surface-muted";
529
+ Tokens69["OnSurfaceRaisedHover"] = "--b-on-surface-raised-hover";
530
+ Tokens69["OnSurfaceRaisedPressed"] = "--b-on-surface-raised-pressed";
531
+ Tokens69["Primary"] = "--b-primary";
532
+ Tokens69["PrimaryHover"] = "--b-primary-hover";
533
+ Tokens69["PrimaryPressed"] = "--b-primary-pressed";
534
+ Tokens69["Scrim"] = "--b-scrim";
535
+ Tokens69["SelectionFill"] = "--b-selection-fill";
536
+ Tokens69["SelectionIndicator"] = "--b-selection-indicator";
537
+ Tokens69["Surface"] = "--b-surface";
538
+ Tokens69["SurfaceActive"] = "--b-surface-active";
539
+ Tokens69["SurfaceActiveBorder"] = "--b-surface-active-border";
540
+ Tokens69["SurfaceActiveHover"] = "--b-surface-active-hover";
541
+ Tokens69["SurfaceDisabled"] = "--b-surface-disabled";
542
+ Tokens69["SurfaceHover"] = "--b-surface-hover";
543
+ Tokens69["SurfaceRaised"] = "--b-surface-raised";
544
+ Tokens69["SurfaceRaisedHover"] = "--b-surface-raised-hover";
545
+ Tokens69["SurfaceRaisedPressed"] = "--b-surface-raised-pressed";
546
+ Tokens69["SurfaceSeparator"] = "--b-surface-separator";
547
+ Tokens69["SurfaceSubtle"] = "--b-surface-subtle";
548
+ Tokens69["TextDisabled"] = "--b-text-disabled";
549
+ Tokens69["TextHelper"] = "--b-text-helper";
550
+ Tokens69["TextLabel"] = "--b-text-label";
551
+ Tokens69["TextLinkDefault"] = "--b-text-link-default";
552
+ Tokens69["TextLinkDisabled"] = "--b-text-link-disabled";
553
+ Tokens69["TextLinkHover"] = "--b-text-link-hover";
554
+ Tokens69["TextLinkPressed"] = "--b-text-link-pressed";
555
+ Tokens69["TextPlaceholder"] = "--b-text-placeholder";
556
+ Tokens69["TextSelection"] = "--b-text-selection";
557
+ return Tokens69;
556
558
  })(Tokens || {});
557
559
  var Keyframes = /* @__PURE__ */ ((Keyframes2) => {
558
560
  Keyframes2["LoadingDots"] = "loadingDots";
@@ -8335,7 +8337,7 @@ function CompanionRowImpl(props) {
8335
8337
  companion,
8336
8338
  position = "trailing",
8337
8339
  levelIndent,
8338
- rowCss,
8340
+ rowCss: rowCss2,
8339
8341
  cellCss
8340
8342
  } = props;
8341
8343
  const RowTag = as === "table" ? "tr" : "div";
@@ -8368,7 +8370,7 @@ function CompanionRowImpl(props) {
8368
8370
  }]
8369
8371
  },
8370
8372
  ...isLastBodyRow && style.lastRowCss,
8371
- ...rowCss
8373
+ ...rowCss2
8372
8374
  }), "data-gridrow": true, ...tid[rowId], children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CellTag, { ...(0, import_runtime17.trussProps)({
8373
8375
  ...style.cellCss,
8374
8376
  ...style.betweenRowsCss,
@@ -11016,7 +11018,7 @@ function RowImpl(props) {
11016
11018
  }
11017
11019
  };
11018
11020
  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 */);
11019
- const rowCss = {
11021
+ const rowCss2 = {
11020
11022
  ...!reservedRowKinds.includes(row.kind) && style.nonHeaderRowCss,
11021
11023
  ...isFirstBodyRow && style.firstBodyRowCss,
11022
11024
  ...isFirstHeadRow && style.firstRowCss,
@@ -11056,7 +11058,7 @@ function RowImpl(props) {
11056
11058
  const ref = (0, import_react33.useRef)(null);
11057
11059
  const dragOverCallback = (0, import_react33.useCallback)((row2, evt) => onDragOver?.(row2, evt), [onDragOver]);
11058
11060
  const onDragOverDebounced = (0, import_use_debounce3.useDebouncedCallback)(dragOverCallback, 100);
11059
- const RowContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(RowTag, { ...(0, import_runtime24.mergeProps)(`${BorderHoverParent}${showRowHoverColor ? ` ${RowHoverClass}` : ""}`, void 0, rowCss), ...others, "data-gridrow": true, ...getCount(row.id), ref, children: isKeptGroupRow ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(KeptGroupRow, { as, style, columnSizes, row, colSpan: columns.length, isLastBodyRow }) : columns.map((column2, columnIndex) => {
11061
+ const RowContent = () => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(RowTag, { ...(0, import_runtime24.mergeProps)(`${BorderHoverParent}${showRowHoverColor ? ` ${RowHoverClass}` : ""}`, void 0, rowCss2), ...others, "data-gridrow": true, ...getCount(row.id), ref, children: isKeptGroupRow ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(KeptGroupRow, { as, style, columnSizes, row, colSpan: columns.length, isLastBodyRow }) : columns.map((column2, columnIndex) => {
11060
11062
  const maybeExpandedColumn = expandColumnHidden ? columns[columnIndex - 1] : column2;
11061
11063
  const isExpanded = tableState.isExpandedColumn(maybeExpandedColumn.id);
11062
11064
  if (column2.hideOnExpand && isExpanded) {
@@ -32823,12 +32825,1087 @@ function Autocomplete(props) {
32823
32825
  ] });
32824
32826
  }
32825
32827
 
32826
- // src/inputs/ToggleButton.tsx
32828
+ // src/inputs/MenuSelectField/internal/AnchoredOverlay.tsx
32829
+ var import_react183 = require("react");
32830
+ var import_react_aria73 = require("react-aria");
32831
+
32832
+ // src/inputs/MenuSelectField/internal/useAnchoredPosition.ts
32827
32833
  var import_react182 = require("react");
32828
32834
  var import_react_aria72 = require("react-aria");
32829
- var import_react_stately20 = require("react-stately");
32830
- var import_runtime173 = require("@homebound/truss/runtime");
32835
+ function useAnchoredPosition(triggerRef, popoverRef, isOpen2) {
32836
+ const { overlayProps, updatePosition } = (0, import_react_aria72.useOverlayPosition)({
32837
+ targetRef: triggerRef,
32838
+ overlayRef: popoverRef,
32839
+ isOpen: isOpen2,
32840
+ shouldFlip: true,
32841
+ placement: "bottom start",
32842
+ offset: overlayOffset,
32843
+ containerPadding: viewportPadding,
32844
+ maxHeight: menuMaxHeight
32845
+ });
32846
+ (0, import_react182.useLayoutEffect)(() => {
32847
+ if (!isOpen2) return;
32848
+ const onScroll = (event) => {
32849
+ const target = event.target;
32850
+ if (!(target instanceof Node) || !triggerRef.current || !target.contains(triggerRef.current)) return;
32851
+ updatePosition();
32852
+ };
32853
+ window.addEventListener("scroll", onScroll, true);
32854
+ return () => window.removeEventListener("scroll", onScroll, true);
32855
+ }, [isOpen2, updatePosition, triggerRef]);
32856
+ (0, import_react182.useLayoutEffect)(() => {
32857
+ if (!isOpen2) return;
32858
+ applyMenuFrame(popoverRef.current, triggerRef.current);
32859
+ });
32860
+ return {
32861
+ ...overlayProps,
32862
+ style: {
32863
+ ...overlayProps.style,
32864
+ zIndex: zIndices.popover
32865
+ }
32866
+ };
32867
+ }
32868
+ var overlayOffset = 4;
32869
+ var viewportPadding = 8;
32870
+ var menuMaxHeight = 512;
32871
+ function applyMenuFrame(overlay, trigger) {
32872
+ if (!overlay) return;
32873
+ const height = overlay.style.maxHeight;
32874
+ if (height && overlay.style.getPropertyValue("--menu-max-height") !== height) {
32875
+ overlay.style.setProperty("--menu-max-height", height);
32876
+ }
32877
+ if (!trigger) return;
32878
+ const width2 = `${trigger.offsetWidth}px`;
32879
+ if (overlay.style.minWidth !== width2) overlay.style.minWidth = width2;
32880
+ }
32881
+
32882
+ // src/inputs/MenuSelectField/internal/AnchoredOverlay.tsx
32831
32883
  var import_jsx_runtime265 = require("react/jsx-runtime");
32884
+ function AnchoredOverlay(props) {
32885
+ const { triggerRef, isOpen: isOpen2, onClose, children } = props;
32886
+ const popoverRef = (0, import_react183.useRef)(null);
32887
+ const tid = useTestIds(props, "anchoredOverlay");
32888
+ const positionProps = useAnchoredPosition(triggerRef, popoverRef, isOpen2);
32889
+ if (!isOpen2) return null;
32890
+ return /* @__PURE__ */ (0, import_jsx_runtime265.jsx)(
32891
+ Popover,
32892
+ {
32893
+ triggerRef,
32894
+ popoverRef,
32895
+ positionProps: { ...positionProps, ...tid.overlay },
32896
+ onClose,
32897
+ isOpen: isOpen2,
32898
+ shouldCloseOnInteractOutside: (el) => {
32899
+ if (!triggerRef.current?.contains(el) && shouldDismissOverlay(el, triggerRef.current)) onClose();
32900
+ return false;
32901
+ },
32902
+ children: /* @__PURE__ */ (0, import_jsx_runtime265.jsx)(import_react_aria73.FocusScope, { children })
32903
+ }
32904
+ );
32905
+ }
32906
+
32907
+ // src/inputs/MenuSelectField/internal/BottomSheet.tsx
32908
+ var import_react184 = require("react");
32909
+ var import_react_aria74 = require("react-aria");
32910
+ var import_react_dom11 = require("react-dom");
32911
+ var import_runtime173 = require("@homebound/truss/runtime");
32912
+ var import_jsx_runtime266 = require("react/jsx-runtime");
32913
+ function BottomSheet(props) {
32914
+ const {
32915
+ isOpen: isOpen2,
32916
+ onClose,
32917
+ label,
32918
+ children
32919
+ } = props;
32920
+ const frameRef = (0, import_react184.useRef)(null);
32921
+ const sheetRef = (0, import_react184.useRef)(null);
32922
+ const contrast = useContrastScope();
32923
+ const tid = useTestIds(props, "bottomSheet");
32924
+ useVisualViewportFrame(frameRef, isOpen2);
32925
+ (0, import_react_aria74.usePreventScroll)({
32926
+ isDisabled: !isOpen2
32927
+ });
32928
+ const {
32929
+ overlayProps,
32930
+ underlayProps
32931
+ } = (0, import_react_aria74.useOverlay)({
32932
+ isOpen: isOpen2,
32933
+ onClose,
32934
+ isDismissable: true
32935
+ }, sheetRef);
32936
+ const {
32937
+ dialogProps
32938
+ } = (0, import_react_aria74.useDialog)({
32939
+ "aria-label": label
32940
+ }, sheetRef);
32941
+ if (!isOpen2) return null;
32942
+ return (0, import_react_dom11.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime266.jsxs)("div", { ref: frameRef, ...(0, import_runtime173.trussProps)(frameCss), "data-theme": contrast ? contrastDataTheme : void 0, children: [
32943
+ /* @__PURE__ */ (0, import_jsx_runtime266.jsx)("div", { ...underlayProps, ...(0, import_runtime173.trussProps)(scrimCss), ...tid.sheetScrim }),
32944
+ /* @__PURE__ */ (0, import_jsx_runtime266.jsx)(import_react_aria74.FocusScope, { contain: true, restoreFocus: true, children: /* @__PURE__ */ (0, import_jsx_runtime266.jsxs)("div", { ...(0, import_react_aria74.mergeProps)(overlayProps, dialogProps), ref: sheetRef, ...(0, import_runtime173.trussProps)(sheetCss), ...tid.sheet, children: [
32945
+ /* @__PURE__ */ (0, import_jsx_runtime266.jsxs)("div", { ...(0, import_runtime173.trussProps)({
32946
+ display: "df",
32947
+ alignItems: "aic",
32948
+ justifyContent: "jcsb",
32949
+ gap: "g_1",
32950
+ paddingLeft: "pl2",
32951
+ paddingRight: "pr2",
32952
+ height: ["h_var", {
32953
+ "--height": `${sheetHeaderHeight}px`
32954
+ }],
32955
+ borderBottomStyle: "bbs_solid",
32956
+ borderBottomWidth: "bbw_1px",
32957
+ borderColor: ["bc_var", {
32958
+ "--borderColor": "var(--b-surface-separator)"
32959
+ }]
32960
+ }), children: [
32961
+ /* @__PURE__ */ (0, import_jsx_runtime266.jsx)("span", { className: "fw6 fz_14px lh_20px wsnw oh to_ellipsis", children: label }),
32962
+ /* @__PURE__ */ (0, import_jsx_runtime266.jsx)(Button, { label: "Done", variant: "tertiary", onClick: onClose, ...tid.sheetDone })
32963
+ ] }),
32964
+ children
32965
+ ] }) })
32966
+ ] }), document.body);
32967
+ }
32968
+ function useVisualViewportFrame(frameRef, isOpen2) {
32969
+ (0, import_react184.useLayoutEffect)(() => {
32970
+ const frame = frameRef.current;
32971
+ if (!isOpen2 || !frame) return;
32972
+ let raf = 0;
32973
+ const apply = () => {
32974
+ raf = 0;
32975
+ const vv = window.visualViewport;
32976
+ const top = vv?.offsetTop ?? 0;
32977
+ const height = vv?.height ?? window.innerHeight;
32978
+ frame.style.top = `${top}px`;
32979
+ frame.style.height = `${height}px`;
32980
+ frame.style.setProperty("--menu-max-height", `${Math.max(0, Math.round(height * sheetMaxRatio) - sheetHeaderHeight)}px`);
32981
+ };
32982
+ const schedule = () => {
32983
+ if (!raf) raf = requestAnimationFrame(apply);
32984
+ };
32985
+ apply();
32986
+ window.visualViewport?.addEventListener("resize", schedule);
32987
+ window.visualViewport?.addEventListener("scroll", schedule);
32988
+ window.addEventListener("resize", schedule);
32989
+ return () => {
32990
+ if (raf) cancelAnimationFrame(raf);
32991
+ window.visualViewport?.removeEventListener("resize", schedule);
32992
+ window.visualViewport?.removeEventListener("scroll", schedule);
32993
+ window.removeEventListener("resize", schedule);
32994
+ };
32995
+ }, [frameRef, isOpen2]);
32996
+ }
32997
+ var sheetHeaderHeight = 48;
32998
+ var sheetMaxRatio = 0.85;
32999
+ var frameCss = {
33000
+ position: "fixed",
33001
+ left: "l_0",
33002
+ width: "w100",
33003
+ top: "top0",
33004
+ display: "df",
33005
+ flexDirection: "fdc",
33006
+ justifyContent: "jcfe",
33007
+ zIndex: ["z_var", {
33008
+ "--zIndex": (0, import_runtime173.maybeCssVar)(zIndices.popover)
33009
+ }]
33010
+ };
33011
+ var scrimCss = {
33012
+ position: "absolute",
33013
+ inset: "ins_0",
33014
+ backgroundColor: ["bgColor_var", {
33015
+ "--backgroundColor": "var(--b-scrim)"
33016
+ }]
33017
+ };
33018
+ var sheetCss = {
33019
+ ...{
33020
+ position: "relative",
33021
+ display: "df",
33022
+ flexDirection: "fdc",
33023
+ width: "w100",
33024
+ backgroundColor: ["bgColor_var", {
33025
+ "--backgroundColor": "var(--b-surface-raised)"
33026
+ }],
33027
+ color: ["color_var", {
33028
+ "--color": "var(--b-on-surface)"
33029
+ }],
33030
+ boxShadow: "bshModal",
33031
+ outline: "ol_0",
33032
+ bottom: "bot_0px"
33033
+ },
33034
+ ...{
33035
+ borderTopLeftRadius: "btlr_12px",
33036
+ borderTopRightRadius: "btrr_12px",
33037
+ paddingBottom: "pb_env_safe_area_inset_bottom"
33038
+ }
33039
+ };
33040
+
33041
+ // src/inputs/MenuSelectField/internal/MenuPanel.tsx
33042
+ var import_runtime174 = require("@homebound/truss/runtime");
33043
+ var import_jsx_runtime267 = require("react/jsx-runtime");
33044
+ function MenuPanel(props) {
33045
+ const {
33046
+ header,
33047
+ children,
33048
+ variant = "anchored"
33049
+ } = props;
33050
+ const tid = useTestIds(props, "menuPanel");
33051
+ return /* @__PURE__ */ (0, import_jsx_runtime267.jsxs)("div", { ...(0, import_runtime174.trussProps)({
33052
+ ...panelCss,
33053
+ ...variant === "anchored" ? anchoredCss : {}
33054
+ }), ...tid.menuPanel, children: [
33055
+ header && /* @__PURE__ */ (0, import_jsx_runtime267.jsx)("div", { ...(0, import_runtime174.trussProps)({
33056
+ flexShrink: "fs0",
33057
+ borderBottomStyle: "bbs_solid",
33058
+ borderBottomWidth: "bbw_1px",
33059
+ borderColor: ["bc_var", {
33060
+ "--borderColor": "var(--b-surface-separator)"
33061
+ }]
33062
+ }), children: header }),
33063
+ /* @__PURE__ */ (0, import_jsx_runtime267.jsx)("div", { className: "df fdc fg1 mh0", children })
33064
+ ] });
33065
+ }
33066
+ var panelCss = {
33067
+ display: "df",
33068
+ flexDirection: "fdc",
33069
+ width: "w100",
33070
+ overflow: "oh",
33071
+ color: ["color_var", {
33072
+ "--color": "var(--b-on-surface)"
33073
+ }],
33074
+ maxHeight: "maxh_var_menu_max_height_512px"
33075
+ };
33076
+ var anchoredCss = {
33077
+ backgroundColor: ["bgColor_var", {
33078
+ "--backgroundColor": "var(--b-surface-raised)"
33079
+ }],
33080
+ borderRadius: "br4",
33081
+ boxShadow: "bshBasic"
33082
+ };
33083
+
33084
+ // src/inputs/MenuSelectField/internal/MenuSearchInput.tsx
33085
+ var import_runtime175 = require("@homebound/truss/runtime");
33086
+ var import_jsx_runtime268 = require("react/jsx-runtime");
33087
+ function MenuSearchInput(props) {
33088
+ const {
33089
+ search,
33090
+ inputRef,
33091
+ label,
33092
+ placeholder = "Search"
33093
+ } = props;
33094
+ const tid = useTestIds(props, "menuSearch");
33095
+ return /* @__PURE__ */ (0, import_jsx_runtime268.jsxs)("label", { className: "df aic g_1 pl2 pr2 h_48px cur_text", children: [
33096
+ /* @__PURE__ */ (0, import_jsx_runtime268.jsx)("span", { ...(0, import_runtime175.trussProps)({
33097
+ display: "df",
33098
+ alignItems: "aic",
33099
+ flexShrink: "fs0",
33100
+ color: ["color_var", {
33101
+ "--color": "var(--b-on-surface-muted)"
33102
+ }]
33103
+ }), children: /* @__PURE__ */ (0, import_jsx_runtime268.jsx)(Icon, { icon: "search" }) }),
33104
+ /* @__PURE__ */ (0, import_jsx_runtime268.jsx)("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, ...(0, import_runtime175.trussProps)(inputCss), ...tid.search })
33105
+ ] });
33106
+ }
33107
+ var inputCss = {
33108
+ ...{
33109
+ flexGrow: "fg1",
33110
+ minWidth: "mw0",
33111
+ outline: "ol_0",
33112
+ backgroundColor: "bgTransparent",
33113
+ fontWeight: "fw4",
33114
+ fontSize: "fz_14px",
33115
+ lineHeight: "lh_20px",
33116
+ color: ["color_var", {
33117
+ "--color": "var(--b-on-surface)"
33118
+ }]
33119
+ },
33120
+ // iOS zooms the page when a focused input is under 16px.
33121
+ ...{
33122
+ fontSize: "sm_fs_16px"
33123
+ }
33124
+ };
33125
+
33126
+ // src/inputs/MenuSelectField/internal/MenuSelectTrigger.tsx
33127
+ var import_react_aria75 = require("react-aria");
33128
+ var import_runtime176 = require("@homebound/truss/runtime");
33129
+ var import_jsx_runtime269 = require("react/jsx-runtime");
33130
+ function MenuSelectTrigger(props) {
33131
+ const {
33132
+ label,
33133
+ required,
33134
+ errorMsg,
33135
+ helperText,
33136
+ disabled,
33137
+ readOnly,
33138
+ labelStyle: labelStyleProp,
33139
+ inputStylePalette,
33140
+ trigger,
33141
+ triggerRef
33142
+ } = props;
33143
+ const internalProps = props.internalProps ?? {};
33144
+ const {
33145
+ compound = false,
33146
+ forceFocus = false,
33147
+ forceHover = false
33148
+ } = internalProps;
33149
+ const tid = useTestIds(props, defaultTestId(label));
33150
+ const {
33151
+ fieldProps
33152
+ } = usePresentationContext();
33153
+ const labelStyle = labelStyleProp ?? fieldProps?.labelStyle ?? "above";
33154
+ const compact = props.compact ?? fieldProps?.compact ?? false;
33155
+ const borderless = props.borderless ?? fieldProps?.borderless ?? false;
33156
+ const borderOnHover = props.borderOnHover ?? fieldProps?.borderOnHover ?? false;
33157
+ const fullWidth = props.fullWidth ?? fieldProps?.fullWidth ?? false;
33158
+ const visuallyDisabled = props.visuallyDisabled ?? fieldProps?.visuallyDisabled ?? true;
33159
+ const errorInTooltip = props.errorInTooltip ?? fieldProps?.errorInTooltip ?? false;
33160
+ const typeScale = fieldProps?.typeScale ?? "sm";
33161
+ const labelSuffix = useLabelSuffix(required, trigger.isReadOnly);
33162
+ const showFocus = (trigger.isFocusVisible || trigger.isOpen) && !trigger.isDisabled && !trigger.isReadOnly || forceFocus;
33163
+ const showHover = trigger.isHovered && !trigger.isDisabled && !trigger.isReadOnly && !showFocus || forceHover;
33164
+ const showErrorAndHelper = !compound && !trigger.isDisabled && !trigger.isReadOnly;
33165
+ const {
33166
+ proposedValue: proposedText,
33167
+ originalValue: originalText
33168
+ } = trigger.proposalProps;
33169
+ const showProposal = proposedText !== void 0;
33170
+ const originalBelow = originalText && !trigger.isReadOnly ? originalText : void 0;
33171
+ const fieldChrome = getFieldChrome({
33172
+ typeScale,
33173
+ labelStyle,
33174
+ labelLeftFieldWidth: fieldProps?.labelLeftFieldWidth,
33175
+ compact,
33176
+ borderless,
33177
+ borderOnHover,
33178
+ fullWidth,
33179
+ compound,
33180
+ visuallyDisabled,
33181
+ isHovered: trigger.isHovered || forceHover,
33182
+ showProposal,
33183
+ inputStylePalette
33184
+ });
33185
+ const fieldStateCss = {
33186
+ ...fieldChrome.control,
33187
+ ...trigger.isDisabled ? fieldChrome.disabled : {},
33188
+ ...showFocus ? fieldChrome.focus : {},
33189
+ ...showHover ? fieldChrome.hover : {},
33190
+ ...errorMsg && !trigger.isDisabled ? fieldChrome.error : {},
33191
+ ...{
33192
+ textAlign: "tal",
33193
+ outline: "ol_0",
33194
+ appearance: "app_none",
33195
+ font: "fnt_inherit",
33196
+ ...!trigger.isDisabled ? {
33197
+ cursor: "cur_pointer"
33198
+ } : {}
33199
+ }
33200
+ };
33201
+ const supporting = /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)(import_jsx_runtime269.Fragment, { children: [
33202
+ originalBelow && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(OriginalValue, { originalValue: originalBelow, ...tid.originalValue }),
33203
+ showErrorAndHelper && errorMsg && !errorInTooltip && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(ErrorMessage, { id: trigger.errorId, errorMsg, ...tid.errorMsg }),
33204
+ showErrorAndHelper && helperText && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(HelperText, { helperText, ...tid.helperText })
33205
+ ] });
33206
+ const hasSupporting = !!(originalBelow || showErrorAndHelper && (errorMsg || helperText));
33207
+ const valueNode = /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)(import_jsx_runtime269.Fragment, { children: [
33208
+ labelStyle === "inline" && /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)("span", { id: trigger.labelId, ...(0, import_runtime176.trussProps)({
33209
+ fontWeight: "fw4",
33210
+ fontSize: "fz_14px",
33211
+ lineHeight: "lh_20px",
33212
+ whiteSpace: "wsnw",
33213
+ paddingRight: "pr_4px",
33214
+ color: ["color_var", {
33215
+ "--color": (0, import_runtime176.maybeCssVar)(trigger.isDisabled && visuallyDisabled ? "currentColor" : "--b-text-label" /* TextLabel */)
33216
+ }]
33217
+ }), children: [
33218
+ label,
33219
+ ":"
33220
+ ] }),
33221
+ /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { id: trigger.valueId, className: "df aic fg1 mw0 oh", children: trigger.isReadOnly && showProposal ? /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { className: "fg1 wsnw oh to_ellipsis", children: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(ProposedValue, { original: originalText, proposed: proposedText, ...tid.proposedValue }) }) : /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)(import_jsx_runtime269.Fragment, { children: [
33222
+ trigger.selectedLabels.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(Tooltip, { title: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(SelectedLabels, { labels: trigger.selectedLabels }), children: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { className: "df aic fs0 mr1", children: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(CountBadge, { count: trigger.selectedLabels.length, ...tid.count }) }) }),
33223
+ /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { ...(0, import_runtime176.trussProps)({
33224
+ ...{
33225
+ flexGrow: "fg1",
33226
+ whiteSpace: "wsnw",
33227
+ overflow: "oh",
33228
+ textOverflow: "to_ellipsis",
33229
+ color: ["color_var", {
33230
+ "--color": (0, import_runtime176.maybeCssVar)(trigger.isPlaceholder ? inputPlaceholderColor : void 0)
33231
+ }]
33232
+ },
33233
+ // A placeholder reads as hint text, so it stays at the field's regular weight.
33234
+ ...!trigger.isPlaceholder ? selectedValueCss(labelStyle, trigger.isReadOnly) : {},
33235
+ ...showProposal ? {
33236
+ fontWeight: "fw6",
33237
+ color: ["color_var", {
33238
+ "--color": "var(--b-ai-field-fg)"
33239
+ }]
33240
+ } : {}
33241
+ }), children: trigger.displayText })
33242
+ ] }) }),
33243
+ errorInTooltip && errorMsg && showErrorAndHelper && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { className: "df aic fs0 pl1", children: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(Icon, { icon: "error", color: "--b-danger" /* Danger */, tooltip: errorMsg }) }),
33244
+ !trigger.isReadOnly && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("span", { ...(0, import_runtime176.trussProps)({
33245
+ display: "df",
33246
+ alignItems: "aic",
33247
+ flexShrink: "fs0",
33248
+ paddingLeft: "pl1",
33249
+ color: ["color_var", {
33250
+ "--color": (0, import_runtime176.maybeCssVar)(trigger.isDisabled ? "--b-field-text-disabled" /* FieldTextDisabled */ : "--b-text-placeholder" /* TextPlaceholder */)
33251
+ }]
33252
+ }), ...tid.toggle, children: /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(Icon, { icon: trigger.isOpen ? "chevronUp" : "chevronDown" }) })
33253
+ ] });
33254
+ return /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)(import_jsx_runtime269.Fragment, { children: [
33255
+ /* @__PURE__ */ (0, import_jsx_runtime269.jsxs)("div", { ...(0, import_runtime176.trussProps)(fieldChrome.container), children: [
33256
+ label && labelStyle !== "inline" && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)(Label, { labelProps: {
33257
+ id: trigger.labelId,
33258
+ htmlFor: trigger.isReadOnly ? void 0 : trigger.triggerId,
33259
+ onClick: (event) => {
33260
+ event.preventDefault();
33261
+ if (trigger.isDisabled || trigger.isReadOnly || trigger.isOpen) return;
33262
+ triggerRef.current?.focus();
33263
+ trigger.open();
33264
+ }
33265
+ }, hidden: labelStyle === "hidden", label, inline: labelStyle === "left", suffix: labelSuffix, ...tid.label }),
33266
+ maybeTooltip({
33267
+ title: resolveTooltip(disabled, void 0, readOnly),
33268
+ placement: "top",
33269
+ children: trigger.isReadOnly ? /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("div", { ...(0, import_runtime176.trussProps)(fieldChrome.readOnly), "data-readonly": "true", "data-ai-mode": showProposal ? "true" : void 0, ...tid, children: valueNode }) : /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("button", { ...(0, import_react_aria75.mergeProps)(trigger.hoverProps, trigger.focusProps, {
33270
+ id: trigger.triggerId,
33271
+ type: "button",
33272
+ disabled: trigger.isDisabled,
33273
+ "aria-haspopup": "listbox",
33274
+ "aria-expanded": trigger.isOpen,
33275
+ "aria-controls": trigger.listId,
33276
+ "aria-labelledby": `${trigger.labelId} ${trigger.valueId}`,
33277
+ "aria-invalid": errorMsg ? true : void 0,
33278
+ "aria-errormessage": errorMsg ? trigger.errorId : void 0,
33279
+ "data-ai-mode": showProposal ? "true" : void 0,
33280
+ onKeyDown: trigger.onKeyDown,
33281
+ onClick: () => trigger.isOpen ? trigger.close({
33282
+ restoreFocus: true
33283
+ }) : trigger.open(),
33284
+ onFocus: trigger.onFocus,
33285
+ onBlur: trigger.onBlur
33286
+ }), ref: triggerRef, ...(0, import_runtime176.mergeProps)(BorderHoverChild, void 0, fieldStateCss), ...tid, children: valueNode })
33287
+ }),
33288
+ labelStyle !== "left" && supporting
33289
+ ] }),
33290
+ labelStyle === "left" && hasSupporting && /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("div", { className: "mt_neg1 ml_50", children: supporting })
33291
+ ] });
33292
+ }
33293
+ var inputPlaceholderColor = "#9ca3af";
33294
+ function SelectedLabels({
33295
+ labels
33296
+ }) {
33297
+ return /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("ul", { className: "mt0 mb0 mr0 ml0 pl2", children: labels.map(({
33298
+ key,
33299
+ label
33300
+ }) => /* @__PURE__ */ (0, import_jsx_runtime269.jsx)("li", { children: label }, key)) });
33301
+ }
33302
+
33303
+ // src/inputs/MenuSelectField/internal/OptionList.tsx
33304
+ var import_interactions2 = require("@react-aria/interactions");
33305
+ var import_react186 = require("react");
33306
+ var import_react_aria77 = require("react-aria");
33307
+ var import_react_virtuoso3 = require("react-virtuoso");
33308
+
33309
+ // src/inputs/MenuSelectField/internal/OptionRow.tsx
33310
+ var import_react185 = require("react");
33311
+ var import_react_aria76 = require("react-aria");
33312
+ var import_runtime177 = require("@homebound/truss/runtime");
33313
+ var import_jsx_runtime270 = require("react/jsx-runtime");
33314
+ function SingleOptionRow(props) {
33315
+ return /* @__PURE__ */ (0, import_jsx_runtime270.jsx)(BaseOptionRow, { ...props, variant: "check" });
33316
+ }
33317
+ function MultiOptionRow(props) {
33318
+ return /* @__PURE__ */ (0, import_jsx_runtime270.jsx)(BaseOptionRow, { ...props, variant: "checkbox" });
33319
+ }
33320
+ function BaseOptionRow(props) {
33321
+ const {
33322
+ item,
33323
+ state,
33324
+ id,
33325
+ disabledReason,
33326
+ variant
33327
+ } = props;
33328
+ const ref = (0, import_react185.useRef)(null);
33329
+ const tid = useTestIds(props, "option");
33330
+ const {
33331
+ hoverProps,
33332
+ isHovered
33333
+ } = (0, import_react_aria76.useHover)({});
33334
+ const {
33335
+ optionProps,
33336
+ isDisabled,
33337
+ isFocused,
33338
+ isSelected
33339
+ } = (0, import_react_aria76.useOption)({
33340
+ key: item.key,
33341
+ shouldSelectOnPressUp: true,
33342
+ shouldFocusOnHover: false
33343
+ }, state, ref);
33344
+ const highlighted = !isDisabled && (isHovered || isFocused);
33345
+ return maybeTooltip({
33346
+ title: disabledReason,
33347
+ placement: "top",
33348
+ children: /* @__PURE__ */ (0, import_jsx_runtime270.jsxs)(
33349
+ "div",
33350
+ {
33351
+ ...(0, import_react_aria76.mergeProps)(optionProps, hoverProps),
33352
+ id,
33353
+ "data-key": item.key,
33354
+ "data-label": item.textValue,
33355
+ ref,
33356
+ ...(0, import_runtime177.trussProps)({
33357
+ ...rowCss,
33358
+ ...highlighted ? {
33359
+ backgroundColor: ["bgColor_var", {
33360
+ "--backgroundColor": "var(--b-surface-raised-hover)"
33361
+ }]
33362
+ } : {},
33363
+ ...isDisabled ? {
33364
+ cursor: "cur_not_allowed",
33365
+ color: ["color_var", {
33366
+ "--color": "var(--b-text-disabled)"
33367
+ }]
33368
+ } : {}
33369
+ }),
33370
+ ...tid.option,
33371
+ children: [
33372
+ variant === "checkbox" && /* @__PURE__ */ (0, import_jsx_runtime270.jsx)(StyledCheckbox, { isSelected, isDisabled }),
33373
+ /* @__PURE__ */ (0, import_jsx_runtime270.jsx)("span", { className: "wsnw oh to_ellipsis fg1 mw0", children: item.rendered }),
33374
+ variant === "check" && isSelected && /* @__PURE__ */ (0, import_jsx_runtime270.jsx)("span", { className: "df aic fs0", children: /* @__PURE__ */ (0, import_jsx_runtime270.jsx)(Icon, { icon: "check", color: isDisabled ? "--b-text-disabled" /* TextDisabled */ : "--b-selection-indicator" /* SelectionIndicator */ }) })
33375
+ ]
33376
+ }
33377
+ )
33378
+ });
33379
+ }
33380
+ var menuRowHeight = 40;
33381
+ var rowCss = {
33382
+ display: "df",
33383
+ alignItems: "aic",
33384
+ gap: "g_1",
33385
+ paddingLeft: "pl2",
33386
+ paddingRight: "pr2",
33387
+ height: ["h_var", {
33388
+ "--height": `${menuRowHeight}px`
33389
+ }],
33390
+ outline: "ol_0",
33391
+ cursor: "cur_pointer",
33392
+ fontWeight: "fw4",
33393
+ fontSize: "fz_14px",
33394
+ lineHeight: "lh_20px",
33395
+ color: ["color_var", {
33396
+ "--color": "var(--b-on-surface)"
33397
+ }]
33398
+ };
33399
+
33400
+ // src/inputs/MenuSelectField/internal/OptionList.tsx
33401
+ var import_runtime178 = require("@homebound/truss/runtime");
33402
+ var import_jsx_runtime271 = require("react/jsx-runtime");
33403
+ function OptionList(props) {
33404
+ const {
33405
+ menu,
33406
+ listRef,
33407
+ label,
33408
+ onKeyDown,
33409
+ activeDescendant
33410
+ } = props;
33411
+ const {
33412
+ state,
33413
+ listId: id,
33414
+ disabledReasons,
33415
+ initialIndex,
33416
+ loading,
33417
+ rowVariant
33418
+ } = menu;
33419
+ const tid = useTestIds(props, "optionList");
33420
+ const virtuosoRef = (0, import_react186.useRef)(null);
33421
+ const {
33422
+ listBoxProps
33423
+ } = (0, import_react_aria77.useListBox)({
33424
+ id,
33425
+ "aria-label": label,
33426
+ autoFocus: false,
33427
+ shouldUseVirtualFocus: true,
33428
+ shouldFocusOnHover: false,
33429
+ shouldSelectOnPressUp: true,
33430
+ isVirtualized: true
33431
+ }, state, listRef);
33432
+ const items = [...state.collection];
33433
+ const focusedKey = state.selectionManager.focusedKey;
33434
+ (0, import_react186.useEffect)(() => {
33435
+ if (focusedKey == null || (0, import_interactions2.getInteractionModality)() !== "keyboard") return;
33436
+ const index = state.collection.getItem(focusedKey)?.index;
33437
+ if (index !== void 0) virtuosoRef.current?.scrollIntoView({
33438
+ index,
33439
+ behavior: "auto"
33440
+ });
33441
+ }, [focusedKey, state.collection]);
33442
+ const [{
33443
+ initialTop,
33444
+ initialCount
33445
+ }] = (0, import_react186.useState)(() => ({
33446
+ initialTop: Math.max(0, Math.min(initialIndex, items.length - 1)),
33447
+ initialCount: items.length
33448
+ }));
33449
+ const syncScroll = initialTop + initialRenderCount <= maxSyncRenderCount;
33450
+ (0, import_react186.useLayoutEffect)(() => {
33451
+ const scroller = listRef.current?.firstElementChild;
33452
+ if (!syncScroll || !scroller) return;
33453
+ const maxTop = Math.max(0, initialCount * menuRowHeight - scroller.clientHeight);
33454
+ setScrollTop(scroller, Math.min(initialTop * menuRowHeight, maxTop));
33455
+ }, [listRef, syncScroll, initialTop, initialCount]);
33456
+ const Row2 = rowVariant === "checkbox" ? MultiOptionRow : SingleOptionRow;
33457
+ const isTest = process.env.NODE_ENV === "test";
33458
+ return /* @__PURE__ */ (0, import_jsx_runtime271.jsx)("div", { ...listBoxProps, ...onKeyDown ? {
33459
+ onKeyDown,
33460
+ tabIndex: -1,
33461
+ "aria-activedescendant": activeDescendant
33462
+ } : {}, ref: listRef, className: "df fdc fg1 mh0 ol_0", ...tid.listbox, children: items.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime271.jsx)("div", { role: "presentation", ...(0, import_runtime178.trussProps)(emptyCss), ...tid.empty, children: "No results" }) : /* @__PURE__ */ (0, import_jsx_runtime271.jsxs)(import_jsx_runtime271.Fragment, { children: [
33463
+ items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime271.jsx)(import_react_virtuoso3.Virtuoso, { ref: virtuosoRef, style: {
33464
+ height: items.length * menuRowHeight,
33465
+ flexShrink: 1,
33466
+ minHeight: 0,
33467
+ overscrollBehavior: "contain"
33468
+ }, totalCount: items.length, fixedItemHeight: menuRowHeight, computeItemKey: (index) => String(items[index]?.key ?? index), ...isTest ? {
33469
+ initialItemCount: items.length
33470
+ } : syncScroll ? {
33471
+ initialItemCount: Math.min(items.length, initialTop + initialRenderCount)
33472
+ } : {
33473
+ initialTopMostItemIndex: initialTop
33474
+ }, itemContent: (index) => {
33475
+ const item = items[index];
33476
+ if (!item) return null;
33477
+ return /* @__PURE__ */ (0, import_jsx_runtime271.jsx)(Row2, { item, state, id: optionDomId(id, index), disabledReason: disabledReasons[String(item.key)], ...tid });
33478
+ } }, isTest ? items.length : "virtuoso"),
33479
+ loading && /* @__PURE__ */ (0, import_jsx_runtime271.jsx)(LoadingDots, {})
33480
+ ] }) });
33481
+ }
33482
+ function optionDomId(listId, index) {
33483
+ return `${listId}-option-${index}`;
33484
+ }
33485
+ function setScrollTop(el, top) {
33486
+ el.scrollTop = top;
33487
+ }
33488
+ var initialRenderCount = 13;
33489
+ var maxSyncRenderCount = 60;
33490
+ var emptyCss = {
33491
+ display: "df",
33492
+ alignItems: "aic",
33493
+ paddingLeft: "pl2",
33494
+ paddingRight: "pr2",
33495
+ height: ["h_var", {
33496
+ "--height": `${menuRowHeight}px`
33497
+ }],
33498
+ fontWeight: "fw4",
33499
+ fontSize: "fz_14px",
33500
+ lineHeight: "lh_20px",
33501
+ color: ["color_var", {
33502
+ "--color": "var(--b-on-surface-muted)"
33503
+ }]
33504
+ };
33505
+
33506
+ // src/inputs/MenuSelectField/internal/useMenuSelectField.tsx
33507
+ var import_react187 = require("react");
33508
+ var import_react_aria78 = require("react-aria");
33509
+ var import_react_stately20 = require("react-stately");
33510
+ var import_jsx_runtime272 = require("react/jsx-runtime");
33511
+ function useMenuSelectField(props) {
33512
+ const {
33513
+ options: optionsProp,
33514
+ getOptionValue = defaultOptionValue,
33515
+ getOptionLabel = defaultOptionLabel,
33516
+ getOptionMenuLabel,
33517
+ getOptionSearchText,
33518
+ disabledOptions,
33519
+ nothingSelectedText = "",
33520
+ placeholder,
33521
+ disabled,
33522
+ readOnly,
33523
+ onFocus,
33524
+ onBlur,
33525
+ selectionMode,
33526
+ values: propValues,
33527
+ proposedValues,
33528
+ onCommit
33529
+ } = props;
33530
+ const multiple = selectionMode === "multiple";
33531
+ const isDisabled = !!disabled;
33532
+ const isReadOnly = !!readOnly;
33533
+ const fieldId = (0, import_react187.useId)();
33534
+ const listId = `${fieldId}-listbox`;
33535
+ const triggerId = `${fieldId}-trigger`;
33536
+ const labelId = `${fieldId}-label`;
33537
+ const valueId = `${fieldId}-value`;
33538
+ const errorId = `${fieldId}-error`;
33539
+ const triggerRef = (0, import_react187.useRef)(null);
33540
+ const searchRef = (0, import_react187.useRef)(null);
33541
+ const listRef = (0, import_react187.useRef)(null);
33542
+ const hasFocusRef = (0, import_react187.useRef)(false);
33543
+ const [isOpen2, setIsOpen] = (0, import_react187.useState)(false);
33544
+ const [search, setSearch] = (0, import_react187.useState)("");
33545
+ const [optionsLoading, setOptionsLoading] = (0, import_react187.useState)(false);
33546
+ const didRequestOptionsRef = (0, import_react187.useRef)(false);
33547
+ const options = (0, import_react187.useMemo)(
33548
+ () => initializeOptions(optionsProp, getOptionValue, getOptionLabel, void 0, false),
33549
+ // getOptionValue and getOptionLabel are typically inline lambdas
33550
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33551
+ [optionsProp]
33552
+ );
33553
+ const { hoverProps, isHovered } = (0, import_react_aria78.useHover)({});
33554
+ const { focusProps, isFocusVisible } = (0, import_react_aria78.useFocusRing)();
33555
+ const { contains } = (0, import_react_aria78.useFilter)({ sensitivity: "base" });
33556
+ const optionsByKey = (0, import_react187.useMemo)(
33557
+ () => new Map(options.map((o) => [valueToKey(getOptionValue(o)), o])),
33558
+ // getOptionValue is typically an inline lambda
33559
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33560
+ [options]
33561
+ );
33562
+ const { effectiveValue, proposalProps } = useAiProposal(
33563
+ propValues,
33564
+ proposedValues,
33565
+ (vs) => labelsFor(vs, options, getOptionValue, getOptionLabel).join(", ")
33566
+ );
33567
+ const values = (0, import_react187.useMemo)(() => effectiveValue ?? [], [effectiveValue]);
33568
+ const selectedKeys = (0, import_react187.useMemo)(() => new Set(values.map(valueToKey)), [values]);
33569
+ const selectedOptions = (0, import_react187.useMemo)(
33570
+ () => values.map((v) => optionsByKey.get(valueToKey(v))).filter((o) => o !== void 0),
33571
+ [values, optionsByKey]
33572
+ );
33573
+ const filteredOptions = (0, import_react187.useMemo)(
33574
+ () => search ? options.filter((o) => matchesSearch(o, search, getOptionLabel, getOptionSearchText, contains)) : options,
33575
+ // getOptionLabel and getOptionSearchText are typically inline lambdas
33576
+ // oxlint-disable-next-line react-hooks/exhaustive-deps
33577
+ [options, search, contains]
33578
+ );
33579
+ const [disabledKeys, disabledReasons] = (0, import_react187.useMemo)(() => {
33580
+ const tuples = (disabledOptions ?? []).map(disabledOptionToKeyedTuple);
33581
+ return [tuples.map(([k]) => String(k)), Object.fromEntries(tuples.map(([k, r]) => [String(k), r]))];
33582
+ }, [disabledOptions]);
33583
+ function onSelectionChange(keys) {
33584
+ if (keys === "all") return;
33585
+ if (!multiple) {
33586
+ const [key] = [...keys];
33587
+ if (key === void 0) {
33588
+ close({ restoreFocus: true });
33589
+ return;
33590
+ }
33591
+ const opt = optionsByKey.get(String(key));
33592
+ proposalProps.onUserEdit?.();
33593
+ onCommit(opt === void 0 ? [] : [getOptionValue(opt)], opt === void 0 ? [] : [opt]);
33594
+ close({ restoreFocus: true });
33595
+ return;
33596
+ }
33597
+ const next = values.filter((v) => keys.has(valueToKey(v)));
33598
+ for (const k of keys) {
33599
+ const opt = optionsByKey.get(String(k));
33600
+ if (opt !== void 0 && !selectedKeys.has(String(k))) next.push(getOptionValue(opt));
33601
+ }
33602
+ proposalProps.onUserEdit?.();
33603
+ onCommit(
33604
+ next,
33605
+ next.map((v) => optionsByKey.get(valueToKey(v))).filter((o) => o !== void 0)
33606
+ );
33607
+ }
33608
+ const state = (0, import_react_stately20.useListState)({
33609
+ items: filteredOptions,
33610
+ children: (o) => /* @__PURE__ */ (0, import_jsx_runtime272.jsx)(import_react_stately20.Item, { textValue: getOptionLabel(o), children: getOptionMenuLabel ? getOptionMenuLabel(o) : getOptionLabel(o) }, valueToKey(getOptionValue(o))),
33611
+ selectionMode: multiple ? "multiple" : "single",
33612
+ selectedKeys,
33613
+ disabledKeys,
33614
+ onSelectionChange
33615
+ });
33616
+ const { selectionManager } = state;
33617
+ const keyboardDelegate = (0, import_react187.useMemo)(
33618
+ () => new MenuSelectKeyboardDelegate({
33619
+ collection: state.collection,
33620
+ disabledKeys: state.disabledKeys,
33621
+ ref: listRef
33622
+ }),
33623
+ [state.collection, state.disabledKeys]
33624
+ );
33625
+ function open() {
33626
+ if (isDisabled || isReadOnly) return;
33627
+ setSearch("");
33628
+ setIsOpen(true);
33629
+ if (didRequestOptionsRef.current || Array.isArray(optionsProp)) return;
33630
+ didRequestOptionsRef.current = true;
33631
+ setOptionsLoading(true);
33632
+ void optionsProp.load().finally(() => setOptionsLoading(false));
33633
+ }
33634
+ function close(opts) {
33635
+ setIsOpen(false);
33636
+ setSearch("");
33637
+ if (opts.restoreFocus) {
33638
+ triggerRef.current?.focus({ preventScroll: true });
33639
+ } else if (hasFocusRef.current) {
33640
+ settleBlur();
33641
+ }
33642
+ }
33643
+ function settleBlur() {
33644
+ hasFocusRef.current = false;
33645
+ maybeCall(proposalProps.onUserBlur);
33646
+ maybeCall(onBlur);
33647
+ }
33648
+ const showSearch = options.length > searchOptionLimit;
33649
+ (0, import_react187.useLayoutEffect)(() => {
33650
+ if (!isOpen2) return;
33651
+ const keyTarget = showSearch ? searchRef.current : listRef.current;
33652
+ keyTarget?.focus({ preventScroll: true });
33653
+ selectionManager.setFocusedKey(null);
33654
+ selectionManager.setFocused(false);
33655
+ }, [isOpen2, showSearch]);
33656
+ function onSearchChange(value) {
33657
+ setSearch(value);
33658
+ selectionManager.setFocusedKey(null);
33659
+ selectionManager.setFocused(false);
33660
+ }
33661
+ function focusKey(key) {
33662
+ if (key == null) return;
33663
+ selectionManager.setFocused(true);
33664
+ selectionManager.setFocusedKey(key);
33665
+ }
33666
+ function onMenuKeyDown(e) {
33667
+ const current2 = selectionManager.focusedKey;
33668
+ switch (e.key) {
33669
+ case "ArrowDown":
33670
+ e.preventDefault();
33671
+ focusKey(
33672
+ current2 == null ? keyboardDelegate.getFirstKey() : keyboardDelegate.getKeyBelow(current2) ?? keyboardDelegate.getFirstKey()
33673
+ );
33674
+ break;
33675
+ case "ArrowUp":
33676
+ e.preventDefault();
33677
+ focusKey(
33678
+ current2 == null ? keyboardDelegate.getLastKey() : keyboardDelegate.getKeyAbove(current2) ?? keyboardDelegate.getLastKey()
33679
+ );
33680
+ break;
33681
+ case "PageDown":
33682
+ e.preventDefault();
33683
+ focusKey(current2 == null ? keyboardDelegate.getFirstKey() : keyboardDelegate.getKeyPageBelow(current2));
33684
+ break;
33685
+ case "PageUp":
33686
+ e.preventDefault();
33687
+ focusKey(current2 == null ? keyboardDelegate.getLastKey() : keyboardDelegate.getKeyPageAbove(current2));
33688
+ break;
33689
+ case "Home":
33690
+ e.preventDefault();
33691
+ focusKey(keyboardDelegate.getFirstKey());
33692
+ break;
33693
+ case "End":
33694
+ e.preventDefault();
33695
+ focusKey(keyboardDelegate.getLastKey());
33696
+ break;
33697
+ case "Enter": {
33698
+ e.preventDefault();
33699
+ const key = selectionManager.focusedKey;
33700
+ if (key != null && !state.disabledKeys.has(key)) selectionManager.select(key);
33701
+ break;
33702
+ }
33703
+ case "Escape":
33704
+ e.preventDefault();
33705
+ e.stopPropagation();
33706
+ close({ restoreFocus: true });
33707
+ break;
33708
+ case "Tab":
33709
+ e.preventDefault();
33710
+ close({ restoreFocus: true });
33711
+ break;
33712
+ default:
33713
+ break;
33714
+ }
33715
+ }
33716
+ function onTriggerKeyDown(e) {
33717
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
33718
+ e.preventDefault();
33719
+ open();
33720
+ }
33721
+ }
33722
+ function onTriggerFocus() {
33723
+ if (hasFocusRef.current) return;
33724
+ hasFocusRef.current = true;
33725
+ maybeCall(onFocus);
33726
+ }
33727
+ function onTriggerBlur() {
33728
+ if (isOpen2) return;
33729
+ settleBlur();
33730
+ }
33731
+ const focusedKey = selectionManager.focusedKey;
33732
+ const focusedIndex = focusedKey != null ? state.collection.getItem(focusedKey)?.index : void 0;
33733
+ const activeDescendant = isOpen2 && focusedIndex !== void 0 ? optionDomId(listId, focusedIndex) : void 0;
33734
+ const initialIndex = Math.max(
33735
+ 0,
33736
+ filteredOptions.findIndex((o) => selectedKeys.has(valueToKey(getOptionValue(o))))
33737
+ );
33738
+ const selectedText = !multiple && selectedOptions[0] !== void 0 ? getOptionLabel(selectedOptions[0]) : "";
33739
+ const displayText = selectedText || (values.length > 0 ? "" : nothingSelectedText || placeholder || "");
33740
+ const isPlaceholder = !selectedText && values.length === 0 && !nothingSelectedText && !!placeholder;
33741
+ const selectedLabels = multiple ? selectedOptions.map((o) => ({ key: valueToKey(getOptionValue(o)), label: getOptionLabel(o) })) : [];
33742
+ const triggerProps = {
33743
+ isDisabled,
33744
+ isReadOnly,
33745
+ isOpen: isOpen2,
33746
+ listId,
33747
+ triggerId,
33748
+ labelId,
33749
+ valueId,
33750
+ errorId,
33751
+ hoverProps,
33752
+ focusProps,
33753
+ isFocusVisible,
33754
+ isHovered,
33755
+ open,
33756
+ close,
33757
+ onKeyDown: onTriggerKeyDown,
33758
+ onFocus: onTriggerFocus,
33759
+ onBlur: onTriggerBlur,
33760
+ displayText,
33761
+ isPlaceholder,
33762
+ selectedLabels,
33763
+ proposalProps
33764
+ };
33765
+ const searchProps = {
33766
+ show: showSearch,
33767
+ value: search,
33768
+ onChange: onSearchChange,
33769
+ listId,
33770
+ activeDescendant,
33771
+ onKeyDown: onMenuKeyDown
33772
+ };
33773
+ const menuProps = {
33774
+ isOpen: isOpen2,
33775
+ close,
33776
+ listId,
33777
+ state,
33778
+ loading: optionsLoading,
33779
+ disabledReasons,
33780
+ initialIndex,
33781
+ rowVariant: multiple ? "checkbox" : "check",
33782
+ onKeyDown: onMenuKeyDown,
33783
+ activeDescendant
33784
+ };
33785
+ return { triggerRef, trigger: triggerProps, searchRef, search: searchProps, listRef, menu: menuProps };
33786
+ }
33787
+ function labelsFor(values, options, getOptionValue, getOptionLabel) {
33788
+ const keys = new Set(values.map(valueToKey));
33789
+ return options.filter((option) => keys.has(valueToKey(getOptionValue(option)))).map(getOptionLabel);
33790
+ }
33791
+ function matchesSearch(option, query, getOptionLabel, getOptionSearchText, contains) {
33792
+ if (contains(getOptionLabel(option), query)) return true;
33793
+ const extra = getOptionSearchText?.(option);
33794
+ const terms = typeof extra === "string" ? [extra] : extra;
33795
+ return terms?.some((term) => contains(term, query)) ?? false;
33796
+ }
33797
+ var searchOptionLimit = 8;
33798
+ var MenuSelectKeyboardDelegate = class _MenuSelectKeyboardDelegate extends import_react_aria78.ListKeyboardDelegate {
33799
+ /** Rows skipped by Page Up / Page Down. */
33800
+ static pageSize = 10;
33801
+ getKeyPageBelow(key) {
33802
+ return this.stepKeys(key, "below");
33803
+ }
33804
+ getKeyPageAbove(key) {
33805
+ return this.stepKeys(key, "above");
33806
+ }
33807
+ stepKeys(key, direction) {
33808
+ let next = key;
33809
+ for (let index = 0; index < _MenuSelectKeyboardDelegate.pageSize; index += 1) {
33810
+ if (next == null) return next;
33811
+ const candidate = direction === "below" ? this.getKeyBelow(next) : this.getKeyAbove(next);
33812
+ if (candidate == null) return next;
33813
+ next = candidate;
33814
+ }
33815
+ return next;
33816
+ }
33817
+ };
33818
+
33819
+ // src/inputs/MenuSelectField/internal/BaseMenuSelectField.tsx
33820
+ var import_jsx_runtime273 = require("react/jsx-runtime");
33821
+ function BaseMenuSelectField(props) {
33822
+ const {
33823
+ label,
33824
+ searchPlaceholder,
33825
+ selectionMode: _selectionMode,
33826
+ values: _values,
33827
+ proposedValues: _proposedValues,
33828
+ onCommit: _onCommit,
33829
+ ...fieldProps
33830
+ } = props;
33831
+ const { triggerRef, trigger, searchRef, search, listRef, menu } = useMenuSelectField(props);
33832
+ const tid = useTestIds(props, defaultTestId(label));
33833
+ const { sm: isMobile } = useBreakpoint();
33834
+ const panel = /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(
33835
+ MenuPanel,
33836
+ {
33837
+ variant: isMobile ? "sheet" : "anchored",
33838
+ header: search.show ? /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(
33839
+ MenuSearchInput,
33840
+ {
33841
+ search,
33842
+ inputRef: searchRef,
33843
+ label: `Search ${label}`,
33844
+ placeholder: searchPlaceholder,
33845
+ ...tid
33846
+ }
33847
+ ) : void 0,
33848
+ ...tid,
33849
+ children: /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(
33850
+ OptionList,
33851
+ {
33852
+ menu,
33853
+ listRef,
33854
+ label,
33855
+ onKeyDown: search.show ? void 0 : menu.onKeyDown,
33856
+ activeDescendant: search.show ? void 0 : menu.activeDescendant,
33857
+ ...tid
33858
+ }
33859
+ )
33860
+ }
33861
+ );
33862
+ return /* @__PURE__ */ (0, import_jsx_runtime273.jsxs)(import_jsx_runtime273.Fragment, { children: [
33863
+ /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(MenuSelectTrigger, { ...fieldProps, label, trigger, triggerRef }),
33864
+ isMobile ? /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(BottomSheet, { isOpen: menu.isOpen, onClose: () => menu.close({ restoreFocus: true }), label, ...tid, children: panel }) : /* @__PURE__ */ (0, import_jsx_runtime273.jsx)(
33865
+ AnchoredOverlay,
33866
+ {
33867
+ triggerRef,
33868
+ isOpen: menu.isOpen,
33869
+ onClose: () => menu.close({ restoreFocus: false }),
33870
+ ...tid,
33871
+ children: panel
33872
+ }
33873
+ )
33874
+ ] });
33875
+ }
33876
+
33877
+ // src/inputs/MenuSelectField/MenuMultiSelectField.tsx
33878
+ var import_jsx_runtime274 = require("react/jsx-runtime");
33879
+ function MenuMultiSelectField(props) {
33880
+ const { onSelect, ...rest } = props;
33881
+ return /* @__PURE__ */ (0, import_jsx_runtime274.jsx)(BaseMenuSelectField, { ...rest, selectionMode: "multiple", onCommit: onSelect });
33882
+ }
33883
+
33884
+ // src/inputs/MenuSelectField/MenuSelectField.tsx
33885
+ var import_react188 = require("react");
33886
+ var import_jsx_runtime275 = require("react/jsx-runtime");
33887
+ function MenuSelectField(props) {
33888
+ const { value, proposedValue, onSelect, ...rest } = props;
33889
+ const values = (0, import_react188.useMemo)(() => value === void 0 ? [] : [value], [value]);
33890
+ const proposedValues = (0, import_react188.useMemo)(() => proposedValue === void 0 ? void 0 : [proposedValue], [proposedValue]);
33891
+ return /* @__PURE__ */ (0, import_jsx_runtime275.jsx)(
33892
+ BaseMenuSelectField,
33893
+ {
33894
+ ...rest,
33895
+ selectionMode: "single",
33896
+ values,
33897
+ proposedValues,
33898
+ onCommit: (next, opts) => onSelect(next[0], opts[0])
33899
+ }
33900
+ );
33901
+ }
33902
+
33903
+ // src/inputs/ToggleButton.tsx
33904
+ var import_react189 = require("react");
33905
+ var import_react_aria79 = require("react-aria");
33906
+ var import_react_stately21 = require("react-stately");
33907
+ var import_runtime179 = require("@homebound/truss/runtime");
33908
+ var import_jsx_runtime276 = require("react/jsx-runtime");
32832
33909
  function ToggleButton(props) {
32833
33910
  const {
32834
33911
  selected: isSelected = false,
@@ -32839,7 +33916,7 @@ function ToggleButton(props) {
32839
33916
  __storyState,
32840
33917
  ...otherProps
32841
33918
  } = props;
32842
- const [asyncInProgress, setAsyncInProgress] = (0, import_react182.useState)(false);
33919
+ const [asyncInProgress, setAsyncInProgress] = (0, import_react189.useState)(false);
32843
33920
  const isDisabled = !!disabled || asyncInProgress;
32844
33921
  const ariaProps = {
32845
33922
  "aria-label": label,
@@ -32847,7 +33924,7 @@ function ToggleButton(props) {
32847
33924
  isDisabled,
32848
33925
  ...otherProps
32849
33926
  };
32850
- const state = (0, import_react_stately20.useToggleState)({
33927
+ const state = (0, import_react_stately21.useToggleState)({
32851
33928
  ...ariaProps,
32852
33929
  onChange: (e) => {
32853
33930
  const result = onChange(e);
@@ -32858,30 +33935,30 @@ function ToggleButton(props) {
32858
33935
  return result;
32859
33936
  }
32860
33937
  });
32861
- const labelRef = (0, import_react182.useRef)(null);
32862
- const ref = (0, import_react182.useRef)(null);
33938
+ const labelRef = (0, import_react189.useRef)(null);
33939
+ const ref = (0, import_react189.useRef)(null);
32863
33940
  const tid = useTestIds(otherProps, label);
32864
33941
  const {
32865
33942
  isPressed: isPressedFromEvents,
32866
33943
  pressProps
32867
- } = (0, import_react_aria72.usePress)({
33944
+ } = (0, import_react_aria79.usePress)({
32868
33945
  ref: labelRef,
32869
33946
  isDisabled
32870
33947
  });
32871
33948
  const {
32872
33949
  inputProps
32873
- } = (0, import_react_aria72.useSwitch)(ariaProps, state, ref);
33950
+ } = (0, import_react_aria79.useSwitch)(ariaProps, state, ref);
32874
33951
  const {
32875
33952
  isFocusVisible: isFocusVisibleFromEvents,
32876
33953
  focusProps
32877
- } = (0, import_react_aria72.useFocusRing)({
33954
+ } = (0, import_react_aria79.useFocusRing)({
32878
33955
  ...otherProps,
32879
33956
  within: true
32880
33957
  });
32881
33958
  const {
32882
33959
  hoverProps,
32883
33960
  isHovered: isHoveredFromEvents
32884
- } = (0, import_react_aria72.useHover)({
33961
+ } = (0, import_react_aria79.useHover)({
32885
33962
  isDisabled
32886
33963
  });
32887
33964
  const isHovered = __storyState?.hovered ?? isHoveredFromEvents;
@@ -32892,7 +33969,7 @@ function ToggleButton(props) {
32892
33969
  ...focusProps,
32893
33970
  ...hoverProps,
32894
33971
  ...pressProps,
32895
- ...(0, import_runtime173.trussProps)({
33972
+ ...(0, import_runtime179.trussProps)({
32896
33973
  // Gray500 off-state has no semantic match — keep palette (OnSurfaceMuted is Gray700).
32897
33974
  ...{
32898
33975
  borderRadius: "br4",
@@ -32932,10 +34009,10 @@ function ToggleButton(props) {
32932
34009
  return maybeTooltip({
32933
34010
  title: tooltip,
32934
34011
  placement: "top",
32935
- children: /* @__PURE__ */ (0, import_jsx_runtime265.jsxs)("label", { ...labelAttrs, children: [
32936
- icon && /* @__PURE__ */ (0, import_jsx_runtime265.jsx)(Icon, { icon }),
34012
+ children: /* @__PURE__ */ (0, import_jsx_runtime276.jsxs)("label", { ...labelAttrs, children: [
34013
+ icon && /* @__PURE__ */ (0, import_jsx_runtime276.jsx)(Icon, { icon }),
32937
34014
  label,
32938
- /* @__PURE__ */ (0, import_jsx_runtime265.jsx)(import_react_aria72.VisuallyHidden, { children: /* @__PURE__ */ (0, import_jsx_runtime265.jsx)("input", { ref, ...inputProps, ...tid.value }) })
34015
+ /* @__PURE__ */ (0, import_jsx_runtime276.jsx)(import_react_aria79.VisuallyHidden, { children: /* @__PURE__ */ (0, import_jsx_runtime276.jsx)("input", { ref, ...inputProps, ...tid.value }) })
32939
34016
  ] })
32940
34017
  });
32941
34018
  }
@@ -33076,6 +34153,8 @@ var togglePressStyles = {
33076
34153
  Loader,
33077
34154
  LoadingSkeleton,
33078
34155
  MaxLines,
34156
+ MenuMultiSelectField,
34157
+ MenuSelectField,
33079
34158
  ModalBanner,
33080
34159
  ModalBody,
33081
34160
  ModalFilterItem,