@homebound/beam 3.101.1 → 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
@@ -28171,14 +28213,19 @@ function BaseHeader(props) {
28171
28213
 
28172
28214
  // src/components/Headers/PageHeader.tsx
28173
28215
  import { trussProps as trussProps135 } from "@homebound/truss/runtime";
28174
- import { jsx as jsx233 } from "react/jsx-runtime";
28216
+ import { Fragment as Fragment51, jsx as jsx233, jsxs as jsxs123 } from "react/jsx-runtime";
28175
28217
  function PageHeader2(props) {
28176
28218
  const {
28177
28219
  tabs,
28220
+ actions,
28221
+ rightSlot,
28178
28222
  ...otherProps
28179
28223
  } = props;
28180
28224
  const tid = useTestIds(otherProps, "header");
28181
- 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 }) }) });
28182
28229
  }
28183
28230
 
28184
28231
  // src/layouts/useBannerAndNavbarHeight.ts
@@ -28188,7 +28235,7 @@ function useBannerAndNavbarHeight() {
28188
28235
 
28189
28236
  // src/layouts/PageHeaderLayout/PageHeaderLayout.tsx
28190
28237
  import { mergeProps as mergeProps40, maybeCssVar as maybeCssVar67 } from "@homebound/truss/runtime";
28191
- import { jsx as jsx234, jsxs as jsxs123 } from "react/jsx-runtime";
28238
+ import { jsx as jsx234, jsxs as jsxs124 } from "react/jsx-runtime";
28192
28239
  var __maybeInc32 = (inc) => {
28193
28240
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
28194
28241
  };
@@ -28244,7 +28291,7 @@ function PageHeaderLayout(props) {
28244
28291
  top: autoHideState === "revealed" ? outerTop : `calc(${outerTop} - ${headerHeight}px)`
28245
28292
  } : void 0;
28246
28293
  const pageHeaderEl = useMemo58(() => /* @__PURE__ */ jsx234(PageHeader2, { ...pageHeader }), [pageHeader]);
28247
- 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, {
28248
28295
  display: "df",
28249
28296
  flexDirection: "fdc",
28250
28297
  width: "w100"
@@ -28379,7 +28426,7 @@ function UnsavedChangesNavigationModal(props) {
28379
28426
  }
28380
28427
 
28381
28428
  // src/layouts/Workflow/WorkflowActions.tsx
28382
- import { jsx as jsx238, jsxs as jsxs124 } from "react/jsx-runtime";
28429
+ import { jsx as jsx238, jsxs as jsxs125 } from "react/jsx-runtime";
28383
28430
  function WorkflowActions(props) {
28384
28431
  const {
28385
28432
  onCancel,
@@ -28397,9 +28444,9 @@ function WorkflowActions(props) {
28397
28444
  sm: isMobile
28398
28445
  } = useBreakpoint();
28399
28446
  const primaryVariant = aiMode ? "ai" : "primary";
28400
- return /* @__PURE__ */ jsxs124("div", { className: "df aic jcsb sm_w100", children: [
28447
+ return /* @__PURE__ */ jsxs125("div", { className: "df aic jcsb sm_w100", children: [
28401
28448
  /* @__PURE__ */ jsx238("div", { className: "df aic", children: !isFirstStep && isMobile && onBack && /* @__PURE__ */ jsx238(IconButton, { icon: "arrowBack", label: "Back", onClick: onBack }) }),
28402
- /* @__PURE__ */ jsxs124("div", { className: "df aic gap1", children: [
28449
+ /* @__PURE__ */ jsxs125("div", { className: "df aic gap1", children: [
28403
28450
  /* @__PURE__ */ jsx238(Button, { label: "Cancel", variant: "quaternary", onClick: onCancel }),
28404
28451
  onSaveAndExit && /* @__PURE__ */ jsx238(Button, { label: "Save & Exit", variant: "secondary", onClick: onSaveAndExit }),
28405
28452
  isLastStep ? /* @__PURE__ */ jsx238(Button, { label: completeLabel, variant: primaryVariant, onClick: onComplete, disabled: primaryDisabled }) : /* @__PURE__ */ jsx238(Button, { label: "Continue", variant: primaryVariant, onClick: async () => {
@@ -28411,7 +28458,7 @@ function WorkflowActions(props) {
28411
28458
 
28412
28459
  // src/layouts/Workflow/WorkflowPageLayout.tsx
28413
28460
  import { trussProps as trussProps137, mergeProps as mergeProps41, maybeCssVar as maybeCssVar69 } from "@homebound/truss/runtime";
28414
- import { jsx as jsx239, jsxs as jsxs125 } from "react/jsx-runtime";
28461
+ import { jsx as jsx239, jsxs as jsxs126 } from "react/jsx-runtime";
28415
28462
  var __maybeInc34 = (inc) => {
28416
28463
  return typeof inc === "string" ? inc : `calc(var(--t-spacing) * ${inc})`;
28417
28464
  };
@@ -28460,8 +28507,8 @@ function WorkflowPageLayout(props) {
28460
28507
  }
28461
28508
  };
28462
28509
  }, [showFooter]);
28463
- return /* @__PURE__ */ jsxs125(DocumentScrollLayoutProvider, { children: [
28464
- /* @__PURE__ */ jsxs125("div", { ...mergeProps41(void 0, cssVars, {
28510
+ return /* @__PURE__ */ jsxs126(DocumentScrollLayoutProvider, { children: [
28511
+ /* @__PURE__ */ jsxs126("div", { ...mergeProps41(void 0, cssVars, {
28465
28512
  display: "df",
28466
28513
  flexDirection: "fdc",
28467
28514
  width: "w100"
@@ -28535,7 +28582,7 @@ function WorkflowPageLayout(props) {
28535
28582
  }
28536
28583
 
28537
28584
  // src/layouts/Workflow/FocusedFormLayout.tsx
28538
- import { jsx as jsx240, jsxs as jsxs126 } from "react/jsx-runtime";
28585
+ import { jsx as jsx240, jsxs as jsxs127 } from "react/jsx-runtime";
28539
28586
  function FocusedFormLayout(props) {
28540
28587
  const {
28541
28588
  onCancel,
@@ -28562,7 +28609,7 @@ function FocusedFormLayout(props) {
28562
28609
  });
28563
28610
  const activeId = useActiveJumpLink(jumpLinks.map((link) => link.id));
28564
28611
  const showRail = withJumpLinks && jumpLinks.length >= 2 && !isMobile;
28565
- 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: [
28566
28613
  showRail && /* @__PURE__ */ jsx240(JumpLinksRail, { links: jumpLinks, activeId, ...tid.jumpLinks }),
28567
28614
  /* @__PURE__ */ jsx240("div", { className: "fg1 mw0 mb4", children: /* @__PURE__ */ jsx240(FormSectionLayout, { ...form, aiMode }) })
28568
28615
  ] }) });