@homebound/beam 4.55.0 → 4.56.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
@@ -8732,6 +8732,8 @@ type MenuSelectFieldBaseProps<O, V extends Value> = {
8732
8732
  getOptionMenuLabel?: (opt: O) => ReactNode;
8733
8733
  /** Extra text the menu search matches, in addition to `getOptionLabel`. */
8734
8734
  getOptionSearchText?: (opt: O) => string | readonly string[];
8735
+ /** Sort options by `getOptionLabel`. On by default. `MenuTreeSelectField` defaults this to false. */
8736
+ autoSort?: boolean;
8735
8737
  /** Debounced menu search text. The caller replaces `options` and should keep the current selection in that list. Closing calls this with `""`. */
8736
8738
  onSearch?: (search: string) => void;
8737
8739
  disabledOptions?: (V | {
@@ -10266,6 +10268,7 @@ type WorkflowDestructiveAction = {
10266
10268
  confirmTitle?: ReactNode;
10267
10269
  confirmMessage?: ReactNode;
10268
10270
  };
10271
+ type WorkflowCompleteLabel = "Create" | "Save" | "Publish";
10269
10272
  type WorkflowActionsProps = {
10270
10273
  /** Leaves the workflow without saving. Always shown. */
10271
10274
  onCancel: (e: PressEvent) => void;
@@ -10273,10 +10276,12 @@ type WorkflowActionsProps = {
10273
10276
  onSaveAndExit?: (e: PressEvent) => void | Promise<void>;
10274
10277
  /** Destructive action on the workflow, rendered as a `danger` button before Continue/Complete. */
10275
10278
  destructiveAction?: WorkflowDestructiveAction;
10276
- /** Label for the completion button shown on the last step (or when there is no next step). */
10277
- completeLabel: "Create" | "Save";
10278
10279
  /** Called when the completion button is clicked. */
10279
10280
  onComplete: (e: PressEvent) => void | Promise<void>;
10281
+ /** `"Create"`, `"Save"`, or `"Publish"`. Defaults to `"Save"`. */
10282
+ completeLabel?: WorkflowCompleteLabel;
10283
+ /** One-off label. Wins over `completeLabel`. Confirm with product and/or design first. */
10284
+ nonStandardCompleteLabel?: string;
10280
10285
  /** Continue/Complete is disabled. A ReactNode is shown in Beam's tooltip. */
10281
10286
  primaryDisabled?: boolean | ReactNode;
10282
10287
  /** When true, Continue/Complete use the `ai` button variant instead of `primary`. */
@@ -11638,14 +11643,14 @@ type RightPaneTrigger = {
11638
11643
  /** The pending in-app navigation, as React Router reports it (pathnames are basename-stripped). */
11639
11644
  type AllowNavigationArgs = Parameters<BlockerFunction>[0];
11640
11645
 
11641
- type FocusedFormLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "completeLabel" | "onComplete" | "onSaveAndExit" | "destructiveAction"> & {
11642
- /** Create/Save is disabled. A ReactNode is shown in Beam's tooltip. */
11646
+ type FocusedFormLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "onComplete" | "onSaveAndExit" | "destructiveAction" | "completeLabel" | "nonStandardCompleteLabel"> & {
11647
+ /** Create/Save/Publish is disabled. A ReactNode is shown in Beam's tooltip. */
11643
11648
  primaryDisabled?: WorkflowActionsProps["primaryDisabled"];
11644
11649
  /** Read on Cancel / leave — a callback so flipping dirty does not re-render. */
11645
11650
  isDirty?: () => boolean;
11646
11651
  /** Consulted only while dirty — return true to allow a route change that stays on this form. */
11647
11652
  allowNavigation?: (args: AllowNavigationArgs) => boolean;
11648
- /** Full-bleed AI wash on the body and the `ai` Create/Save variant. Pair with body `aiMode` (e.g. FormSectionLayout). */
11653
+ /** Full-bleed AI wash on the body and the `ai` Create/Save/Publish variant. Pair with body `aiMode` (e.g. FormSectionLayout). */
11649
11654
  aiMode?: boolean;
11650
11655
  /** Icon triggers that open the document-scroll right pane. Hosts the pane — do not also set `withRightPane` on the body. */
11651
11656
  rightPaneTriggers?: RightPaneTrigger[];
@@ -11674,7 +11679,7 @@ type StepperLayoutStep = Omit<StepperTabsStep, "value" | "disabled"> & {
11674
11679
  /** Icon triggers for this step. Chrome is rendered by the workflow; the pane closes on step change. */
11675
11680
  rightPaneTriggers?: RightPaneTrigger[];
11676
11681
  };
11677
- type StepperLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "completeLabel" | "onComplete" | "onSaveAndExit" | "destructiveAction"> & {
11682
+ type StepperLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "onComplete" | "onSaveAndExit" | "destructiveAction" | "completeLabel" | "nonStandardCompleteLabel"> & {
11678
11683
  /** The workflow's steps; the active step's `content` is the body, and it drives the header's tab strip. */
11679
11684
  steps: StepperLayoutStep[];
11680
11685
  /** The step shown initially (matched against `defaultTestId(step.label)`); falls back to the first step if omitted or if it doesn't match any step. Uncontrolled — the layout owns step navigation from here. */
package/dist/index.d.ts CHANGED
@@ -8732,6 +8732,8 @@ type MenuSelectFieldBaseProps<O, V extends Value> = {
8732
8732
  getOptionMenuLabel?: (opt: O) => ReactNode;
8733
8733
  /** Extra text the menu search matches, in addition to `getOptionLabel`. */
8734
8734
  getOptionSearchText?: (opt: O) => string | readonly string[];
8735
+ /** Sort options by `getOptionLabel`. On by default. `MenuTreeSelectField` defaults this to false. */
8736
+ autoSort?: boolean;
8735
8737
  /** Debounced menu search text. The caller replaces `options` and should keep the current selection in that list. Closing calls this with `""`. */
8736
8738
  onSearch?: (search: string) => void;
8737
8739
  disabledOptions?: (V | {
@@ -10266,6 +10268,7 @@ type WorkflowDestructiveAction = {
10266
10268
  confirmTitle?: ReactNode;
10267
10269
  confirmMessage?: ReactNode;
10268
10270
  };
10271
+ type WorkflowCompleteLabel = "Create" | "Save" | "Publish";
10269
10272
  type WorkflowActionsProps = {
10270
10273
  /** Leaves the workflow without saving. Always shown. */
10271
10274
  onCancel: (e: PressEvent) => void;
@@ -10273,10 +10276,12 @@ type WorkflowActionsProps = {
10273
10276
  onSaveAndExit?: (e: PressEvent) => void | Promise<void>;
10274
10277
  /** Destructive action on the workflow, rendered as a `danger` button before Continue/Complete. */
10275
10278
  destructiveAction?: WorkflowDestructiveAction;
10276
- /** Label for the completion button shown on the last step (or when there is no next step). */
10277
- completeLabel: "Create" | "Save";
10278
10279
  /** Called when the completion button is clicked. */
10279
10280
  onComplete: (e: PressEvent) => void | Promise<void>;
10281
+ /** `"Create"`, `"Save"`, or `"Publish"`. Defaults to `"Save"`. */
10282
+ completeLabel?: WorkflowCompleteLabel;
10283
+ /** One-off label. Wins over `completeLabel`. Confirm with product and/or design first. */
10284
+ nonStandardCompleteLabel?: string;
10280
10285
  /** Continue/Complete is disabled. A ReactNode is shown in Beam's tooltip. */
10281
10286
  primaryDisabled?: boolean | ReactNode;
10282
10287
  /** When true, Continue/Complete use the `ai` button variant instead of `primary`. */
@@ -11638,14 +11643,14 @@ type RightPaneTrigger = {
11638
11643
  /** The pending in-app navigation, as React Router reports it (pathnames are basename-stripped). */
11639
11644
  type AllowNavigationArgs = Parameters<BlockerFunction>[0];
11640
11645
 
11641
- type FocusedFormLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "completeLabel" | "onComplete" | "onSaveAndExit" | "destructiveAction"> & {
11642
- /** Create/Save is disabled. A ReactNode is shown in Beam's tooltip. */
11646
+ type FocusedFormLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "onComplete" | "onSaveAndExit" | "destructiveAction" | "completeLabel" | "nonStandardCompleteLabel"> & {
11647
+ /** Create/Save/Publish is disabled. A ReactNode is shown in Beam's tooltip. */
11643
11648
  primaryDisabled?: WorkflowActionsProps["primaryDisabled"];
11644
11649
  /** Read on Cancel / leave — a callback so flipping dirty does not re-render. */
11645
11650
  isDirty?: () => boolean;
11646
11651
  /** Consulted only while dirty — return true to allow a route change that stays on this form. */
11647
11652
  allowNavigation?: (args: AllowNavigationArgs) => boolean;
11648
- /** Full-bleed AI wash on the body and the `ai` Create/Save variant. Pair with body `aiMode` (e.g. FormSectionLayout). */
11653
+ /** Full-bleed AI wash on the body and the `ai` Create/Save/Publish variant. Pair with body `aiMode` (e.g. FormSectionLayout). */
11649
11654
  aiMode?: boolean;
11650
11655
  /** Icon triggers that open the document-scroll right pane. Hosts the pane — do not also set `withRightPane` on the body. */
11651
11656
  rightPaneTriggers?: RightPaneTrigger[];
@@ -11674,7 +11679,7 @@ type StepperLayoutStep = Omit<StepperTabsStep, "value" | "disabled"> & {
11674
11679
  /** Icon triggers for this step. Chrome is rendered by the workflow; the pane closes on step change. */
11675
11680
  rightPaneTriggers?: RightPaneTrigger[];
11676
11681
  };
11677
- type StepperLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "completeLabel" | "onComplete" | "onSaveAndExit" | "destructiveAction"> & {
11682
+ type StepperLayoutProps = Pick<BaseHeaderProps, "title" | "documentTitleSuffix" | "breadcrumbs"> & Pick<WorkflowActionsProps, "onCancel" | "onComplete" | "onSaveAndExit" | "destructiveAction" | "completeLabel" | "nonStandardCompleteLabel"> & {
11678
11683
  /** The workflow's steps; the active step's `content` is the body, and it drives the header's tab strip. */
11679
11684
  steps: StepperLayoutStep[];
11680
11685
  /** The step shown initially (matched against `defaultTestId(step.label)`); falls back to the first step if omitted or if it doesn't match any step. Uncontrolled — the layout owns step navigation from here. */
package/dist/index.js CHANGED
@@ -19919,6 +19919,7 @@ function useMenuSelectField(props) {
19919
19919
  getOptionLabel = defaultOptionLabel,
19920
19920
  getOptionMenuLabel,
19921
19921
  getOptionSearchText,
19922
+ autoSort = true,
19922
19923
  onSearch,
19923
19924
  disabledOptions,
19924
19925
  nothingSelectedText = "",
@@ -19961,10 +19962,10 @@ function useMenuSelectField(props) {
19961
19962
  const [optionsLoading, setOptionsLoading] = useState31(false);
19962
19963
  const didRequestOptionsRef = useRef36(false);
19963
19964
  const options = useMemo28(
19964
- () => initializeOptions(optionsProp, getOptionValue, getOptionLabel, void 0, false),
19965
+ () => initializeOptions(optionsProp, getOptionValue, getOptionLabel, void 0, autoSort),
19965
19966
  // getOptionValue and getOptionLabel are typically inline lambdas
19966
19967
  // oxlint-disable-next-line react-hooks/exhaustive-deps
19967
- [optionsProp]
19968
+ [optionsProp, autoSort]
19968
19969
  );
19969
19970
  const { hoverProps, isHovered } = useHover13({});
19970
19971
  const { focusProps, isFocusVisible } = useFocusRing10();
@@ -21824,11 +21825,12 @@ import { Observer as Observer8 } from "mobx-react";
21824
21825
  // src/inputs/MenuSelectField/MenuTreeSelectField.tsx
21825
21826
  import { jsx as jsx140 } from "react/jsx-runtime";
21826
21827
  function MenuTreeSelectField(props) {
21827
- const { onSelect, selectionDisplay = "all", defaultExpanded = false, ...rest } = props;
21828
+ const { onSelect, selectionDisplay = "all", defaultExpanded = false, autoSort = false, ...rest } = props;
21828
21829
  return /* @__PURE__ */ jsx140(
21829
21830
  BaseMenuSelectField,
21830
21831
  {
21831
21832
  ...rest,
21833
+ autoSort,
21832
21834
  selectionMode: "multiple",
21833
21835
  tree: { getChildren: getNestedChildren, display: selectionDisplay, defaultExpanded },
21834
21836
  onCommit: (values, opts) => onSelect(treeSelectResponse(values, opts))
@@ -31508,14 +31510,19 @@ var SingleFilter = class extends BaseFilter {
31508
31510
  return resolveOptionSelectedFilterLabel(options, getOptionValue, getOptionLabel, value);
31509
31511
  }
31510
31512
  render(value, setValue, tid, inModal, vertical) {
31511
- const { label, defaultValue, options: maybeOptions, nothingSelectedText, ...props } = this.props;
31513
+ const { label, defaultValue, options: maybeOptions, nothingSelectedText, autoSort, ...props } = this.props;
31512
31514
  const { getOptionValue, getOptionLabel } = optionReaders2(this.props);
31513
31515
  const unsetText = nothingSelectedText ?? "All";
31514
- const options = Array.isArray(maybeOptions) ? [allOption, ...maybeOptions] : { ...maybeOptions, current: maybeOptions.current };
31516
+ const isStaticList = Array.isArray(maybeOptions);
31517
+ const options = isStaticList ? [
31518
+ allOption,
31519
+ ...initializeOptions(maybeOptions, getOptionValue, getOptionLabel, void 0, autoSort ?? true)
31520
+ ] : maybeOptions;
31515
31521
  return /* @__PURE__ */ jsx241(
31516
31522
  MenuSelectField,
31517
31523
  {
31518
31524
  ...props,
31525
+ autoSort: isStaticList ? false : autoSort,
31519
31526
  options,
31520
31527
  getOptionValue: (option) => option === allOption ? void 0 : getOptionValue(option),
31521
31528
  getOptionLabel: (option) => option === allOption ? unsetText : getOptionLabel(option),
@@ -33938,26 +33945,28 @@ function WorkflowActions(props) {
33938
33945
  onCancel,
33939
33946
  onSaveAndExit,
33940
33947
  destructiveAction,
33941
- completeLabel,
33942
33948
  onComplete,
33943
33949
  primaryDisabled,
33944
33950
  aiMode = false,
33945
33951
  isFirstStep = true,
33946
33952
  isLastStep = true,
33947
33953
  onBack,
33948
- onContinue
33954
+ onContinue,
33955
+ completeLabel,
33956
+ nonStandardCompleteLabel
33949
33957
  } = props;
33950
33958
  const {
33951
33959
  sm: isMobile
33952
33960
  } = useBreakpoint();
33953
33961
  const primaryVariant = aiMode ? "ai" : "primary";
33962
+ const completeButtonLabel = nonStandardCompleteLabel ?? completeLabel ?? "Save";
33954
33963
  return /* @__PURE__ */ jsxs147("div", { className: "df aic jcsb sm_w100", children: [
33955
33964
  /* @__PURE__ */ jsx273("div", { className: "df aic", children: !isFirstStep && isMobile && onBack && /* @__PURE__ */ jsx273(IconButton, { icon: "arrowBack", label: "Back", onClick: onBack }) }),
33956
33965
  /* @__PURE__ */ jsxs147("div", { className: "df aic g_1", children: [
33957
33966
  /* @__PURE__ */ jsx273(Button, { label: "Cancel", variant: "quaternary", onClick: onCancel }),
33958
33967
  onSaveAndExit && /* @__PURE__ */ jsx273(Button, { label: "Save & Exit", variant: "secondary", onClick: onSaveAndExit }),
33959
33968
  destructiveAction && /* @__PURE__ */ jsx273(Button, { label: destructiveAction.label ?? "Remove", variant: "danger", onClick: destructiveAction.onConfirm }),
33960
- isLastStep ? /* @__PURE__ */ jsx273(Button, { label: completeLabel, variant: primaryVariant, onClick: onComplete, disabled: primaryDisabled }) : /* @__PURE__ */ jsx273(Button, { label: "Continue", variant: primaryVariant, onClick: async () => {
33969
+ isLastStep ? /* @__PURE__ */ jsx273(Button, { label: completeButtonLabel, variant: primaryVariant, onClick: onComplete, disabled: primaryDisabled }) : /* @__PURE__ */ jsx273(Button, { label: "Continue", variant: primaryVariant, onClick: async () => {
33961
33970
  await onContinue?.();
33962
33971
  }, disabled: primaryDisabled })
33963
33972
  ] })
@@ -33985,7 +33994,15 @@ function WorkflowPageLayout(props) {
33985
33994
  destructiveAction,
33986
33995
  rightPaneTriggers,
33987
33996
  banner: bannerProp,
33988
- ...actionProps
33997
+ onSaveAndExit,
33998
+ onComplete,
33999
+ primaryDisabled,
34000
+ isFirstStep,
34001
+ isLastStep,
34002
+ onBack,
34003
+ onContinue,
34004
+ completeLabel,
34005
+ nonStandardCompleteLabel
33989
34006
  } = props;
33990
34007
  const tid = useTestIds(props, "workflowPageLayout");
33991
34008
  const {
@@ -34005,7 +34022,7 @@ function WorkflowPageLayout(props) {
34005
34022
  onCancel,
34006
34023
  destructiveAction
34007
34024
  });
34008
- const actions = /* @__PURE__ */ jsx274(WorkflowActions, { ...actionProps, aiMode, onCancel: onCancelClick, destructiveAction: destructiveAction && {
34025
+ const actions = /* @__PURE__ */ jsx274(WorkflowActions, { completeLabel, nonStandardCompleteLabel, onSaveAndExit, onComplete, primaryDisabled, isFirstStep, isLastStep, onBack, onContinue, aiMode, onCancel: onCancelClick, destructiveAction: destructiveAction && {
34009
34026
  ...destructiveAction,
34010
34027
  onConfirm: onDestructiveActionClick
34011
34028
  } });
@@ -34133,7 +34150,6 @@ import { jsx as jsx275 } from "react/jsx-runtime";
34133
34150
  function FocusedFormLayout(props) {
34134
34151
  const {
34135
34152
  onCancel,
34136
- completeLabel,
34137
34153
  onComplete,
34138
34154
  onSaveAndExit,
34139
34155
  destructiveAction,
@@ -34144,14 +34160,20 @@ function FocusedFormLayout(props) {
34144
34160
  rightPaneTriggers,
34145
34161
  banner,
34146
34162
  children,
34147
- ...headerProps
34163
+ title,
34164
+ documentTitleSuffix,
34165
+ breadcrumbs,
34166
+ completeLabel,
34167
+ nonStandardCompleteLabel
34148
34168
  } = props;
34149
34169
  const tid = useTestIds(props, "focusedFormLayout");
34150
34170
  return /* @__PURE__ */ jsx275(
34151
34171
  WorkflowPageLayout,
34152
34172
  {
34153
34173
  ...tid,
34154
- ...headerProps,
34174
+ title,
34175
+ documentTitleSuffix,
34176
+ breadcrumbs,
34155
34177
  banner,
34156
34178
  aiMode,
34157
34179
  isDirty,
@@ -34160,6 +34182,7 @@ function FocusedFormLayout(props) {
34160
34182
  onSaveAndExit,
34161
34183
  destructiveAction,
34162
34184
  completeLabel,
34185
+ nonStandardCompleteLabel,
34163
34186
  onComplete,
34164
34187
  primaryDisabled,
34165
34188
  rightPaneTriggers,
@@ -34176,7 +34199,6 @@ function StepperLayout(props) {
34176
34199
  steps,
34177
34200
  defaultStep,
34178
34201
  onCancel,
34179
- completeLabel,
34180
34202
  onComplete,
34181
34203
  onSaveAndExit,
34182
34204
  destructiveAction,
@@ -34184,7 +34206,11 @@ function StepperLayout(props) {
34184
34206
  allowNavigation,
34185
34207
  aiMode,
34186
34208
  banner,
34187
- ...headerProps
34209
+ title,
34210
+ documentTitleSuffix,
34211
+ breadcrumbs,
34212
+ completeLabel,
34213
+ nonStandardCompleteLabel
34188
34214
  } = props;
34189
34215
  const stepTabs = steps.map((step) => ({ ...step, value: defaultTestId(step.label) }));
34190
34216
  const [currentStep, setCurrentStep] = useState72(() => getInitialStep(stepTabs, defaultStep));
@@ -34201,7 +34227,9 @@ function StepperLayout(props) {
34201
34227
  WorkflowPageLayout,
34202
34228
  {
34203
34229
  ...tid,
34204
- ...headerProps,
34230
+ title,
34231
+ documentTitleSuffix,
34232
+ breadcrumbs,
34205
34233
  banner,
34206
34234
  aiMode,
34207
34235
  stepperTabs: { steps: stepTabs, currentStep, onChange: goToStep },
@@ -34217,6 +34245,7 @@ function StepperLayout(props) {
34217
34245
  onSaveAndExit,
34218
34246
  destructiveAction,
34219
34247
  completeLabel,
34248
+ nonStandardCompleteLabel,
34220
34249
  onComplete,
34221
34250
  primaryDisabled: activeStep?.primaryDisabled,
34222
34251
  rightPaneTriggers: activeStep?.rightPaneTriggers,