@homebound/beam 3.39.0 → 3.41.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
@@ -97,7 +97,6 @@ __export(index_exports, {
97
97
  EnvironmentBannerLayout: () => EnvironmentBannerLayout,
98
98
  ErrorMessage: () => ErrorMessage,
99
99
  FieldGroup: () => FieldGroup,
100
- FilterDropdownMenu: () => _FilterDropdownMenu,
101
100
  FilterModal: () => FilterModal,
102
101
  Filters: () => _Filters,
103
102
  FormDivider: () => FormDivider,
@@ -182,6 +181,7 @@ __export(index_exports, {
182
181
  Tabs: () => Tabs,
183
182
  TabsWithContent: () => TabsWithContent,
184
183
  Tag: () => Tag,
184
+ TagGroup: () => TagGroup,
185
185
  TextAreaField: () => TextAreaField,
186
186
  TextField: () => TextField,
187
187
  Toast: () => Toast,
@@ -2112,6 +2112,32 @@ var CssBuilder = class _CssBuilder {
2112
2112
  position(value) {
2113
2113
  return this.add("position", value);
2114
2114
  }
2115
+ // scrollSnap
2116
+ /** Sets `scrollSnapAlign: value`. */
2117
+ ssa(value) {
2118
+ return this.add("scrollSnapAlign", value);
2119
+ }
2120
+ /** Sets `scrollSnapType: value`. */
2121
+ sst(value) {
2122
+ return this.add("scrollSnapType", value);
2123
+ }
2124
+ // scrollbarWidth
2125
+ /** Sets `scrollbarWidth: "auto"`. */
2126
+ get sbwa() {
2127
+ return this.add("scrollbarWidth", "auto");
2128
+ }
2129
+ /** Sets `scrollbarWidth: "thin"`. */
2130
+ get sbwt() {
2131
+ return this.add("scrollbarWidth", "thin");
2132
+ }
2133
+ /** Sets `scrollbarWidth: "none"`. */
2134
+ get sbwn() {
2135
+ return this.add("scrollbarWidth", "none");
2136
+ }
2137
+ /** Sets `scrollbarWidth: value`. */
2138
+ sbw(value) {
2139
+ return this.add("scrollbarWidth", value);
2140
+ }
2115
2141
  // skins
2116
2142
  /** Sets `color: "rgba(255, 255, 255, 1)"`. */
2117
2143
  get white() {
@@ -9380,7 +9406,7 @@ function RowImpl(props) {
9380
9406
  const tooltip = isGridCellContent(maybeContent) ? maybeContent.tooltip : void 0;
9381
9407
  const renderFn = (rowStyle?.renderCell || rowStyle?.rowLink) && wrapAction ? rowLinkRenderFn(as, currentColspan) : isHeader || isTotals || isExpandableHeader ? headerRenderFn(column2, as, currentColspan) : rowStyle?.onClick && wrapAction ? rowClickRenderFn(as, api, currentColspan) : defaultRenderFn(as, currentColspan);
9382
9408
  const cellElement = renderFn(columnIndex, cellCss, content, row, rowStyle, void 0, cellOnClick, tooltip);
9383
- if (!disableColumnResizing && isHeader && columnIndex < columns.length - 1 && currentColspan === 1 && !isContentColumn(column2)) {
9409
+ if (!disableColumnResizing && isHeader && columnIndex < columns.length - 1 && currentColspan === 1 && isContentColumn(column2)) {
9384
9410
  const currentSizeStr = columnSizes[columnIndex];
9385
9411
  const minWidthPx = column2.mw ? parseInt(column2.mw.replace("px", ""), 10) : 100;
9386
9412
  const currentWidthPx = parseWidthToPx(currentSizeStr, void 0) ?? resizedWidths?.[column2.id] ?? minWidthPx;
@@ -20094,7 +20120,7 @@ function invertSpacing(value) {
20094
20120
  }
20095
20121
 
20096
20122
  // src/components/Layout/GridTableLayout/GridTableLayout.tsx
20097
- var import_utils124 = require("@react-aria/utils");
20123
+ var import_utils125 = require("@react-aria/utils");
20098
20124
  var import_react110 = __toESM(require("react"), 1);
20099
20125
 
20100
20126
  // src/components/ButtonMenu.tsx
@@ -20134,8 +20160,26 @@ function isSelectionButtonMenuProps(props) {
20134
20160
  return typeof props === "object" && "selectedItem" in props && "onChange" in props;
20135
20161
  }
20136
20162
 
20137
- // src/components/Filters/FilterDropdownMenu.tsx
20138
- var import_react106 = require("react");
20163
+ // src/components/Filters/utils.tsx
20164
+ function getActiveFilterCount(filter) {
20165
+ return safeKeys(filter).filter((key) => isDefined(filter[key])).length;
20166
+ }
20167
+ function updateFilter(currentFilter, key, value) {
20168
+ if (value === void 0) {
20169
+ return omitKey(key, currentFilter);
20170
+ } else {
20171
+ return { ...currentFilter, [key]: value };
20172
+ }
20173
+ }
20174
+ var filterTestIdPrefix = "filter";
20175
+
20176
+ // src/components/Layout/layoutTypes.ts
20177
+ function isGridTableProps(props) {
20178
+ return "rows" in props;
20179
+ }
20180
+
20181
+ // src/components/Layout/GridTableLayout/GridTableLayoutActions.tsx
20182
+ var import_react107 = require("react");
20139
20183
 
20140
20184
  // src/components/CountBadge.tsx
20141
20185
  var import_runtime74 = require("@homebound/truss/runtime");
@@ -20181,6 +20225,114 @@ function CountBadge(props) {
20181
20225
  }), children: count });
20182
20226
  }
20183
20227
 
20228
+ // src/components/Table/components/EditColumnsButton.tsx
20229
+ var import_react103 = require("react");
20230
+ var import_react_aria46 = require("react-aria");
20231
+ var import_react_stately17 = require("react-stately");
20232
+ var import_runtime75 = require("@homebound/truss/runtime");
20233
+ var import_jsx_runtime134 = require("react/jsx-runtime");
20234
+ function EditColumnsButton(props) {
20235
+ const {
20236
+ defaultOpen,
20237
+ disabled,
20238
+ columns,
20239
+ api
20240
+ } = props;
20241
+ const state = (0, import_react_stately17.useMenuTriggerState)({
20242
+ isOpen: defaultOpen
20243
+ });
20244
+ const buttonRef = (0, import_react103.useRef)(null);
20245
+ const {
20246
+ menuTriggerProps
20247
+ } = (0, import_react_aria46.useMenuTrigger)({
20248
+ isDisabled: !!disabled
20249
+ }, state, buttonRef);
20250
+ const tid = useTestIds(props, "columns");
20251
+ const {
20252
+ sm
20253
+ } = useBreakpoint();
20254
+ const options = (0, import_react103.useMemo)(() => columns.filter((column2) => column2.canHide).filter((column2) => {
20255
+ if (!column2.name || column2.name.length === 0 || !column2.id || column2.id.length === 0) {
20256
+ console.warn("Column is missing 'name' and/or 'id' property required by the Edit Columns button", column2);
20257
+ return false;
20258
+ }
20259
+ return true;
20260
+ }).map((column2) => ({
20261
+ label: column2.name,
20262
+ value: column2.id
20263
+ })), [columns]);
20264
+ const selectedValues = useComputed(() => api.getVisibleColumnIds(), [api]);
20265
+ const setSelectedValues = (0, import_react103.useCallback)((ids) => {
20266
+ api.resetColumnWidths();
20267
+ api.setVisibleColumns(columns.filter((column2) => column2.canHide ? ids.includes(column2.id) : true).map((c) => c.id));
20268
+ }, [columns, api]);
20269
+ const hasHiddenColumn = (0, import_react103.useMemo)(() => {
20270
+ const selectableOptionValues = options.map((option) => option.value);
20271
+ return selectableOptionValues.some((option) => !selectedValues.includes(option));
20272
+ }, [options, selectedValues]);
20273
+ return /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(OverlayTrigger, { ...props, trigger: sm ? {
20274
+ icon: hasHiddenColumn ? "columnsBadged" : "columns",
20275
+ variant: "outline"
20276
+ } : {
20277
+ icon: hasHiddenColumn ? "columnsBadged" : "columns",
20278
+ label: "",
20279
+ size: "md",
20280
+ variant: "secondaryBlack"
20281
+ }, menuTriggerProps, state, buttonRef, ...tid, children: /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)("div", { ...(0, import_runtime75.trussProps)({
20282
+ display: "df",
20283
+ flexDirection: "fdc",
20284
+ backgroundColor: ["bgColor_var", {
20285
+ "--backgroundColor": "var(--b-surface)"
20286
+ }],
20287
+ maxWidth: "maxw_326px",
20288
+ maxHeight: "maxh_512px",
20289
+ boxShadow: "h_bshHover"
20290
+ }), children: [
20291
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "dg gtc_1fr_auto gap2 pt2 pb2 pr2 pl2 fg1 mh0 oya", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(import_react103.Fragment, { children: [
20292
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { className: "fw4 fz_14px lh_20px wsnw oh to_ellipsis pr1", children: option.label }),
20293
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Switch, { compact: true, selected: selectedValues.includes(option.value), onChange: (value) => setSelectedValues(value ? [...selectedValues, option.value] : selectedValues.filter((v) => v !== option.value)), labelStyle: "hidden", label: option.label, ...tid[`option${option.value}`] })
20294
+ ] }, option.value)) }),
20295
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)("div", { ...(0, import_runtime75.trussProps)({
20296
+ display: "df",
20297
+ justifyContent: "jcc",
20298
+ paddingTop: "pt2",
20299
+ paddingBottom: "pb2",
20300
+ paddingRight: "pr2",
20301
+ paddingLeft: "pl2",
20302
+ borderTopStyle: "bts_solid",
20303
+ borderTopWidth: "btw_1px",
20304
+ borderColor: ["bc_var", {
20305
+ "--borderColor": "var(--b-surface-separator)"
20306
+ }]
20307
+ }), children: /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Button, { variant: "tertiary", label: "Reset Column Widths", onClick: () => api.resetColumnWidths() }) })
20308
+ ] }) });
20309
+ }
20310
+
20311
+ // src/components/Table/components/ViewToggleButton.tsx
20312
+ var import_jsx_runtime135 = require("react/jsx-runtime");
20313
+ function ViewToggleButton({ view, onChange, defaultOpen }) {
20314
+ const { sm } = useBreakpoint();
20315
+ const tid = useTestIds({}, "viewToggleButton");
20316
+ const menuItems = [
20317
+ { label: "List", icon: "projects", onClick: () => onChange("list") },
20318
+ { label: "Card", icon: "tile", onClick: () => onChange("card") }
20319
+ ];
20320
+ const icon = view === "list" ? "projects" : "tile";
20321
+ return /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
20322
+ ButtonMenu,
20323
+ {
20324
+ trigger: sm ? { icon, variant: "outline" } : { icon, label: "", size: "md", variant: "secondaryBlack" },
20325
+ items: menuItems,
20326
+ defaultOpen,
20327
+ ...tid
20328
+ }
20329
+ );
20330
+ }
20331
+
20332
+ // src/components/Layout/GridTableLayout/GridTableLayoutActions.tsx
20333
+ var import_use_debounce7 = require("use-debounce");
20334
+ var import_use_query_params3 = require("use-query-params");
20335
+
20184
20336
  // src/components/Filters/BaseFilter.ts
20185
20337
  var BaseFilter = class {
20186
20338
  constructor(key, props) {
@@ -20199,7 +20351,7 @@ var BaseFilter = class {
20199
20351
  };
20200
20352
 
20201
20353
  // src/components/Filters/DateFilter.tsx
20202
- var import_jsx_runtime134 = require("react/jsx-runtime");
20354
+ var import_jsx_runtime136 = require("react/jsx-runtime");
20203
20355
  function dateFilter(props) {
20204
20356
  return (key) => new DateFilter(key, props);
20205
20357
  }
@@ -20221,10 +20373,10 @@ var DateFilter = class extends BaseFilter {
20221
20373
  }
20222
20374
  render(value, setValue, tid, inModal, vertical) {
20223
20375
  const { label, operations, getOperationValue, getOperationLabel, defaultValue } = this.props;
20224
- return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(import_jsx_runtime134.Fragment, { children: [
20225
- vertical && /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(Label, { label }),
20226
- /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(CompoundField, { children: [
20227
- /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
20376
+ return /* @__PURE__ */ (0, import_jsx_runtime136.jsxs)(import_jsx_runtime136.Fragment, { children: [
20377
+ vertical && /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(Label, { label }),
20378
+ /* @__PURE__ */ (0, import_jsx_runtime136.jsxs)(CompoundField, { children: [
20379
+ /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(
20228
20380
  SelectField,
20229
20381
  {
20230
20382
  sizeToContent: true,
@@ -20246,7 +20398,7 @@ var DateFilter = class extends BaseFilter {
20246
20398
  ...tid[`${defaultTestId(this.label)}_dateOperation`]
20247
20399
  }
20248
20400
  ),
20249
- /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
20401
+ /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(
20250
20402
  DateField,
20251
20403
  {
20252
20404
  labelStyle: "inline",
@@ -20270,7 +20422,7 @@ function isDateFilterValue(value) {
20270
20422
  }
20271
20423
 
20272
20424
  // src/components/Filters/DateRangeFilter.tsx
20273
- var import_jsx_runtime135 = require("react/jsx-runtime");
20425
+ var import_jsx_runtime137 = require("react/jsx-runtime");
20274
20426
  function dateRangeFilter(props) {
20275
20427
  return (key) => new DateRangeFilter(key, props);
20276
20428
  }
@@ -20292,9 +20444,9 @@ var DateRangeFilter = class extends BaseFilter {
20292
20444
  }
20293
20445
  render(value, setValue, tid, inModal, vertical) {
20294
20446
  const { label, placeholderText, disabledDays, testFieldLabel, defaultValue } = this.props;
20295
- return /* @__PURE__ */ (0, import_jsx_runtime135.jsxs)(import_jsx_runtime135.Fragment, { children: [
20296
- vertical && /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(Label, { label }),
20297
- /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
20447
+ return /* @__PURE__ */ (0, import_jsx_runtime137.jsxs)(import_jsx_runtime137.Fragment, { children: [
20448
+ vertical && /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(Label, { label }),
20449
+ /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
20298
20450
  DateRangeField,
20299
20451
  {
20300
20452
  labelStyle: "inline",
@@ -20350,7 +20502,7 @@ function resolveNestedOptions(optionsOrLoad) {
20350
20502
  }
20351
20503
 
20352
20504
  // src/components/Filters/MultiFilter.tsx
20353
- var import_jsx_runtime136 = require("react/jsx-runtime");
20505
+ var import_jsx_runtime138 = require("react/jsx-runtime");
20354
20506
  function multiFilter(props) {
20355
20507
  return (key) => new MultiFilter(key, props);
20356
20508
  }
@@ -20364,7 +20516,7 @@ var MultiFilter = class extends BaseFilter {
20364
20516
  const { disabledOptions } = this.props;
20365
20517
  const disabledOptionsWithReasons = Object.fromEntries(disabledOptions?.map(disabledOptionToKeyedTuple) ?? []);
20366
20518
  const disabledKeys = Object.keys(disabledOptionsWithReasons);
20367
- return /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(
20519
+ return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
20368
20520
  ToggleChipGroup,
20369
20521
  {
20370
20522
  label: this.label,
@@ -20388,7 +20540,7 @@ var MultiFilter = class extends BaseFilter {
20388
20540
  );
20389
20541
  }
20390
20542
  const { defaultValue, nothingSelectedText, ...props } = this.props;
20391
- return /* @__PURE__ */ (0, import_jsx_runtime136.jsx)(
20543
+ return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
20392
20544
  MultiSelectField,
20393
20545
  {
20394
20546
  ...props,
@@ -20407,7 +20559,7 @@ var MultiFilter = class extends BaseFilter {
20407
20559
  };
20408
20560
 
20409
20561
  // src/components/Filters/NumberRangeFilter.tsx
20410
- var import_jsx_runtime137 = require("react/jsx-runtime");
20562
+ var import_jsx_runtime139 = require("react/jsx-runtime");
20411
20563
  function numberRangeFilter(props) {
20412
20564
  return (key) => new NumberRangeFilter(key, props);
20413
20565
  }
@@ -20424,10 +20576,10 @@ var NumberRangeFilter = class extends BaseFilter {
20424
20576
  } = this.props;
20425
20577
  const min = value?.min ?? void 0;
20426
20578
  const max = value?.max ?? void 0;
20427
- return /* @__PURE__ */ (0, import_jsx_runtime137.jsxs)(import_jsx_runtime137.Fragment, { children: [
20428
- vertical && /* @__PURE__ */ (0, import_jsx_runtime137.jsxs)("div", { ...tid, children: [
20429
- /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(Label, { label }),
20430
- /* @__PURE__ */ (0, import_jsx_runtime137.jsx)("div", { className: "pb1", children: /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(NumberField, { labelStyle: "inline", clearable: true, label: "Min", value: min, type: numberFieldType, numberFormatOptions, onChange: (minVal) => {
20579
+ return /* @__PURE__ */ (0, import_jsx_runtime139.jsxs)(import_jsx_runtime139.Fragment, { children: [
20580
+ vertical && /* @__PURE__ */ (0, import_jsx_runtime139.jsxs)("div", { ...tid, children: [
20581
+ /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(Label, { label }),
20582
+ /* @__PURE__ */ (0, import_jsx_runtime139.jsx)("div", { className: "pb1", children: /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(NumberField, { labelStyle: "inline", clearable: true, label: "Min", value: min, type: numberFieldType, numberFormatOptions, onChange: (minVal) => {
20431
20583
  const maxValue = max ? {
20432
20584
  max
20433
20585
  } : {};
@@ -20436,7 +20588,7 @@ var NumberRangeFilter = class extends BaseFilter {
20436
20588
  ...maxValue
20437
20589
  } : void 0);
20438
20590
  }, ...tid[`${defaultTestId(label)}_min_vertical`] }) }),
20439
- /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(NumberField, { labelStyle: "inline", clearable: true, label: "Max", value: max, type: numberFieldType, numberFormatOptions, onChange: (maxVal) => {
20591
+ /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(NumberField, { labelStyle: "inline", clearable: true, label: "Max", value: max, type: numberFieldType, numberFormatOptions, onChange: (maxVal) => {
20440
20592
  const minValue = min ? {
20441
20593
  min
20442
20594
  } : {};
@@ -20446,8 +20598,8 @@ var NumberRangeFilter = class extends BaseFilter {
20446
20598
  } : void 0);
20447
20599
  }, ...tid[`${defaultTestId(label)}_max_vertical`] })
20448
20600
  ] }),
20449
- !vertical && /* @__PURE__ */ (0, import_jsx_runtime137.jsxs)(CompoundField, { ...tid, children: [
20450
- /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
20601
+ !vertical && /* @__PURE__ */ (0, import_jsx_runtime139.jsxs)(CompoundField, { ...tid, children: [
20602
+ /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(
20451
20603
  NumberField,
20452
20604
  {
20453
20605
  sizeToContent: !inModal,
@@ -20469,7 +20621,7 @@ var NumberRangeFilter = class extends BaseFilter {
20469
20621
  ...tid[`${defaultTestId(label)}_min`]
20470
20622
  }
20471
20623
  ),
20472
- /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(NumberField, { sizeToContent: !inModal, labelStyle: "inline", clearable: true, label: !inModal ? `${label} Max` : "Max", value: max, type: numberFieldType, numberFormatOptions, onChange: (maxVal) => {
20624
+ /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(NumberField, { sizeToContent: !inModal, labelStyle: "inline", clearable: true, label: !inModal ? `${label} Max` : "Max", value: max, type: numberFieldType, numberFormatOptions, onChange: (maxVal) => {
20473
20625
  const minValue = min ? {
20474
20626
  min
20475
20627
  } : {};
@@ -20484,7 +20636,7 @@ var NumberRangeFilter = class extends BaseFilter {
20484
20636
  };
20485
20637
 
20486
20638
  // src/components/Filters/SingleFilter.tsx
20487
- var import_jsx_runtime138 = require("react/jsx-runtime");
20639
+ var import_jsx_runtime140 = require("react/jsx-runtime");
20488
20640
  function singleFilter(props) {
20489
20641
  return (key) => new SingleFilter(key, props);
20490
20642
  }
@@ -20505,7 +20657,7 @@ var SingleFilter = class extends BaseFilter {
20505
20657
  ...props
20506
20658
  } = this.props;
20507
20659
  const options = Array.isArray(maybeOptions) ? [allOption, ...maybeOptions] : { ...maybeOptions, current: maybeOptions.current };
20508
- return /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
20660
+ return /* @__PURE__ */ (0, import_jsx_runtime140.jsx)(
20509
20661
  SelectField,
20510
20662
  {
20511
20663
  ...props,
@@ -20525,7 +20677,7 @@ var SingleFilter = class extends BaseFilter {
20525
20677
  };
20526
20678
 
20527
20679
  // src/components/Filters/TreeFilter.tsx
20528
- var import_jsx_runtime139 = require("react/jsx-runtime");
20680
+ var import_jsx_runtime141 = require("react/jsx-runtime");
20529
20681
  function treeFilter(props) {
20530
20682
  return (key) => new TreeFilter(key, props);
20531
20683
  }
@@ -20536,7 +20688,7 @@ var TreeFilter = class extends BaseFilter {
20536
20688
  }
20537
20689
  render(value, setValue, tid, inModal, vertical) {
20538
20690
  const { defaultValue, nothingSelectedText, filterBy = "root", ...props } = this.props;
20539
- return /* @__PURE__ */ (0, import_jsx_runtime139.jsx)(
20691
+ return /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(
20540
20692
  TreeSelectField,
20541
20693
  {
20542
20694
  ...props,
@@ -20556,7 +20708,7 @@ var TreeFilter = class extends BaseFilter {
20556
20708
  };
20557
20709
 
20558
20710
  // src/components/Filters/BooleanFilter.tsx
20559
- var import_jsx_runtime140 = require("react/jsx-runtime");
20711
+ var import_jsx_runtime142 = require("react/jsx-runtime");
20560
20712
  function booleanFilter(props) {
20561
20713
  return (key) => new BooleanFilter(key, props);
20562
20714
  }
@@ -20568,7 +20720,7 @@ var BooleanFilter = class extends BaseFilter {
20568
20720
  }
20569
20721
  render(value, setValue, tid, inModal, vertical) {
20570
20722
  const { options = defaultBooleanOptions, label, defaultValue, ...props } = this.props;
20571
- return /* @__PURE__ */ (0, import_jsx_runtime140.jsx)(
20723
+ return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(
20572
20724
  SelectField,
20573
20725
  {
20574
20726
  ...props,
@@ -20595,7 +20747,7 @@ var defaultBooleanOptions = [
20595
20747
  ];
20596
20748
 
20597
20749
  // src/components/Filters/CheckboxFilter.tsx
20598
- var import_jsx_runtime141 = require("react/jsx-runtime");
20750
+ var import_jsx_runtime143 = require("react/jsx-runtime");
20599
20751
  function checkboxFilter(props) {
20600
20752
  return (key) => new CheckboxFilter(key, {
20601
20753
  // If the user has set the offValue, that should be the default b/c we're only a two-state
@@ -20610,7 +20762,7 @@ var CheckboxFilter = class extends BaseFilter {
20610
20762
  }
20611
20763
  render(value, setValue, tid, inModal, vertical) {
20612
20764
  const { defaultValue, onValue = true, offValue = void 0, ...props } = this.props;
20613
- return /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(
20765
+ return /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(
20614
20766
  Checkbox,
20615
20767
  {
20616
20768
  ...props,
@@ -20629,29 +20781,29 @@ var CheckboxFilter = class extends BaseFilter {
20629
20781
  };
20630
20782
 
20631
20783
  // src/components/Filters/FilterModal.tsx
20632
- var import_react104 = require("react");
20784
+ var import_react105 = require("react");
20633
20785
 
20634
20786
  // src/components/Modal/OpenModal.tsx
20635
- var import_react103 = require("react");
20636
- var import_jsx_runtime142 = require("react/jsx-runtime");
20787
+ var import_react104 = require("react");
20788
+ var import_jsx_runtime144 = require("react/jsx-runtime");
20637
20789
  function OpenModal(props) {
20638
20790
  const { openModal } = useModal();
20639
20791
  const { size, children, keepOpen } = props;
20640
- (0, import_react103.useEffect)(() => {
20792
+ (0, import_react104.useEffect)(() => {
20641
20793
  if (!keepOpen) {
20642
20794
  openModal({ size, content: children });
20643
20795
  }
20644
20796
  }, [keepOpen, openModal, size, children]);
20645
20797
  if (keepOpen) {
20646
- return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)(Modal, { size, content: children });
20798
+ return /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(Modal, { size, content: children });
20647
20799
  } else {
20648
- return /* @__PURE__ */ (0, import_jsx_runtime142.jsx)("div", { children: "dummy content" });
20800
+ return /* @__PURE__ */ (0, import_jsx_runtime144.jsx)("div", { children: "dummy content" });
20649
20801
  }
20650
20802
  }
20651
20803
 
20652
20804
  // src/components/Filters/FilterModal.tsx
20653
- var import_runtime75 = require("@homebound/truss/runtime");
20654
- var import_jsx_runtime143 = require("react/jsx-runtime");
20805
+ var import_runtime76 = require("@homebound/truss/runtime");
20806
+ var import_jsx_runtime145 = require("react/jsx-runtime");
20655
20807
  function FilterModal(props) {
20656
20808
  const {
20657
20809
  filter,
@@ -20662,20 +20814,20 @@ function FilterModal(props) {
20662
20814
  const {
20663
20815
  closeModal
20664
20816
  } = useModal();
20665
- const [modalFilter, setModalFilter] = (0, import_react104.useState)(filter);
20666
- return /* @__PURE__ */ (0, import_jsx_runtime143.jsxs)(import_jsx_runtime143.Fragment, { children: [
20667
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(ModalHeader, { children: "More Filters" }),
20668
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(ModalBody, { children: /* @__PURE__ */ (0, import_jsx_runtime143.jsx)("div", { className: "df fdc", children: safeEntries(filters).map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(ModalFilterItem, { label: f.hideLabelInModal ? void 0 : f.label, children: f.render(modalFilter[key], (value) => setModalFilter(updateFilter(modalFilter, key, value)), testId, true, false) }, key)) }) }),
20669
- /* @__PURE__ */ (0, import_jsx_runtime143.jsxs)(ModalFooter, { xss: {
20817
+ const [modalFilter, setModalFilter] = (0, import_react105.useState)(filter);
20818
+ return /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(import_jsx_runtime145.Fragment, { children: [
20819
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(ModalHeader, { children: "More Filters" }),
20820
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(ModalBody, { children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("div", { className: "df fdc", children: safeEntries(filters).map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(ModalFilterItem, { label: f.hideLabelInModal ? void 0 : f.label, children: f.render(modalFilter[key], (value) => setModalFilter(updateFilter(modalFilter, key, value)), testId, true, false) }, key)) }) }),
20821
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(ModalFooter, { xss: {
20670
20822
  justifyContent: "jcsb"
20671
20823
  }, children: [
20672
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(Button, { label: "Clear", variant: "tertiary", disabled: safeKeys(filters).filter((fk) => modalFilter[fk] !== void 0).length === 0, onClick: () => (
20824
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Button, { label: "Clear", variant: "tertiary", disabled: safeKeys(filters).filter((fk) => modalFilter[fk] !== void 0).length === 0, onClick: () => (
20673
20825
  // Only remove the filters keys that exist in the modal.
20674
20826
  setModalFilter(safeKeys(filters).reduce((acc, fk) => omitKey(fk, acc), modalFilter))
20675
20827
  ), ...testId.modalClear }),
20676
- /* @__PURE__ */ (0, import_jsx_runtime143.jsxs)("div", { className: "df gap1", children: [
20677
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(Button, { label: "Cancel", variant: "quaternary", onClick: closeModal, ...testId.modalClose }),
20678
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(Button, { label: "Apply", onClick: () => {
20828
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { className: "df gap1", children: [
20829
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Button, { label: "Cancel", variant: "quaternary", onClick: closeModal, ...testId.modalClose }),
20830
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Button, { label: "Apply", onClick: () => {
20679
20831
  onApply(modalFilter);
20680
20832
  closeModal();
20681
20833
  }, ...testId.modalApply })
@@ -20687,7 +20839,7 @@ function ModalFilterItem({
20687
20839
  label,
20688
20840
  children
20689
20841
  }) {
20690
- return /* @__PURE__ */ (0, import_jsx_runtime143.jsxs)("div", { ...(0, import_runtime75.trussProps)({
20842
+ return /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)("div", { ...(0, import_runtime76.trussProps)({
20691
20843
  marginBottom: "mb4",
20692
20844
  ...!label ? {
20693
20845
  borderTopStyle: "bts_solid",
@@ -20695,8 +20847,8 @@ function ModalFilterItem({
20695
20847
  borderColor: "bcGray200"
20696
20848
  } : {}
20697
20849
  }), children: [
20698
- label && /* @__PURE__ */ (0, import_jsx_runtime143.jsx)("h2", { className: "fw4 fz_16px lh_24px mb2", children: label }),
20699
- /* @__PURE__ */ (0, import_jsx_runtime143.jsx)("div", { ...(0, import_runtime75.trussProps)({
20850
+ label && /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("h2", { className: "fw4 fz_16px lh_24px mb2", children: label }),
20851
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)("div", { ...(0, import_runtime76.trussProps)({
20700
20852
  ...!label ? {
20701
20853
  paddingTop: "pt3"
20702
20854
  } : {}
@@ -20705,9 +20857,9 @@ function ModalFilterItem({
20705
20857
  }
20706
20858
 
20707
20859
  // src/components/Filters/Filters.tsx
20708
- var import_react105 = require("react");
20709
- var import_runtime76 = require("@homebound/truss/runtime");
20710
- var import_jsx_runtime144 = require("react/jsx-runtime");
20860
+ var import_react106 = require("react");
20861
+ var import_runtime77 = require("@homebound/truss/runtime");
20862
+ var import_jsx_runtime146 = require("react/jsx-runtime");
20711
20863
  function Filters(props) {
20712
20864
  const {
20713
20865
  filter,
@@ -20721,7 +20873,7 @@ function Filters(props) {
20721
20873
  const {
20722
20874
  openModal
20723
20875
  } = useModal();
20724
- const [pageFilters, modalFilters] = (0, import_react105.useMemo)(() => {
20876
+ const [pageFilters, modalFilters] = (0, import_react106.useMemo)(() => {
20725
20877
  const impls = safeEntries(filterDefs).map(([key, fn]) => [key, fn(key)]);
20726
20878
  if (!vertical && impls.length > numberOfInlineFilters) {
20727
20879
  return [Object.fromEntries(impls.slice(0, numberOfInlineFilters - 1)), Object.fromEntries(impls.slice(numberOfInlineFilters - 1))];
@@ -20729,8 +20881,8 @@ function Filters(props) {
20729
20881
  return [Object.fromEntries(impls), {}];
20730
20882
  }, [numberOfInlineFilters, vertical, filterDefs]);
20731
20883
  const numModalFilters = safeKeys(modalFilters).filter((fk) => filter[fk] !== void 0).length;
20732
- const maybeGroupByField = groupBy ? /* @__PURE__ */ (0, import_jsx_runtime144.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(SelectField, { label: "Group by", labelStyle: !vertical ? "inline" : "above", sizeToContent: !vertical, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }) }) : null;
20733
- return /* @__PURE__ */ (0, import_jsx_runtime144.jsxs)("div", { ...(0, import_runtime76.trussProps)({
20884
+ const maybeGroupByField = groupBy ? /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(SelectField, { label: "Group by", labelStyle: !vertical ? "inline" : "above", sizeToContent: !vertical, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }) }) : null;
20885
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { ...(0, import_runtime77.trussProps)({
20734
20886
  ...vertical ? {
20735
20887
  display: "df",
20736
20888
  flexDirection: "fdc",
@@ -20742,18 +20894,18 @@ function Filters(props) {
20742
20894
  }
20743
20895
  }), ...testId, children: [
20744
20896
  maybeGroupByField,
20745
- safeEntries(pageFilters).map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime144.jsx)("div", { children: f.render(filter[key], (value) => onChange(updateFilter(filter, key, value)), testId, false, vertical) }, key)),
20746
- Object.keys(modalFilters).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(Button, { label: "More Filters", endAdornment: /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(CountBadge, { count: numModalFilters, hideIfZero: true }), variant: "secondary", onClick: () => openModal({
20897
+ safeEntries(pageFilters).map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { children: f.render(filter[key], (value) => onChange(updateFilter(filter, key, value)), testId, false, vertical) }, key)),
20898
+ Object.keys(modalFilters).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Button, { label: "More Filters", endAdornment: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(CountBadge, { count: numModalFilters, hideIfZero: true }), variant: "secondary", onClick: () => openModal({
20747
20899
  // Spreading `props` to pass along `data-testid`
20748
- content: /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(FilterModal, { ...props, filter, onApply: onChange, filters: modalFilters })
20900
+ content: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(FilterModal, { ...props, filter, onApply: onChange, filters: modalFilters })
20749
20901
  }), ...testId.moreFiltersBtn }),
20750
- Object.keys(filter).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime144.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime144.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: () => onChange({}), ...testId.clearBtn }) })
20902
+ Object.keys(filter).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: () => onChange({}), ...testId.clearBtn }) })
20751
20903
  ] });
20752
20904
  }
20753
- var _Filters = (0, import_react105.memo)(Filters);
20905
+ var _Filters = (0, import_react106.memo)(Filters);
20754
20906
 
20755
20907
  // src/components/Filters/ToggleFilter.tsx
20756
- var import_jsx_runtime145 = require("react/jsx-runtime");
20908
+ var import_jsx_runtime147 = require("react/jsx-runtime");
20757
20909
  function toggleFilter(props) {
20758
20910
  return (key) => new ToggleFilter(key, {
20759
20911
  // If the user has set the offValue, that should be the default b/c we're only a two-state
@@ -20768,7 +20920,7 @@ var ToggleFilter = class extends BaseFilter {
20768
20920
  }
20769
20921
  render(value, setValue, tid, inModal, vertical) {
20770
20922
  const { defaultValue, onValue = true, offValue = void 0, ...props } = this.props;
20771
- return /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
20923
+ return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(
20772
20924
  Switch,
20773
20925
  {
20774
20926
  ...props,
@@ -20787,126 +20939,83 @@ var ToggleFilter = class extends BaseFilter {
20787
20939
  }
20788
20940
  };
20789
20941
 
20790
- // src/components/Filters/utils.tsx
20791
- function getActiveFilterCount(filter) {
20792
- return safeKeys(filter).filter((key) => isDefined(filter[key])).length;
20793
- }
20794
- function updateFilter(currentFilter, key, value) {
20795
- if (value === void 0) {
20796
- return omitKey(key, currentFilter);
20797
- } else {
20798
- return { ...currentFilter, [key]: value };
20799
- }
20942
+ // src/components/Layout/GridTableLayout/FilterPanel.tsx
20943
+ var import_runtime78 = require("@homebound/truss/runtime");
20944
+ var import_jsx_runtime148 = require("react/jsx-runtime");
20945
+ function FilterPanel(props) {
20946
+ return props.isOpen ? /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(FilterPanelOpen, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(FilterPanelClosed, { ...props });
20800
20947
  }
20801
- var filterTestIdPrefix = "filter";
20802
-
20803
- // src/components/Filters/FilterDropdownMenu.tsx
20804
- var import_use_debounce7 = require("use-debounce");
20805
- var import_use_query_params3 = require("use-query-params");
20806
- var import_runtime77 = require("@homebound/truss/runtime");
20807
- var import_jsx_runtime146 = require("react/jsx-runtime");
20808
- function FilterDropdownMenu(props) {
20809
- const {
20810
- filter,
20811
- onChange,
20812
- filterDefs,
20813
- groupBy,
20814
- searchProps
20815
- } = props;
20816
- const testId = useTestIds(props, filterTestIdPrefix);
20817
- const {
20818
- sm
20819
- } = useBreakpoint();
20820
- const [isOpen, setIsOpen] = (0, import_react106.useState)(false);
20821
- const [searchIsOpen, setSearchIsOpen] = (0, import_react106.useState)(false);
20822
- const [{
20823
- search: initialValue
20824
- }, setQueryParams] = (0, import_use_query_params3.useQueryParams)({
20825
- search: import_use_query_params3.StringParam
20826
- });
20827
- const [searchValue, setSearchValue] = (0, import_react106.useState)(initialValue || "");
20828
- const [debouncedSearch] = (0, import_use_debounce7.useDebounce)(searchValue, 300);
20829
- (0, import_react106.useEffect)(() => {
20830
- if (searchProps) {
20831
- searchProps.onSearch(debouncedSearch);
20832
- setQueryParams({
20833
- search: debouncedSearch || void 0
20834
- }, "replaceIn");
20835
- }
20836
- }, [debouncedSearch, searchProps, setQueryParams]);
20837
- const hasSearch = !!searchProps;
20838
- const hasFilters = !!filterDefs && Object.keys(filterDefs ?? {}).length > 0;
20839
- const activeFilterCount = (0, import_react106.useMemo)(() => filter ? getActiveFilterCount(filter) : 0, [filter]);
20840
- const filterImpls = (0, import_react106.useMemo)(() => filterDefs ? buildFilterImpls(filterDefs) : {}, [filterDefs]);
20841
- const renderFilters = () => {
20842
- if (!filter || !onChange) return null;
20843
- const entries = safeEntries(filterImpls);
20844
- const nonCheckbox = entries.filter(([_, f]) => !f.hideLabelInModal);
20845
- const checkbox = entries.filter(([_, f]) => f.hideLabelInModal);
20846
- return [...nonCheckbox, ...checkbox].map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { children: f.render(filter[key], (value) => onChange(updateFilter(filter, key, value)), testId, false, false) }, key));
20847
- };
20848
- const searchTextField = /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(TextField, { label: "Search", labelStyle: "hidden", value: searchValue, onChange: (v) => setSearchValue(v ?? ""), placeholder: "Search", clearable: true, startAdornment: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Icon, { icon: "search", color: "rgba(100, 100, 100, 1)" /* Gray700 */ }) });
20849
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_jsx_runtime146.Fragment, { children: [
20850
- hasSearch && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { ...(0, import_runtime77.trussProps)({
20851
- width: "w_244px",
20852
- ...sm ? {
20853
- position: "absolute",
20854
- overflow: "oh",
20855
- clip: "cli_inset_50",
20856
- clipPath: "clp_none",
20857
- border: "bd_0",
20858
- height: "h_1px",
20859
- margin: "m_neg1px",
20860
- width: "w_1px",
20861
- padding: "p_0",
20862
- whiteSpace: "wsnw",
20863
- opacity: "o0"
20864
- } : {}
20865
- }), children: searchTextField }),
20866
- sm && hasSearch && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(IconButton, { variant: "outline", icon: searchValue ? "searchBadged" : "search", label: "Search", onClick: () => setSearchIsOpen(!searchIsOpen), active: searchIsOpen, ...testId.searchButton }),
20867
- sm && hasFilters && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(IconButton, { variant: "outline", icon: activeFilterCount > 0 ? "filterBadged" : "filter", label: "Filter", active: isOpen, onClick: () => setIsOpen(!isOpen), ...testId.button }),
20868
- !sm && hasFilters && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Button, { label: "Filter", icon: "filter", size: "md", endAdornment: /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "df aic gap1", children: [
20869
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(CountBadge, { count: activeFilterCount }),
20870
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Icon, { icon: isOpen ? "chevronUp" : "chevronDown" })
20871
- ] }), variant: "secondaryBlack", onClick: () => setIsOpen(!isOpen), active: isOpen, ...testId.button }),
20872
- searchIsOpen && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { ...(0, import_runtime77.trussProps)({
20873
- width: "w100",
20874
- ...!sm ? {
20875
- position: "absolute",
20876
- overflow: "oh",
20877
- clip: "cli_inset_50",
20878
- clipPath: "clp_none",
20879
- border: "bd_0",
20880
- height: "h_1px",
20881
- margin: "m_neg1px",
20882
- width: "w_1px",
20883
- padding: "p_0",
20884
- whiteSpace: "wsnw",
20885
- opacity: "o0"
20948
+ function FilterPanelOpen({
20949
+ groupBy,
20950
+ filterImpls,
20951
+ filter,
20952
+ setFilter,
20953
+ onClear
20954
+ }) {
20955
+ const tid = useTestIds({}, filterTestIdPrefix);
20956
+ const inDocumentScrollLayout = useDocumentScrollLayout();
20957
+ const activeFilterCount = getActiveFilterCount(filter ?? {});
20958
+ const filterControls = filter && setFilter ? buildFilterControls(filterImpls, filter, setFilter, tid) : null;
20959
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { ...(0, import_runtime78.trussProps)({
20960
+ ...{
20961
+ display: "df",
20962
+ alignItems: "aic",
20963
+ gap: "gap1",
20964
+ scrollbarWidth: "sbwn"
20965
+ },
20966
+ ...{
20967
+ overflowX: "sm_oxa",
20968
+ minWidth: "sm_mw0"
20969
+ },
20970
+ ...{
20971
+ flexWrap: "mdandup_fww"
20972
+ },
20973
+ ...{
20974
+ ...inDocumentScrollLayout ? {
20975
+ paddingLeft: "pl3",
20976
+ paddingRight: "pr3"
20886
20977
  } : {}
20887
- }), children: searchTextField }),
20888
- hasFilters && isOpen && /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "df aic fww gap1 w100", children: [
20889
- groupBy && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(SelectField, { label: "Group by", labelStyle: "inline", sizeToContent: true, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }),
20890
- renderFilters(),
20891
- activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: () => onChange?.({}), ...testId.clearBtn })
20892
- ] }),
20893
- hasFilters && !isOpen && filter && onChange && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(FilterChips, { filter, filterImpls, onChange, onClear: () => onChange({}), testId })
20978
+ }
20979
+ }), children: [
20980
+ groupBy && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(SelectField, { label: "Group by", labelStyle: "inline", sizeToContent: true, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }),
20981
+ filterControls,
20982
+ activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: onClear, ...tid.clearBtn })
20894
20983
  ] });
20895
20984
  }
20896
- function FilterChips({
20897
- filter,
20985
+ function FilterPanelClosed({
20898
20986
  filterImpls,
20899
- onChange,
20900
- onClear,
20901
- testId
20987
+ filter,
20988
+ setFilter,
20989
+ onClear
20902
20990
  }) {
20903
- const chips = safeEntries(filterImpls).flatMap(([key, f]) => chipsForFilterKey(key, f, filter, onChange, testId));
20991
+ const tid = useTestIds({}, filterTestIdPrefix);
20992
+ const inDocumentScrollLayout = useDocumentScrollLayout();
20993
+ if (!filter || !setFilter) return null;
20994
+ const chips = safeEntries(filterImpls).flatMap(([key, f]) => chipsForFilterKey(key, f, filter, setFilter, tid));
20904
20995
  if (chips.length === 0) return null;
20905
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "df gap1 fww aic order_1", children: [
20996
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { ...(0, import_runtime78.trussProps)({
20997
+ display: "df",
20998
+ gap: "gap1",
20999
+ alignItems: "aic",
21000
+ minWidth: "mw0",
21001
+ flexWrap: "fww",
21002
+ ...inDocumentScrollLayout ? {
21003
+ paddingLeft: "pl3"
21004
+ } : {}
21005
+ }), children: [
20906
21006
  chips,
20907
- /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: onClear, ...testId.clearBtn })
21007
+ /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(Button, { label: "Clear", variant: "tertiary", onClick: onClear, ...tid.clearBtn })
20908
21008
  ] });
20909
21009
  }
21010
+ function buildFilterControls(filterImpls, filter, setFilter, testId) {
21011
+ const entries = safeEntries(filterImpls);
21012
+ const nonCheckbox = entries.filter(([_, f]) => !f.hideLabelInModal);
21013
+ const checkbox = entries.filter(([_, f]) => f.hideLabelInModal);
21014
+ return [...nonCheckbox, ...checkbox].map(([key, f]) => /* @__PURE__ */ (0, import_jsx_runtime148.jsx)("div", { children: f.render(filter[key], (value) => setFilter(updateFilter(filter, key, value)), testId, false, false) }, key));
21015
+ }
21016
+ function buildFilterImpls(filterDefs) {
21017
+ return Object.fromEntries(safeEntries(filterDefs).map(([key, fn]) => [key, fn(key)]));
21018
+ }
20910
21019
  function chipsForFilterKey(key, f, filter, onChange, testId) {
20911
21020
  const value = filter[key];
20912
21021
  if (!isDefined(value)) return [];
@@ -20916,143 +21025,90 @@ function chipsForFilterKey(key, f, filter, onChange, testId) {
20916
21025
  if (!isDefined(label2)) return [];
20917
21026
  const chipKey = `${String(key)}_${item}`;
20918
21027
  const newArray = value.filter((v) => v !== item);
20919
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(ToggleChip, { text: label2, onClick: () => onChange(updateFilter(filter, key, newArray.length > 0 ? newArray : void 0)), ...testId[`chip_${chipKey}`] }, chipKey);
21028
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ToggleChip, { text: label2, onClick: () => onChange(updateFilter(filter, key, newArray.length > 0 ? newArray : void 0)), ...testId[`chip_${chipKey}`] }, chipKey);
20920
21029
  });
20921
21030
  }
20922
21031
  const label = f.formatSelectedFilterLabel(value);
20923
21032
  if (!isDefined(label)) return [];
20924
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(ToggleChip, { text: label, onClick: () => onChange(updateFilter(filter, key, void 0)), ...testId[`chip_${String(key)}`] }, String(key));
20925
- }
20926
- function buildFilterImpls(filterDefs) {
20927
- return Object.fromEntries(safeEntries(filterDefs).map(([key, fn]) => [key, fn(key)]));
21033
+ return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(ToggleChip, { text: label, onClick: () => onChange(updateFilter(filter, key, void 0)), ...testId[`chip_${String(key)}`] }, String(key));
20928
21034
  }
20929
- var _FilterDropdownMenu = (0, import_react106.memo)(FilterDropdownMenu);
20930
21035
 
20931
- // src/components/Table/components/EditColumnsButton.tsx
20932
- var import_react107 = require("react");
20933
- var import_react_aria46 = require("react-aria");
20934
- var import_react_stately17 = require("react-stately");
20935
- var import_runtime78 = require("@homebound/truss/runtime");
20936
- var import_jsx_runtime147 = require("react/jsx-runtime");
20937
- function EditColumnsButton(props) {
21036
+ // src/components/Layout/GridTableLayout/GridTableLayoutActions.tsx
21037
+ var import_runtime79 = require("@homebound/truss/runtime");
21038
+ var import_jsx_runtime149 = require("react/jsx-runtime");
21039
+ function GridTableLayoutActionsComponent(props) {
20938
21040
  const {
20939
- defaultOpen,
20940
- disabled,
21041
+ filter,
21042
+ setFilter,
21043
+ filterDefs,
21044
+ groupBy,
21045
+ searchProps,
21046
+ hasHideableColumns,
20941
21047
  columns,
20942
- api
21048
+ api,
21049
+ withCardView,
21050
+ view,
21051
+ setView
20943
21052
  } = props;
20944
- const state = (0, import_react_stately17.useMenuTriggerState)({
20945
- isOpen: defaultOpen
20946
- });
20947
- const buttonRef = (0, import_react107.useRef)(null);
20948
- const {
20949
- menuTriggerProps
20950
- } = (0, import_react_aria46.useMenuTrigger)({
20951
- isDisabled: !!disabled
20952
- }, state, buttonRef);
20953
- const tid = useTestIds(props, "columns");
21053
+ const testId = useTestIds(props, "gridTableLayoutActions");
20954
21054
  const {
20955
21055
  sm
20956
21056
  } = useBreakpoint();
20957
- const options = (0, import_react107.useMemo)(() => columns.filter((column2) => column2.canHide).filter((column2) => {
20958
- if (!column2.name || column2.name.length === 0 || !column2.id || column2.id.length === 0) {
20959
- console.warn("Column is missing 'name' and/or 'id' property required by the Edit Columns button", column2);
20960
- return false;
20961
- }
20962
- return true;
20963
- }).map((column2) => ({
20964
- label: column2.name,
20965
- value: column2.id
20966
- })), [columns]);
20967
- const selectedValues = useComputed(() => api.getVisibleColumnIds(), [api]);
20968
- const setSelectedValues = (0, import_react107.useCallback)((ids) => {
20969
- api.resetColumnWidths();
20970
- api.setVisibleColumns(columns.filter((column2) => column2.canHide ? ids.includes(column2.id) : true).map((c) => c.id));
20971
- }, [columns, api]);
20972
- return /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(OverlayTrigger, { ...props, trigger: {
20973
- icon: "columns",
20974
- size: "md",
20975
- label: "",
20976
- variant: "secondaryBlack"
20977
- }, menuTriggerProps, state, buttonRef, hideEndAdornment: sm, ...tid, children: /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)("div", { ...(0, import_runtime78.trussProps)({
20978
- display: "df",
20979
- flexDirection: "fdc",
20980
- backgroundColor: ["bgColor_var", {
20981
- "--backgroundColor": "var(--b-surface)"
20982
- }],
20983
- maxWidth: "maxw_326px",
20984
- maxHeight: "maxh_512px",
20985
- boxShadow: "h_bshHover"
20986
- }), children: [
20987
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "dg gtc_1fr_auto gap2 pt2 pb2 pr2 pl2 fg1 mh0 oya", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime147.jsxs)(import_react107.Fragment, { children: [
20988
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { className: "fw4 fz_14px lh_20px wsnw oh to_ellipsis pr1", children: option.label }),
20989
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Switch, { compact: true, selected: selectedValues.includes(option.value), onChange: (value) => setSelectedValues(value ? [...selectedValues, option.value] : selectedValues.filter((v) => v !== option.value)), labelStyle: "hidden", label: option.label, ...tid[`option${option.value}`] })
20990
- ] }, option.value)) }),
20991
- /* @__PURE__ */ (0, import_jsx_runtime147.jsx)("div", { ...(0, import_runtime78.trussProps)({
20992
- display: "df",
20993
- justifyContent: "jcc",
20994
- paddingTop: "pt2",
20995
- paddingBottom: "pb2",
20996
- paddingRight: "pr2",
20997
- paddingLeft: "pl2",
20998
- borderTopStyle: "bts_solid",
20999
- borderTopWidth: "btw_1px",
21000
- borderColor: ["bc_var", {
21001
- "--borderColor": "var(--b-surface-separator)"
21002
- }]
21003
- }), children: /* @__PURE__ */ (0, import_jsx_runtime147.jsx)(Button, { variant: "tertiary", label: "Reset Column Widths", onClick: () => api.resetColumnWidths() }) })
21004
- ] }) });
21005
- }
21006
-
21007
- // src/components/Table/components/ViewToggleButton.tsx
21008
- var import_jsx_runtime148 = require("react/jsx-runtime");
21009
- function ViewToggleButton({ view, onChange, defaultOpen }) {
21010
- const { sm } = useBreakpoint();
21011
- const tid = useTestIds({}, "viewToggleButton");
21012
- const menuItems = [
21013
- { label: "List", icon: "projects", onClick: () => onChange("list") },
21014
- { label: "Card", icon: "tile", onClick: () => onChange("card") }
21015
- ];
21016
- return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
21017
- ButtonMenu,
21018
- {
21019
- trigger: { icon: view === "list" ? "projects" : "tile", label: "", size: "md", variant: "secondaryBlack" },
21020
- items: menuItems,
21021
- hideEndAdornment: sm,
21022
- defaultOpen,
21023
- ...tid
21057
+ const inDocumentScrollLayout = useDocumentScrollLayout();
21058
+ const [showSearch, setShowSearch] = (0, import_react107.useState)(false);
21059
+ const [showFilters, setShowFilters] = (0, import_react107.useState)(false);
21060
+ const [{
21061
+ search: initialValue
21062
+ }, setQueryParams] = (0, import_use_query_params3.useQueryParams)({
21063
+ search: import_use_query_params3.StringParam
21064
+ });
21065
+ const [searchValue, setSearchValue] = (0, import_react107.useState)(initialValue || "");
21066
+ const handleSearchDebounced = (0, import_use_debounce7.useDebouncedCallback)((value) => {
21067
+ if (searchProps) {
21068
+ searchProps.onSearch(value);
21069
+ setQueryParams({
21070
+ search: value || void 0
21071
+ }, "replaceIn");
21024
21072
  }
21025
- );
21026
- }
21027
-
21028
- // src/components/Table/TableActions.tsx
21029
- var import_runtime79 = require("@homebound/truss/runtime");
21030
- var import_jsx_runtime149 = require("react/jsx-runtime");
21031
- function TableActions(props) {
21032
- const {
21033
- xss,
21034
- children,
21035
- right
21036
- } = props;
21037
- return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { ...(0, import_runtime79.trussProps)({
21038
- ...{
21073
+ }, 300);
21074
+ const hasSearch = !!searchProps;
21075
+ const hasFilters = !!filterDefs && Object.keys(filterDefs ?? {}).length > 0;
21076
+ const activeFilterCount = (0, import_react107.useMemo)(() => filter ? getActiveFilterCount(filter) : 0, [filter]);
21077
+ const filterImpls = (0, import_react107.useMemo)(() => filterDefs ? buildFilterImpls(filterDefs) : {}, [filterDefs]);
21078
+ const searchTextField = /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(TextField, { label: "Search", labelStyle: "hidden", value: searchValue, onChange: (v) => {
21079
+ setSearchValue(v ?? "");
21080
+ handleSearchDebounced(v ?? "");
21081
+ }, placeholder: "Search", clearable: true, fullWidth: true, startAdornment: /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(Icon, { icon: "search", color: "rgba(100, 100, 100, 1)" /* Gray700 */ }) });
21082
+ return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "df fdc gap1 pb2", children: [
21083
+ /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { ...(0, import_runtime79.trussProps)({
21039
21084
  display: "df",
21040
21085
  gap: "gap1",
21041
- alignItems: "aifs",
21042
21086
  justifyContent: "jcsb",
21043
- paddingBottom: "pb2"
21044
- },
21045
- ...xss
21046
- }), children: [
21047
- /* @__PURE__ */ (0, import_jsx_runtime149.jsx)("div", { className: "df gap1 aic fww", children }),
21048
- right
21087
+ paddingTop: "pt3",
21088
+ ...inDocumentScrollLayout ? {
21089
+ paddingLeft: "pl3",
21090
+ paddingRight: "pr3"
21091
+ } : {}
21092
+ }), children: [
21093
+ /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "df gap1 aic", children: [
21094
+ !sm && hasSearch && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)("div", { className: "w_244px", children: searchTextField }),
21095
+ sm && hasSearch && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(IconButton, { variant: "outline", icon: searchValue ? "searchBadged" : "search", label: "Search", onClick: () => setShowSearch(!showSearch), active: showSearch, ...testId.searchButton }),
21096
+ sm && hasFilters && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(IconButton, { variant: "outline", icon: activeFilterCount > 0 ? "filterBadged" : "filter", label: "Filter", onClick: () => setShowFilters(!showFilters), active: showFilters, ...testId.filterSmallButton }),
21097
+ !sm && hasFilters && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(Button, { label: "Filter", icon: "filter", size: "md", endAdornment: /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "df aic gap1", children: [
21098
+ activeFilterCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(CountBadge, { count: activeFilterCount }),
21099
+ /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(Icon, { icon: showFilters ? "chevronUp" : "chevronDown" })
21100
+ ] }), variant: "secondaryBlack", onClick: () => setShowFilters(!showFilters), active: showFilters, ...testId.filterButton })
21101
+ ] }),
21102
+ (hasHideableColumns || withCardView) && /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)("div", { className: "df gap1", children: [
21103
+ hasHideableColumns && view === "list" && columns && api && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(EditColumnsButton, { columns, api, tooltip: "Display columns" }),
21104
+ withCardView && view !== void 0 && setView && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(ViewToggleButton, { view, onChange: setView })
21105
+ ] })
21106
+ ] }),
21107
+ sm && showSearch && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)("div", { className: "pl3 pr3", children: searchTextField }),
21108
+ hasFilters && /* @__PURE__ */ (0, import_jsx_runtime149.jsx)(FilterPanel, { isOpen: showFilters, groupBy, filterImpls, filter, setFilter, onClear: () => setFilter?.({}) })
21049
21109
  ] });
21050
21110
  }
21051
-
21052
- // src/components/Layout/layoutTypes.ts
21053
- function isGridTableProps(props) {
21054
- return "rows" in props;
21055
- }
21111
+ var _GridTableLayoutActions = (0, import_react107.memo)(GridTableLayoutActionsComponent);
21056
21112
 
21057
21113
  // src/components/Layout/GridTableLayout/QueryTable.tsx
21058
21114
  var import_react108 = require("react");
@@ -21214,16 +21270,7 @@ function GridTableLayoutComponent(props) {
21214
21270
  onSearch: layoutState.setSearchString
21215
21271
  } : void 0, [layoutState?.search, layoutState?.setSearchString]);
21216
21272
  const emptyState = (0, import_react110.useMemo)(() => composeEmptyState(tableProps, layoutState, layoutEmptyFallback), [layoutEmptyFallback, layoutState, tableProps]);
21217
- const tableActionsEl = /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(TableActions, { right: (hasHideableColumns || withCardView) && /* @__PURE__ */ (0, import_jsx_runtime152.jsxs)("div", { className: "df gap1", children: [
21218
- hasHideableColumns && view === "list" && /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(EditColumnsButton, { columns, api, tooltip: "Display columns", ...tid.editColumnsButton }),
21219
- withCardView && /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(ViewToggleButton, { view, onChange: setView })
21220
- ] }), xss: {
21221
- paddingTop: "pt3",
21222
- ...inDocumentScrollLayout ? {
21223
- paddingLeft: "pl3",
21224
- paddingRight: "pr3"
21225
- } : {}
21226
- }, children: layoutState && (layoutState.filterDefs || layoutState.search) && /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(_FilterDropdownMenu, { filterDefs: layoutState.filterDefs, filter: layoutState.filter, onChange: layoutState.setFilter, groupBy: layoutState.groupBy, searchProps: filterSearchProps }) });
21273
+ const tableActionsEl = /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(_GridTableLayoutActions, { filterDefs: layoutState?.filterDefs, filter: layoutState?.filter, setFilter: layoutState?.setFilter, groupBy: layoutState?.groupBy, searchProps: filterSearchProps, hasHideableColumns, columns, api, withCardView, view, setView });
21227
21274
  const cardAs = withCardView && view === "card" ? "card" : void 0;
21228
21275
  const tableBody = /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(import_jsx_runtime152.Fragment, { children: isGridTableProps(tableProps) ? /* @__PURE__ */ (0, import_jsx_runtime152.jsx)(GridTable, { ...tableProps, ...cardAs ? {
21229
21276
  as: cardAs
@@ -21339,7 +21386,7 @@ function useSetTableActionsHeight(tableWrapperRef, tableActionsRef, enabled) {
21339
21386
  tableWrapper.style.removeProperty(beamTableActionsHeightVar);
21340
21387
  }
21341
21388
  }, [enabled, tableActionsRef, tableWrapperRef]);
21342
- (0, import_utils124.useResizeObserver)({
21389
+ (0, import_utils125.useResizeObserver)({
21343
21390
  ref: tableActionsRef,
21344
21391
  onResize: enabled ? syncHeightVar : noop
21345
21392
  });
@@ -21976,7 +22023,7 @@ var import_react118 = require("react");
21976
22023
  var import_react_aria50 = require("react-aria");
21977
22024
 
21978
22025
  // src/components/Tag.tsx
21979
- var import_utils132 = require("@react-aria/utils");
22026
+ var import_utils133 = require("@react-aria/utils");
21980
22027
  var import_react117 = require("react");
21981
22028
  var import_runtime85 = require("@homebound/truss/runtime");
21982
22029
  var import_jsx_runtime162 = require("react/jsx-runtime");
@@ -21984,6 +22031,7 @@ function Tag(props) {
21984
22031
  const {
21985
22032
  text,
21986
22033
  type,
22034
+ variant = "primary",
21987
22035
  xss,
21988
22036
  preventTooltip = false,
21989
22037
  iconOnly,
@@ -21993,12 +22041,14 @@ function Tag(props) {
21993
22041
  const isIconOnly = !!iconOnly && !!icon;
21994
22042
  const {
21995
22043
  background,
21996
- iconColor
21997
- } = getStyles(type);
22044
+ iconColor,
22045
+ typography,
22046
+ padding
22047
+ } = getVariantStyles(variant, type);
21998
22048
  const tid = useTestIds(otherProps);
21999
22049
  const [showTooltip, setShowTooltip] = (0, import_react117.useState)(false);
22000
22050
  const ref = (0, import_react117.useRef)(null);
22001
- (0, import_utils132.useResizeObserver)({
22051
+ (0, import_utils133.useResizeObserver)({
22002
22052
  ref,
22003
22053
  onResize: () => {
22004
22054
  if (!isIconOnly && ref.current) {
@@ -22013,10 +22063,6 @@ function Tag(props) {
22013
22063
  ...{
22014
22064
  position: "relative",
22015
22065
  display: "dif",
22016
- fontWeight: "fw6",
22017
- fontSize: "fz_10px",
22018
- lineHeight: "lh_14px",
22019
- textTransform: "ttu",
22020
22066
  alignItems: "aic",
22021
22067
  gap: "gap_4px",
22022
22068
  paddingTop: "pt_2px",
@@ -22024,13 +22070,11 @@ function Tag(props) {
22024
22070
  color: "gray900",
22025
22071
  borderRadius: "br4"
22026
22072
  },
22073
+ ...typography,
22027
22074
  ...isIconOnly ? {
22028
22075
  paddingLeft: "pl_2px",
22029
22076
  paddingRight: "pr_2px"
22030
- } : {
22031
- paddingLeft: "pl_6px",
22032
- paddingRight: "pr_6px"
22033
- },
22077
+ } : padding,
22034
22078
  ...background,
22035
22079
  ...xss
22036
22080
  }), children: [
@@ -22039,7 +22083,42 @@ function Tag(props) {
22039
22083
  ] })
22040
22084
  });
22041
22085
  }
22042
- function getStyles(type) {
22086
+ function getVariantStyles(variant, type) {
22087
+ if (variant === "secondary") {
22088
+ return {
22089
+ background: {
22090
+ backgroundColor: "bgWhite",
22091
+ borderColor: "bcGray300",
22092
+ borderWidth: "bw1",
22093
+ borderStyle: "bss"
22094
+ },
22095
+ iconColor: "rgba(100, 100, 100, 1)" /* Gray700 */,
22096
+ typography: {
22097
+ fontWeight: "fw4",
22098
+ fontSize: "fz_12px",
22099
+ lineHeight: "lh_16px"
22100
+ },
22101
+ padding: {
22102
+ paddingLeft: "pl_8px",
22103
+ paddingRight: "pr_8px"
22104
+ }
22105
+ };
22106
+ }
22107
+ return {
22108
+ ...getPrimaryStyles(type),
22109
+ typography: {
22110
+ fontWeight: "fw6",
22111
+ fontSize: "fz_10px",
22112
+ lineHeight: "lh_14px",
22113
+ textTransform: "ttu"
22114
+ },
22115
+ padding: {
22116
+ paddingLeft: "pl_6px",
22117
+ paddingRight: "pr_6px"
22118
+ }
22119
+ };
22120
+ }
22121
+ function getPrimaryStyles(type) {
22043
22122
  switch (type) {
22044
22123
  case "info":
22045
22124
  return {
@@ -22917,7 +22996,7 @@ function HomeboundLogo(props) {
22917
22996
  }
22918
22997
 
22919
22998
  // src/components/MaxLines.tsx
22920
- var import_utils141 = require("@react-aria/utils");
22999
+ var import_utils142 = require("@react-aria/utils");
22921
23000
  var import_react127 = require("react");
22922
23001
  var import_runtime95 = require("@homebound/truss/runtime");
22923
23002
  var import_jsx_runtime172 = require("react/jsx-runtime");
@@ -22928,7 +23007,7 @@ function MaxLines({
22928
23007
  const elRef = (0, import_react127.useRef)(null);
22929
23008
  const [hasMore, setHasMore] = (0, import_react127.useState)(false);
22930
23009
  const [expanded, setExpanded] = (0, import_react127.useState)(false);
22931
- (0, import_utils141.useLayoutEffect)(() => {
23010
+ (0, import_utils142.useLayoutEffect)(() => {
22932
23011
  if (!elRef.current) return;
22933
23012
  setHasMore(elRef.current.scrollHeight > elRef.current.clientHeight);
22934
23013
  }, []);
@@ -22939,7 +23018,7 @@ function MaxLines({
22939
23018
  if (!elRef.current) return;
22940
23019
  !expanded && setHasMore(elRef.current.scrollHeight > elRef.current.clientHeight);
22941
23020
  }, [expanded]);
22942
- (0, import_utils141.useResizeObserver)({
23021
+ (0, import_utils142.useResizeObserver)({
22943
23022
  ref: elRef,
22944
23023
  onResize
22945
23024
  });
@@ -22963,7 +23042,7 @@ function MaxLines({
22963
23042
  var import_change_case8 = require("change-case");
22964
23043
 
22965
23044
  // src/components/AppNav/AppNavGroup.tsx
22966
- var import_utils143 = require("@react-aria/utils");
23045
+ var import_utils144 = require("@react-aria/utils");
22967
23046
  var import_change_case7 = require("change-case");
22968
23047
  var import_react130 = require("react");
22969
23048
 
@@ -23206,7 +23285,7 @@ function AppNavGroupDisclosure(props) {
23206
23285
  setContentHeight(`${contentEl.scrollHeight}px`);
23207
23286
  }
23208
23287
  }, [expanded, contentEl]);
23209
- (0, import_utils143.useResizeObserver)({
23288
+ (0, import_utils144.useResizeObserver)({
23210
23289
  ref: contentRef,
23211
23290
  onResize
23212
23291
  });
@@ -23908,7 +23987,7 @@ function toPageNumberSize(page) {
23908
23987
  }
23909
23988
 
23910
23989
  // src/components/ScrollShadows.tsx
23911
- var import_utils152 = require("@react-aria/utils");
23990
+ var import_utils153 = require("@react-aria/utils");
23912
23991
  var import_react134 = require("react");
23913
23992
  var import_runtime103 = require("@homebound/truss/runtime");
23914
23993
  var import_jsx_runtime184 = require("react/jsx-runtime");
@@ -23997,7 +24076,7 @@ function ScrollShadows(props) {
23997
24076
  setShowEndShadow(start + boxSize < end);
23998
24077
  }, [horizontal]);
23999
24078
  const onResize = (0, import_react134.useCallback)(() => scrollRef.current && updateScrollProps(scrollRef.current), [updateScrollProps]);
24000
- (0, import_utils152.useResizeObserver)({
24079
+ (0, import_utils153.useResizeObserver)({
24001
24080
  ref: scrollRef,
24002
24081
  onResize
24003
24082
  });
@@ -24709,6 +24788,21 @@ function visit(rows, fn) {
24709
24788
  }
24710
24789
  }
24711
24790
 
24791
+ // src/components/TagGroup.tsx
24792
+ var import_jsx_runtime192 = require("react/jsx-runtime");
24793
+ function TagGroup(props) {
24794
+ const {
24795
+ tags,
24796
+ onEdit,
24797
+ ...otherProps
24798
+ } = props;
24799
+ const tid = useTestIds(otherProps, "tagGroup");
24800
+ return /* @__PURE__ */ (0, import_jsx_runtime192.jsxs)("div", { ...tid, className: "df aic fww gap1", children: [
24801
+ tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(Tag, { ...tag, variant: "secondary" }, tag.text)),
24802
+ onEdit && /* @__PURE__ */ (0, import_jsx_runtime192.jsx)("span", { className: "ml1 fw4 fz_14px lh_20px", children: /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(Button, { label: "Edit", variant: "text", onClick: onEdit, ...tid.edit }) })
24803
+ ] });
24804
+ }
24805
+
24712
24806
  // src/components/Toast/useToast.tsx
24713
24807
  var import_react140 = require("react");
24714
24808
  function useToast() {
@@ -24719,14 +24813,14 @@ function useToast() {
24719
24813
 
24720
24814
  // src/layouts/SideNavLayout/SideNavLayout.tsx
24721
24815
  var import_runtime108 = require("@homebound/truss/runtime");
24722
- var import_jsx_runtime192 = require("react/jsx-runtime");
24816
+ var import_jsx_runtime193 = require("react/jsx-runtime");
24723
24817
  var __maybeInc21 = (inc) => {
24724
24818
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
24725
24819
  };
24726
24820
  function SideNavLayout(props) {
24727
24821
  const hasProvider = useHasSideNavLayoutProvider();
24728
- if (hasProvider) return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(SideNavLayoutContent, { ...props });
24729
- return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(SideNavLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(SideNavLayoutContent, { ...props }) });
24822
+ if (hasProvider) return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(SideNavLayoutContent, { ...props });
24823
+ return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(SideNavLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(SideNavLayoutContent, { ...props }) });
24730
24824
  }
24731
24825
  function SideNavLayoutContent(props) {
24732
24826
  const {
@@ -24748,7 +24842,7 @@ function SideNavLayoutContent(props) {
24748
24842
  const railOffsetPx = !showRail ? 0 : !bp.mdAndUp || collapsed ? railCollapsedWidthPx : railWidthPx;
24749
24843
  const navTop = bannerAndNavbarChromeTop();
24750
24844
  const railViewportHeight = `calc(var(${beamLayoutViewportHeightVar}, 100vh) - var(${beamEnvironmentBannerLayoutHeightVar}, 0px) - var(${beamNavbarLayoutHeightVar}, 0px))`;
24751
- const rail = showRail && /* @__PURE__ */ (0, import_jsx_runtime192.jsxs)("div", { ...(0, import_runtime108.trussProps)({
24845
+ const rail = showRail && /* @__PURE__ */ (0, import_jsx_runtime193.jsxs)("div", { ...(0, import_runtime108.trussProps)({
24752
24846
  ...{
24753
24847
  display: "df",
24754
24848
  flexDirection: "fdc",
@@ -24805,18 +24899,18 @@ function SideNavLayoutContent(props) {
24805
24899
  }
24806
24900
  }
24807
24901
  }), ...tid.sideNav, children: [
24808
- showCollapseToggle && /* @__PURE__ */ (0, import_jsx_runtime192.jsx)("div", { className: "absolute right2 top2 z2", children: /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(IconButton, { icon: collapsed ? "menuOpen" : "menuClose", label: collapsed ? "Expand navigation" : "Collapse navigation", onClick: () => setNavState(collapsed ? "expanded" : "collapse"), ...tid.toggle }) }),
24809
- /* @__PURE__ */ (0, import_jsx_runtime192.jsx)("div", { className: "fg1 mh0 df fdc", ...tid.sideNavContent, children: /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(SideNav, { ...sideNav }) })
24902
+ showCollapseToggle && /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("div", { className: "absolute right2 top2 z2", children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(IconButton, { icon: collapsed ? "menuOpen" : "menuClose", label: collapsed ? "Expand navigation" : "Collapse navigation", onClick: () => setNavState(collapsed ? "expanded" : "collapse"), ...tid.toggle }) }),
24903
+ /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("div", { className: "fg1 mh0 df fdc", ...tid.sideNavContent, children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(SideNav, { ...sideNav }) })
24810
24904
  ] });
24811
- return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime192.jsxs)("div", { ...(0, import_runtime108.mergeProps)(void 0, {
24905
+ return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime193.jsxs)("div", { ...(0, import_runtime108.mergeProps)(void 0, {
24812
24906
  [beamSideNavLayoutWidthVar]: `${railOffsetPx}px`
24813
24907
  }, {
24814
24908
  display: "df",
24815
24909
  flexDirection: "fdr",
24816
24910
  width: "w100"
24817
24911
  }), ...tid, children: [
24818
- contrastRail ? /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(ContrastScope, { children: rail }) : rail,
24819
- /* @__PURE__ */ (0, import_jsx_runtime192.jsx)("div", { ...(0, import_runtime108.trussProps)({
24912
+ contrastRail ? /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(ContrastScope, { children: rail }) : rail,
24913
+ /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("div", { ...(0, import_runtime108.trussProps)({
24820
24914
  display: "df",
24821
24915
  flexDirection: "fdc",
24822
24916
  flexGrow: "fg1",
@@ -24833,7 +24927,7 @@ function SideNavLayoutContent(props) {
24833
24927
 
24834
24928
  // src/layouts/EnvironmentBannerLayout/EnvironmentBannerLayout.tsx
24835
24929
  var import_runtime109 = require("@homebound/truss/runtime");
24836
- var import_jsx_runtime193 = require("react/jsx-runtime");
24930
+ var import_jsx_runtime194 = require("react/jsx-runtime");
24837
24931
  var __maybeInc22 = (inc) => {
24838
24932
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
24839
24933
  };
@@ -24849,18 +24943,18 @@ function EnvironmentBannerLayout(props) {
24849
24943
  [beamEnvironmentBannerLayoutHeightVar]: `${bannerHeightPx}px`
24850
24944
  };
24851
24945
  const innerWidth = `var(${beamLayoutViewportWidthVar}, 100vw)`;
24852
- return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(EnvironmentBannerLayoutHeightProvider, { value: bannerHeightPx, children: /* @__PURE__ */ (0, import_jsx_runtime193.jsxs)("div", { ...(0, import_runtime109.mergeProps)(void 0, style, {
24946
+ return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(EnvironmentBannerLayoutHeightProvider, { value: bannerHeightPx, children: /* @__PURE__ */ (0, import_jsx_runtime194.jsxs)("div", { ...(0, import_runtime109.mergeProps)(void 0, style, {
24853
24947
  display: "df",
24854
24948
  flexDirection: "fdc",
24855
24949
  width: "wfc",
24856
24950
  minWidth: "mw100"
24857
24951
  }), ...tid, children: [
24858
- showBanner && environmentBanner && /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("div", { ...(0, import_runtime109.mergeProps)(void 0, {
24952
+ showBanner && environmentBanner && /* @__PURE__ */ (0, import_jsx_runtime194.jsx)("div", { ...(0, import_runtime109.mergeProps)(void 0, {
24859
24953
  height: environmentBannerSizePx
24860
24954
  }, {
24861
24955
  flexShrink: "fs0",
24862
24956
  width: "w100"
24863
- }), children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)("div", { ...(0, import_runtime109.trussProps)({
24957
+ }), children: /* @__PURE__ */ (0, import_jsx_runtime194.jsx)("div", { ...(0, import_runtime109.trussProps)({
24864
24958
  position: "fixed",
24865
24959
  top: "top0",
24866
24960
  left: "left0",
@@ -24870,7 +24964,7 @@ function EnvironmentBannerLayout(props) {
24870
24964
  width: ["w_var", {
24871
24965
  "--width": (0, import_runtime109.maybeCssVar)(__maybeInc22(innerWidth))
24872
24966
  }]
24873
- }), ...tid.bannerSticky, children: /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(EnvironmentBanner, { ...environmentBanner, ...tid.environmentBanner }) }) }),
24967
+ }), ...tid.bannerSticky, children: /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(EnvironmentBanner, { ...environmentBanner, ...tid.environmentBanner }) }) }),
24874
24968
  children
24875
24969
  ] }) }) });
24876
24970
  }
@@ -24970,7 +25064,7 @@ function useAutoHideOnScroll(spacerRef, enabled, getTopOffset) {
24970
25064
  }
24971
25065
 
24972
25066
  // src/layouts/useMeasuredHeight.ts
24973
- var import_utils160 = require("@react-aria/utils");
25067
+ var import_utils162 = require("@react-aria/utils");
24974
25068
  var import_react142 = require("react");
24975
25069
  function useMeasuredHeight(ref, enabled) {
24976
25070
  const [height, setHeight] = (0, import_react142.useState)(0);
@@ -24979,7 +25073,7 @@ function useMeasuredHeight(ref, enabled) {
24979
25073
  const next = el ? Math.round(el.getBoundingClientRect().height) : 0;
24980
25074
  setHeight((prev) => prev === next ? prev : next);
24981
25075
  }, [ref]);
24982
- (0, import_utils160.useResizeObserver)({ ref, onResize: syncElementHeight });
25076
+ (0, import_utils162.useResizeObserver)({ ref, onResize: syncElementHeight });
24983
25077
  (0, import_react142.useLayoutEffect)(() => {
24984
25078
  syncElementHeight();
24985
25079
  }, [enabled, syncElementHeight]);
@@ -24988,17 +25082,17 @@ function useMeasuredHeight(ref, enabled) {
24988
25082
 
24989
25083
  // src/layouts/NavbarLayout/NavbarLayoutHeightContext.tsx
24990
25084
  var import_react143 = require("react");
24991
- var import_jsx_runtime194 = require("react/jsx-runtime");
25085
+ var import_jsx_runtime195 = require("react/jsx-runtime");
24992
25086
  var NavbarLayoutHeightContext = (0, import_react143.createContext)(0);
24993
25087
  function NavbarLayoutHeightProvider({ value, children }) {
24994
- return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(NavbarLayoutHeightContext.Provider, { value, children });
25088
+ return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(NavbarLayoutHeightContext.Provider, { value, children });
24995
25089
  }
24996
25090
  function useNavbarLayoutHeight() {
24997
25091
  return (0, import_react143.useContext)(NavbarLayoutHeightContext);
24998
25092
  }
24999
25093
 
25000
25094
  // src/layouts/NavbarLayout/NavbarLayout.tsx
25001
- var import_jsx_runtime195 = require("react/jsx-runtime");
25095
+ var import_jsx_runtime196 = require("react/jsx-runtime");
25002
25096
  var __maybeInc23 = (inc) => {
25003
25097
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
25004
25098
  };
@@ -25051,20 +25145,20 @@ function NavbarLayout(props) {
25051
25145
  const innerStyle = autoHideState !== "static" ? {
25052
25146
  top: autoHideState === "revealed" ? bannerTop : `calc(${bannerTop} - ${navHeight}px)`
25053
25147
  } : void 0;
25054
- const navbarEl = (0, import_react144.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(Navbar, { ...navbar }), [navbar]);
25055
- return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(NavbarLayoutHeightProvider, { value: navbarOffsetPx, children: /* @__PURE__ */ (0, import_jsx_runtime195.jsxs)("div", { ...(0, import_runtime110.mergeProps)(void 0, cssVars, {
25148
+ const navbarEl = (0, import_react144.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(Navbar, { ...navbar }), [navbar]);
25149
+ return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(NavbarLayoutHeightProvider, { value: navbarOffsetPx, children: /* @__PURE__ */ (0, import_jsx_runtime196.jsxs)("div", { ...(0, import_runtime110.mergeProps)(void 0, cssVars, {
25056
25150
  display: "df",
25057
25151
  flexDirection: "fdc",
25058
25152
  width: "wfc",
25059
25153
  minWidth: "mw100"
25060
25154
  }), ...tid, children: [
25061
- /* @__PURE__ */ (0, import_jsx_runtime195.jsx)("div", { ref: spacerRef, ...(0, import_runtime110.mergeProps)(void 0, {
25155
+ /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { ref: spacerRef, ...(0, import_runtime110.mergeProps)(void 0, {
25062
25156
  height: navHeight
25063
25157
  }, {
25064
25158
  flexShrink: "fs0",
25065
25159
  width: "w100"
25066
- }), children: /* @__PURE__ */ (0, import_jsx_runtime195.jsx)("div", { ref: navMetricsRef, ...(0, import_runtime110.mergeProps)(void 0, innerStyle, innerCss), ...tid.navbar, children: navbarEl }) }),
25067
- /* @__PURE__ */ (0, import_jsx_runtime195.jsx)("div", { className: "df fdc mh0 mw100 w100", ...tid.body, children })
25160
+ }), children: /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { ref: navMetricsRef, ...(0, import_runtime110.mergeProps)(void 0, innerStyle, innerCss), ...tid.navbar, children: navbarEl }) }),
25161
+ /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { className: "df fdc mh0 mw100 w100", ...tid.body, children })
25068
25162
  ] }) }) });
25069
25163
  }
25070
25164
 
@@ -25078,7 +25172,7 @@ function useBannerAndNavbarHeight() {
25078
25172
 
25079
25173
  // src/layouts/PageHeaderLayout/PageHeaderLayout.tsx
25080
25174
  var import_runtime111 = require("@homebound/truss/runtime");
25081
- var import_jsx_runtime196 = require("react/jsx-runtime");
25175
+ var import_jsx_runtime197 = require("react/jsx-runtime");
25082
25176
  var __maybeInc24 = (inc) => {
25083
25177
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
25084
25178
  };
@@ -25133,19 +25227,19 @@ function PageHeaderLayout(props) {
25133
25227
  const innerStyle = autoHideState !== "static" ? {
25134
25228
  top: autoHideState === "revealed" ? outerTop : `calc(${outerTop} - ${headerHeight}px)`
25135
25229
  } : void 0;
25136
- const pageHeaderEl = (0, import_react145.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(PageHeader2, { ...pageHeader }), [pageHeader]);
25137
- return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime196.jsxs)("div", { ...(0, import_runtime111.mergeProps)(void 0, cssVars, {
25230
+ const pageHeaderEl = (0, import_react145.useMemo)(() => /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(PageHeader2, { ...pageHeader }), [pageHeader]);
25231
+ return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime197.jsxs)("div", { ...(0, import_runtime111.mergeProps)(void 0, cssVars, {
25138
25232
  display: "df",
25139
25233
  flexDirection: "fdc",
25140
25234
  width: "w100"
25141
25235
  }), ...tid, children: [
25142
- /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { ref: spacerRef, ...(0, import_runtime111.mergeProps)(void 0, {
25236
+ /* @__PURE__ */ (0, import_jsx_runtime197.jsx)("div", { ref: spacerRef, ...(0, import_runtime111.mergeProps)(void 0, {
25143
25237
  height: headerHeight
25144
25238
  }, {
25145
25239
  flexShrink: "fs0",
25146
25240
  width: "w100"
25147
- }), children: /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { ref: headerMetricsRef, ...(0, import_runtime111.mergeProps)(void 0, innerStyle, innerCss), ...tid.pageHeader, children: pageHeaderEl }) }),
25148
- /* @__PURE__ */ (0, import_jsx_runtime196.jsx)("div", { className: "df fdc fg1 mh0 w100", ...tid.body, children })
25241
+ }), children: /* @__PURE__ */ (0, import_jsx_runtime197.jsx)("div", { ref: headerMetricsRef, ...(0, import_runtime111.mergeProps)(void 0, innerStyle, innerCss), ...tid.pageHeader, children: pageHeaderEl }) }),
25242
+ /* @__PURE__ */ (0, import_jsx_runtime197.jsx)("div", { className: "df fdc fg1 mh0 w100", ...tid.body, children })
25149
25243
  ] }) });
25150
25244
  }
25151
25245
  // Annotate the CommonJS export names for ESM import in node:
@@ -25217,7 +25311,6 @@ function PageHeaderLayout(props) {
25217
25311
  EnvironmentBannerLayout,
25218
25312
  ErrorMessage,
25219
25313
  FieldGroup,
25220
- FilterDropdownMenu,
25221
25314
  FilterModal,
25222
25315
  Filters,
25223
25316
  FormDivider,
@@ -25302,6 +25395,7 @@ function PageHeaderLayout(props) {
25302
25395
  Tabs,
25303
25396
  TabsWithContent,
25304
25397
  Tag,
25398
+ TagGroup,
25305
25399
  TextAreaField,
25306
25400
  TextField,
25307
25401
  Toast,