@homebound/beam 3.101.0 → 3.102.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.d.cts CHANGED
@@ -9099,14 +9099,18 @@ declare function HbSpinnerProvider({ quips, children }: HbSpinnerProviderProps):
9099
9099
  * Tagged with `kind` (not `type`) because `ButtonProps` already has its own
9100
9100
  * unrelated `type?: "button" | "submit" | "reset"` HTML-attribute field.
9101
9101
  *
9102
+ * Labels are `string` so actions can collapse into a `ButtonMenu` on mobile.
9102
9103
  * Icon actions always render with the `outline` `IconButton` variant, so `variant` is omitted here.
9103
- * Menu actions always use a `verticalDots` trigger.
9104
9104
  */
9105
9105
  type HeaderAction = ({
9106
9106
  kind?: "default";
9107
- } & ButtonProps) | ({
9107
+ } & Omit<ButtonProps, "label"> & {
9108
+ label: string;
9109
+ }) | ({
9108
9110
  kind: "icon";
9109
- } & Omit<IconButtonProps, "variant">) | ({
9111
+ } & Omit<IconButtonProps, "variant" | "label"> & {
9112
+ label: string;
9113
+ }) | ({
9110
9114
  kind: "menu";
9111
9115
  } & ButtonMenuProps);
9112
9116
 
@@ -10631,6 +10635,8 @@ type BaseHeaderProps = {
10631
10635
  };
10632
10636
 
10633
10637
  type PageHeaderProps<V extends string, X> = Omit<BaseHeaderProps, "bottomSlot"> & {
10638
+ /** Rendered as buttons on desktop; two or more collapse into a `ButtonMenu` at `sm`. */
10639
+ actions?: HeaderAction[];
10634
10640
  tabs?: Omit<TabsProps<V, X>, "contentXss" | "omitFullBleedPadding" | "includeBottomBorder"> | Omit<RouteTabsProps<V, X>, "contentXss" | "omitFullBleedPadding" | "includeBottomBorder">;
10635
10641
  };
10636
10642
 
package/dist/index.d.ts CHANGED
@@ -9099,14 +9099,18 @@ declare function HbSpinnerProvider({ quips, children }: HbSpinnerProviderProps):
9099
9099
  * Tagged with `kind` (not `type`) because `ButtonProps` already has its own
9100
9100
  * unrelated `type?: "button" | "submit" | "reset"` HTML-attribute field.
9101
9101
  *
9102
+ * Labels are `string` so actions can collapse into a `ButtonMenu` on mobile.
9102
9103
  * Icon actions always render with the `outline` `IconButton` variant, so `variant` is omitted here.
9103
- * Menu actions always use a `verticalDots` trigger.
9104
9104
  */
9105
9105
  type HeaderAction = ({
9106
9106
  kind?: "default";
9107
- } & ButtonProps) | ({
9107
+ } & Omit<ButtonProps, "label"> & {
9108
+ label: string;
9109
+ }) | ({
9108
9110
  kind: "icon";
9109
- } & Omit<IconButtonProps, "variant">) | ({
9111
+ } & Omit<IconButtonProps, "variant" | "label"> & {
9112
+ label: string;
9113
+ }) | ({
9110
9114
  kind: "menu";
9111
9115
  } & ButtonMenuProps);
9112
9116
 
@@ -10631,6 +10635,8 @@ type BaseHeaderProps = {
10631
10635
  };
10632
10636
 
10633
10637
  type PageHeaderProps<V extends string, X> = Omit<BaseHeaderProps, "bottomSlot"> & {
10638
+ /** Rendered as buttons on desktop; two or more collapse into a `ButtonMenu` at `sm`. */
10639
+ actions?: HeaderAction[];
10634
10640
  tabs?: Omit<TabsProps<V, X>, "contentXss" | "omitFullBleedPadding" | "includeBottomBorder"> | Omit<RouteTabsProps<V, X>, "contentXss" | "omitFullBleedPadding" | "includeBottomBorder">;
10635
10641
  };
10636
10642
 
package/dist/index.js CHANGED
@@ -21474,9 +21474,20 @@ import { jsx as jsx149 } from "react/jsx-runtime";
21474
21474
  function HeaderActions(props) {
21475
21475
  const {
21476
21476
  actions,
21477
+ collapseOnSm = false,
21477
21478
  ...otherProps
21478
21479
  } = props;
21479
21480
  const tid = useTestIds(otherProps, "headerActions");
21481
+ const {
21482
+ sm
21483
+ } = useBreakpoint();
21484
+ const collapse = collapseOnSm && sm && actions.length > 1;
21485
+ if (collapse) {
21486
+ return /* @__PURE__ */ jsx149("div", { className: "df aic gap1 fs0", ...tid, children: /* @__PURE__ */ jsx149(ButtonMenu, { trigger: {
21487
+ icon: "verticalDots",
21488
+ variant: "outline"
21489
+ }, items: toMenuItems(actions) }) });
21490
+ }
21480
21491
  return /* @__PURE__ */ jsx149("div", { className: "df aic gap1 fs0", ...tid, children: actions.map((action, i) => {
21481
21492
  const key = headerActionKey(action, i);
21482
21493
  if (action.kind === "icon") {
@@ -21496,7 +21507,38 @@ function HeaderActions(props) {
21496
21507
  function headerActionKey(action, index) {
21497
21508
  if (action.kind === "icon") return `${action.icon}-${index}`;
21498
21509
  if (action.kind === "menu") return `menu-${index}`;
21499
- return `${String(action.label)}-${index}`;
21510
+ return `${action.label}-${index}`;
21511
+ }
21512
+ function toMenuItems(actions) {
21513
+ return actions.flatMap((action) => {
21514
+ if (action.kind === "menu") return action.items;
21515
+ const {
21516
+ label,
21517
+ onClick,
21518
+ disabled
21519
+ } = action;
21520
+ const itemOnClick = typeof onClick === "string" ? onClick : () => void onClick({});
21521
+ if (action.kind === "icon") {
21522
+ return [{
21523
+ label,
21524
+ onClick: itemOnClick,
21525
+ disabled,
21526
+ icon: action.icon
21527
+ }];
21528
+ }
21529
+ return [{
21530
+ label,
21531
+ onClick: itemOnClick,
21532
+ disabled,
21533
+ // Buttons can opt out of their default icon with `icon: null`, which menu items can't render.
21534
+ ...action.icon ? {
21535
+ icon: action.icon
21536
+ } : {},
21537
+ ...action.variant === "danger" ? {
21538
+ destructive: true
21539
+ } : {}
21540
+ }];
21541
+ });
21500
21542
  }
21501
21543
 
21502
21544
  // src/components/Headers/ContentHeader.tsx
@@ -25397,6 +25439,7 @@ function InlineFeedbackBanner(props) {
25397
25439
  /* @__PURE__ */ jsx203("span", { ...trussProps114({
25398
25440
  flexGrow: "fg1",
25399
25441
  minWidth: "mw0",
25442
+ paddingTop: "pt_1px",
25400
25443
  color: ["color_var", {
25401
25444
  "--color": "var(--b-on-surface)"
25402
25445
  }]
@@ -28170,14 +28213,19 @@ function BaseHeader(props) {
28170
28213
 
28171
28214
  // src/components/Headers/PageHeader.tsx
28172
28215
  import { trussProps as trussProps135 } from "@homebound/truss/runtime";
28173
- import { jsx as jsx233 } from "react/jsx-runtime";
28216
+ import { Fragment as Fragment51, jsx as jsx233, jsxs as jsxs123 } from "react/jsx-runtime";
28174
28217
  function PageHeader2(props) {
28175
28218
  const {
28176
28219
  tabs,
28220
+ actions,
28221
+ rightSlot,
28177
28222
  ...otherProps
28178
28223
  } = props;
28179
28224
  const tid = useTestIds(otherProps, "header");
28180
- return /* @__PURE__ */ jsx233(BaseHeader, { ...otherProps, bottomSlot: tabs && /* @__PURE__ */ jsx233("div", { ...trussProps135(pageContentPaddingX), children: /* @__PURE__ */ jsx233(Tabs, { ...tabs, ...tid.tabs }) }) });
28225
+ return /* @__PURE__ */ jsx233(BaseHeader, { ...otherProps, rightSlot: /* @__PURE__ */ jsxs123(Fragment51, { children: [
28226
+ rightSlot,
28227
+ actions && actions.length > 0 && /* @__PURE__ */ jsx233(HeaderActions, { actions, collapseOnSm: true })
28228
+ ] }), bottomSlot: tabs && /* @__PURE__ */ jsx233("div", { ...trussProps135(pageContentPaddingX), children: /* @__PURE__ */ jsx233(Tabs, { ...tabs, ...tid.tabs }) }) });
28181
28229
  }
28182
28230
 
28183
28231
  // src/layouts/useBannerAndNavbarHeight.ts
@@ -28187,7 +28235,7 @@ function useBannerAndNavbarHeight() {
28187
28235
 
28188
28236
  // src/layouts/PageHeaderLayout/PageHeaderLayout.tsx
28189
28237
  import { mergeProps as mergeProps40, maybeCssVar as maybeCssVar67 } from "@homebound/truss/runtime";
28190
- import { jsx as jsx234, jsxs as jsxs123 } from "react/jsx-runtime";
28238
+ import { jsx as jsx234, jsxs as jsxs124 } from "react/jsx-runtime";
28191
28239
  var __maybeInc32 = (inc) => {
28192
28240
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
28193
28241
  };
@@ -28243,7 +28291,7 @@ function PageHeaderLayout(props) {
28243
28291
  top: autoHideState === "revealed" ? outerTop : `calc(${outerTop} - ${headerHeight}px)`
28244
28292
  } : void 0;
28245
28293
  const pageHeaderEl = useMemo58(() => /* @__PURE__ */ jsx234(PageHeader2, { ...pageHeader }), [pageHeader]);
28246
- return /* @__PURE__ */ jsx234(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ jsxs123("div", { ...mergeProps40(void 0, cssVars, {
28294
+ return /* @__PURE__ */ jsx234(DocumentScrollLayoutProvider, { children: /* @__PURE__ */ jsxs124("div", { ...mergeProps40(void 0, cssVars, {
28247
28295
  display: "df",
28248
28296
  flexDirection: "fdc",
28249
28297
  width: "w100"
@@ -28378,7 +28426,7 @@ function UnsavedChangesNavigationModal(props) {
28378
28426
  }
28379
28427
 
28380
28428
  // src/layouts/Workflow/WorkflowActions.tsx
28381
- import { jsx as jsx238, jsxs as jsxs124 } from "react/jsx-runtime";
28429
+ import { jsx as jsx238, jsxs as jsxs125 } from "react/jsx-runtime";
28382
28430
  function WorkflowActions(props) {
28383
28431
  const {
28384
28432
  onCancel,
@@ -28396,9 +28444,9 @@ function WorkflowActions(props) {
28396
28444
  sm: isMobile
28397
28445
  } = useBreakpoint();
28398
28446
  const primaryVariant = aiMode ? "ai" : "primary";
28399
- return /* @__PURE__ */ jsxs124("div", { className: "df aic jcsb sm_w100", children: [
28447
+ return /* @__PURE__ */ jsxs125("div", { className: "df aic jcsb sm_w100", children: [
28400
28448
  /* @__PURE__ */ jsx238("div", { className: "df aic", children: !isFirstStep && isMobile && onBack && /* @__PURE__ */ jsx238(IconButton, { icon: "arrowBack", label: "Back", onClick: onBack }) }),
28401
- /* @__PURE__ */ jsxs124("div", { className: "df aic gap1", children: [
28449
+ /* @__PURE__ */ jsxs125("div", { className: "df aic gap1", children: [
28402
28450
  /* @__PURE__ */ jsx238(Button, { label: "Cancel", variant: "quaternary", onClick: onCancel }),
28403
28451
  onSaveAndExit && /* @__PURE__ */ jsx238(Button, { label: "Save & Exit", variant: "secondary", onClick: onSaveAndExit }),
28404
28452
  isLastStep ? /* @__PURE__ */ jsx238(Button, { label: completeLabel, variant: primaryVariant, onClick: onComplete, disabled: primaryDisabled }) : /* @__PURE__ */ jsx238(Button, { label: "Continue", variant: primaryVariant, onClick: async () => {
@@ -28410,7 +28458,7 @@ function WorkflowActions(props) {
28410
28458
 
28411
28459
  // src/layouts/Workflow/WorkflowPageLayout.tsx
28412
28460
  import { trussProps as trussProps137, mergeProps as mergeProps41, maybeCssVar as maybeCssVar69 } from "@homebound/truss/runtime";
28413
- import { jsx as jsx239, jsxs as jsxs125 } from "react/jsx-runtime";
28461
+ import { jsx as jsx239, jsxs as jsxs126 } from "react/jsx-runtime";
28414
28462
  var __maybeInc34 = (inc) => {
28415
28463
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
28416
28464
  };
@@ -28459,8 +28507,8 @@ function WorkflowPageLayout(props) {
28459
28507
  }
28460
28508
  };
28461
28509
  }, [showFooter]);
28462
- return /* @__PURE__ */ jsxs125(DocumentScrollLayoutProvider, { children: [
28463
- /* @__PURE__ */ jsxs125("div", { ...mergeProps41(void 0, cssVars, {
28510
+ return /* @__PURE__ */ jsxs126(DocumentScrollLayoutProvider, { children: [
28511
+ /* @__PURE__ */ jsxs126("div", { ...mergeProps41(void 0, cssVars, {
28464
28512
  display: "df",
28465
28513
  flexDirection: "fdc",
28466
28514
  width: "w100"
@@ -28534,7 +28582,7 @@ function WorkflowPageLayout(props) {
28534
28582
  }
28535
28583
 
28536
28584
  // src/layouts/Workflow/FocusedFormLayout.tsx
28537
- import { jsx as jsx240, jsxs as jsxs126 } from "react/jsx-runtime";
28585
+ import { jsx as jsx240, jsxs as jsxs127 } from "react/jsx-runtime";
28538
28586
  function FocusedFormLayout(props) {
28539
28587
  const {
28540
28588
  onCancel,
@@ -28561,7 +28609,7 @@ function FocusedFormLayout(props) {
28561
28609
  });
28562
28610
  const activeId = useActiveJumpLink(jumpLinks.map((link) => link.id));
28563
28611
  const showRail = withJumpLinks && jumpLinks.length >= 2 && !isMobile;
28564
- return /* @__PURE__ */ jsx240(WorkflowPageLayout, { ...tid, ...headerProps, aiMode, isDirty, onCancel, onSaveAndExit, completeLabel, onComplete, primaryDisabled: !isValid, children: /* @__PURE__ */ jsxs126("div", { className: "df w100", children: [
28612
+ return /* @__PURE__ */ jsx240(WorkflowPageLayout, { ...tid, ...headerProps, aiMode, isDirty, onCancel, onSaveAndExit, completeLabel, onComplete, primaryDisabled: !isValid, children: /* @__PURE__ */ jsxs127("div", { className: "df w100", children: [
28565
28613
  showRail && /* @__PURE__ */ jsx240(JumpLinksRail, { links: jumpLinks, activeId, ...tid.jumpLinks }),
28566
28614
  /* @__PURE__ */ jsx240("div", { className: "fg1 mw0 mb4", children: /* @__PURE__ */ jsx240(FormSectionLayout, { ...form, aiMode }) })
28567
28615
  ] }) });