@homebound/beam 2.261.0 → 2.263.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.
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.multiFilter = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const BaseFilter_1 = require("./BaseFilter");
6
- const SelectFieldBase_1 = require("../../inputs/internal/SelectFieldBase");
6
+ const ComboBoxBase_1 = require("../../inputs/internal/ComboBoxBase");
7
7
  const MultiSelectField_1 = require("../../inputs/MultiSelectField");
8
8
  const ToggleChipGroup_1 = require("../../inputs/ToggleChipGroup");
9
9
  const defaultTestId_1 = require("../../utils/defaultTestId");
@@ -16,7 +16,7 @@ class MultiFilter extends BaseFilter_1.BaseFilter {
16
16
  var _a;
17
17
  if (inModal && this.props.options.length > 0 && this.props.options.length <= 8) {
18
18
  const { disabledOptions } = this.props;
19
- const disabledOptionsWithReasons = Object.fromEntries((_a = disabledOptions === null || disabledOptions === void 0 ? void 0 : disabledOptions.map(SelectFieldBase_1.disabledOptionToKeyedTuple)) !== null && _a !== void 0 ? _a : []);
19
+ const disabledOptionsWithReasons = Object.fromEntries((_a = disabledOptions === null || disabledOptions === void 0 ? void 0 : disabledOptions.map(ComboBoxBase_1.disabledOptionToKeyedTuple)) !== null && _a !== void 0 ? _a : []);
20
20
  const disabledKeys = Object.keys(disabledOptionsWithReasons);
21
21
  return ((0, jsx_runtime_1.jsx)(ToggleChipGroup_1.ToggleChipGroup, { label: this.label, options: this.props.options.map((o) => {
22
22
  const value = this.props.getOptionValue(o);
@@ -7,5 +7,5 @@ interface MenuItemProps {
7
7
  onClose: VoidFunction;
8
8
  contrast: boolean;
9
9
  }
10
- export declare function MenuItemImpl(props: MenuItemProps): import("@emotion/react/jsx-runtime").JSX.Element;
10
+ export declare function MenuItemImpl(props: MenuItemProps): import("@emotion/react/jsx-runtime").JSX.Element | null;
11
11
  export {};
@@ -15,6 +15,9 @@ const defaultTestId_1 = require("../../utils/defaultTestId");
15
15
  function MenuItemImpl(props) {
16
16
  const { item, state, onClose, contrast } = props;
17
17
  const menuItem = item.value;
18
+ if (!menuItem) {
19
+ return null;
20
+ }
18
21
  const { disabled, onClick, label, destructive } = menuItem;
19
22
  const isDisabled = Boolean(disabled);
20
23
  const isSelected = state.selectionManager.selectedKeys.has(label);
@@ -23,7 +23,7 @@ function CheckboxBase(props) {
23
23
  .maxw((0, Css_1.px)(320))
24
24
  .if(description !== undefined)
25
25
  .maxw((0, Css_1.px)(344))
26
- .if(isDisabled).cursorNotAllowed.$, "aria-label": label, children: [(0, jsx_runtime_1.jsx)(react_aria_1.VisuallyHidden, { children: (0, jsx_runtime_1.jsx)("input", { ref: ref, ...(0, react_aria_1.mergeProps)(inputProps, focusProps), ...tid }) }), (0, jsx_runtime_1.jsx)("span", { ...hoverProps, css: {
26
+ .if(isDisabled).cursorNotAllowed.$, "aria-label": label, children: [(0, jsx_runtime_1.jsx)(react_aria_1.VisuallyHidden, { children: (0, jsx_runtime_1.jsx)("input", { ref: ref, ...(0, react_aria_1.mergeProps)(inputProps, focusProps), ...tid, "data-indeterminate": isIndeterminate }) }), (0, jsx_runtime_1.jsx)("span", { ...hoverProps, css: {
27
27
  ...baseStyles,
28
28
  ...(((isSelected && !isDisabled) || isIndeterminate) && filledBoxStyles),
29
29
  ...(((isSelected && !isDisabled) || isIndeterminate) && isHovered && filledBoxHoverStyles),
@@ -24,9 +24,9 @@ function DateFieldBase(props) {
24
24
  const inputWrapRef = (0, react_1.useRef)(null);
25
25
  const buttonRef = (0, react_1.useRef)(null);
26
26
  const overlayRef = (0, react_1.useRef)(null);
27
- // Local focus state to conditionally call onBlur when the date picker closes.
27
+ // Local focus ref to conditionally call onBlur when the date picker closes. Using a ref instead of a state to have a reliable value between renders
28
28
  // E.g. If the picker closes due to focus going back to the input field then don't call onBlur. Also used to avoid updating WIP values
29
- const [isFocused, setIsFocused] = (0, react_1.useState)(false);
29
+ const isFocused = (0, react_1.useRef)(false);
30
30
  const dateFormat = (0, utils_1.getDateFormat)(format);
31
31
  // The `wipValue` allows the "range" mode to set the value to `undefined`, even if the `onChange` response cannot be undefined.
32
32
  // This makes working within the DateRangePicker much more user friendly.
@@ -45,8 +45,9 @@ function DateFieldBase(props) {
45
45
  };
46
46
  const state = (0, react_stately_1.useOverlayTriggerState)({
47
47
  onOpenChange: (isOpen) => {
48
- // Handles calling `onBlur` for the case where the user interacts with the overlay, removing focus from the input field, and eventually closes the overlay (whether clicking away, or selecting a date)
49
- if (!isOpen && !isFocused) {
48
+ // Handles avoiding calling `onBlur` for the case where the user closes the overlay by changing the DateField input value (TextFieldBase.onChange calls state.close()).
49
+ // Calls `onBlur` for the case where the user interacts with the overlay (!isFocused) and eventually closes the overlay (whether clicking away, or selecting a date) as focus is not returned to the field.
50
+ if (!isOpen && !isFocused.current) {
50
51
  (0, utils_2.maybeCall)(onBlur);
51
52
  }
52
53
  },
@@ -57,8 +58,8 @@ function DateFieldBase(props) {
57
58
  onFocus: () => {
58
59
  var _a;
59
60
  // Open overlay on focus of the input.
61
+ isFocused.current = true;
60
62
  state.open();
61
- setIsFocused(true);
62
63
  (0, utils_2.maybeCall)(onFocus);
63
64
  if (wipValue && dateFormat !== utils_1.dateFormats.short) {
64
65
  // When focused, change to use the "short" date format, as it is simpler to update by hand and parse.
@@ -69,7 +70,7 @@ function DateFieldBase(props) {
69
70
  },
70
71
  onBlur: (e) => {
71
72
  var _a, _b;
72
- setIsFocused(false);
73
+ isFocused.current = false;
73
74
  // If we are interacting any other part of `inputWrap` ref (such as the calendar button) return early as clicking anywhere within there will push focus to the input field.
74
75
  // Or if interacting with the DatePicker then also return early. The overlay will handle calling `onBlur` once it closes.
75
76
  if ((inputWrapRef.current && inputWrapRef.current.contains(e.relatedTarget)) ||
@@ -89,7 +90,10 @@ function DateFieldBase(props) {
89
90
  setInputValue((_b = (isRangeMode ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _b !== void 0 ? _b : "");
90
91
  }
91
92
  state.close();
92
- (0, utils_2.maybeCall)(onBlur);
93
+ // Only call `onBlur` if the overlay is closed. In other cases, the overlay's `onOpenChange` will handling calling `onBlur` when closing and the focus is not still on the input.
94
+ if (!state.isOpen) {
95
+ (0, utils_2.maybeCall)(onBlur);
96
+ }
93
97
  },
94
98
  onKeyDown: (e) => {
95
99
  var _a;
@@ -121,7 +125,7 @@ function DateFieldBase(props) {
121
125
  (0, react_1.useEffect)(() => {
122
126
  var _a;
123
127
  // Avoid updating any WIP values.
124
- if (!isFocused && !state.isOpen) {
128
+ if (!isFocused.current && !state.isOpen) {
125
129
  setWipValue(value);
126
130
  setInputValue((_a = (isRangeMode ? (0, utils_1.formatDateRange)(props.value, dateFormat) : (0, utils_1.formatDate)(props.value, dateFormat))) !== null && _a !== void 0 ? _a : "");
127
131
  }
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import { Value } from "./";
3
- import { BeamSelectFieldBaseProps } from "./internal/SelectFieldBase";
3
+ import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
4
4
  import { Optional } from "../types";
5
- export interface MultiLineSelectFieldProps<O, V extends Value> extends Exclude<BeamSelectFieldBaseProps<O, V>, "unsetLabel"> {
5
+ export interface MultiLineSelectFieldProps<O, V extends Value> extends Exclude<ComboBoxBaseProps<O, V>, "unsetLabel"> {
6
6
  values: V[];
7
7
  options: O[];
8
8
  getOptionValue: (opt: O) => V;
@@ -1,8 +1,8 @@
1
1
  import { ReactNode } from "react";
2
2
  import { Value } from "./";
3
- import { BeamSelectFieldBaseProps } from "./internal/SelectFieldBase";
3
+ import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
4
4
  import { HasIdAndName, Optional } from "../types";
5
- export interface MultiSelectFieldProps<O, V extends Value> extends Exclude<BeamSelectFieldBaseProps<O, V>, "unsetLabel"> {
5
+ export interface MultiSelectFieldProps<O, V extends Value> extends Exclude<ComboBoxBaseProps<O, V>, "unsetLabel"> {
6
6
  /** Renders `opt` in the dropdown menu, defaults to the `getOptionLabel` prop. */
7
7
  getOptionMenuLabel?: (opt: O) => string | ReactNode;
8
8
  getOptionValue: (opt: O) => V;
@@ -2,12 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MultiSelectField = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
- const SelectFieldBase_1 = require("./internal/SelectFieldBase");
5
+ const ComboBoxBase_1 = require("./internal/ComboBoxBase");
6
6
  function MultiSelectField(props) {
7
7
  const { getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
8
8
  getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
9
9
  options, onSelect, values, ...otherProps } = props;
10
- return ((0, jsx_runtime_1.jsx)(SelectFieldBase_1.SelectFieldBase, { multiselect: true, ...otherProps, options: options, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, values: values, onSelect: (values) => {
10
+ return ((0, jsx_runtime_1.jsx)(ComboBoxBase_1.ComboBoxBase, { multiselect: true, ...otherProps, options: options, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, values: values, onSelect: (values) => {
11
11
  const [selectedValues, selectedOptions] = options
12
12
  .filter((o) => values.includes(getOptionValue(o)))
13
13
  .reduce((acc, o) => {
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import { Value } from "./";
3
- import { BeamSelectFieldBaseProps } from "./internal/SelectFieldBase";
3
+ import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
4
4
  import { HasIdAndName, Optional } from "../types";
5
- export interface SelectFieldProps<O, V extends Value> extends Omit<BeamSelectFieldBaseProps<O, V>, "values" | "onSelect"> {
5
+ export interface SelectFieldProps<O, V extends Value> extends Omit<ComboBoxBaseProps<O, V>, "values" | "onSelect" | "multiselect"> {
6
6
  /** The current value; it can be `undefined`, even if `V` cannot be. */
7
7
  value: V | undefined;
8
8
  onSelect: (value: V | undefined, opt: O | undefined) => void;
@@ -2,15 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SelectField = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
- const SelectFieldBase_1 = require("./internal/SelectFieldBase");
5
+ const ComboBoxBase_1 = require("./internal/ComboBoxBase");
6
6
  function SelectField(props) {
7
7
  const { getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
8
8
  getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
9
9
  options, onSelect, value, ...otherProps } = props;
10
- return ((0, jsx_runtime_1.jsx)(SelectFieldBase_1.SelectFieldBase, { ...otherProps, options: options, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, values: [value], onSelect: (values, options) => {
10
+ return ((0, jsx_runtime_1.jsx)(ComboBoxBase_1.ComboBoxBase, { ...otherProps, options: options, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, values: [value], onSelect: (values, options) => {
11
11
  if (values.length > 0 && options.length > 0) {
12
12
  const option = options[0];
13
- onSelect(values[0], option === SelectFieldBase_1.unsetOption ? undefined : option);
13
+ onSelect(values[0], option === ComboBoxBase_1.unsetOption ? undefined : option);
14
14
  }
15
15
  } }));
16
16
  }
@@ -17,5 +17,9 @@ export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "labe
17
17
  tooltip?: ReactNode;
18
18
  hideErrorMessage?: boolean;
19
19
  alwaysShowHelperText?: boolean;
20
+ /** Used by ComboBoxInput to decide whether we should allow the user to type to filter the options.
21
+ * This is admittedly a hack, as we really should not use a TextField at all in this instance. How we're currently implementing breaks all sorts of accessibility best practices.
22
+ * But for now it is the quickest way to get the desired behavior. Will updating to use a proper select field at another point. */
23
+ typeToFilter?: boolean;
20
24
  }
21
25
  export declare function TextFieldBase<X extends Only<TextFieldXss, X>>(props: TextFieldBaseProps<X>): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -18,7 +18,7 @@ const useTestIds_1 = require("../utils/useTestIds");
18
18
  function TextFieldBase(props) {
19
19
  var _a, _b, _c, _d, _e, _f, _g;
20
20
  const { fieldProps, wrap = false } = (0, PresentationContext_1.usePresentationContext)();
21
- const { label, required, labelProps, inputProps, inputRef, inputWrapRef, groupProps, compact = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _a !== void 0 ? _a : false, errorMsg, helperText, multiline = false, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, labelStyle = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.labelStyle) !== null && _b !== void 0 ? _b : "above", contrast = false, borderless = (_c = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.borderless) !== null && _c !== void 0 ? _c : false, textAreaMinHeight = 96, clearable = false, tooltip, visuallyDisabled = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.visuallyDisabled) !== null && _d !== void 0 ? _d : true, errorInTooltip = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.errorInTooltip) !== null && _e !== void 0 ? _e : false, hideErrorMessage = false, alwaysShowHelperText = false, } = props;
21
+ const { label, required, labelProps, inputProps, inputRef, inputWrapRef, groupProps, compact = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _a !== void 0 ? _a : false, errorMsg, helperText, multiline = false, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, labelStyle = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.labelStyle) !== null && _b !== void 0 ? _b : "above", contrast = false, borderless = (_c = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.borderless) !== null && _c !== void 0 ? _c : false, textAreaMinHeight = 96, clearable = false, tooltip, visuallyDisabled = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.visuallyDisabled) !== null && _d !== void 0 ? _d : true, errorInTooltip = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.errorInTooltip) !== null && _e !== void 0 ? _e : false, hideErrorMessage = false, alwaysShowHelperText = false, typeToFilter = true, } = props;
22
22
  const typeScale = (_f = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _f !== void 0 ? _f : (inputProps.readOnly && labelStyle !== "hidden" ? "smMd" : "sm");
23
23
  const internalProps = props.internalProps || {};
24
24
  const { compound = false, forceFocus = false, forceHover = false } = internalProps;
@@ -89,7 +89,7 @@ function TextFieldBase(props) {
89
89
  }
90
90
  }
91
91
  const onFocusChained = (0, react_aria_1.chain)((e) => {
92
- e.target.select();
92
+ typeToFilter && e.target.select();
93
93
  }, onFocus);
94
94
  const showFocus = (isFocused && !inputProps.readOnly) || forceFocus;
95
95
  const showHover = (isHovered && !inputProps.disabled && !inputProps.readOnly && !isFocused) || forceHover;
@@ -111,7 +111,9 @@ function TextFieldBase(props) {
111
111
  // Only show error styles if the field is not disabled, following the pattern that the error message is also hidden
112
112
  ...(errorMsg && !inputProps.disabled ? fieldStyles.error : {}),
113
113
  ...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
114
- }, ...hoverProps, ref: inputWrapRef, children: [!multiline && labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.fs0.br4.pr1.$, children: startAdornment }), (0, jsx_runtime_1.jsx)(ElementType, { ...(0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(labelStyle === "hidden" ? { "aria-label": label } : {}) }), ...(errorMsg ? { "aria-errormessage": errorMessageId } : {}), ref: fieldRef, rows: multiline ? 1 : undefined, css: {
114
+ }, ...hoverProps, ref: inputWrapRef, children: [!multiline && labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.fs0.br4.pr1.$, children: startAdornment }), (0, jsx_runtime_1.jsx)(ElementType, { ...(0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(labelStyle === "hidden" ? { "aria-label": label } : {}) }), ...(errorMsg ? { "aria-errormessage": errorMessageId } : {}), ref: fieldRef, rows: multiline ? 1 : undefined,
115
+ // Make the input field readOnly if the field explicitly sets it to `true`, otherwise base it on whether we should allow `typeToFilter`
116
+ readOnly: inputProps.readOnly || typeToFilter === false, css: {
115
117
  ...fieldStyles.input,
116
118
  ...(inputProps.disabled ? fieldStyles.disabled : {}),
117
119
  ...(showHover ? fieldStyles.hover : {}),
@@ -2,7 +2,7 @@ import React, { ReactNode } from "react";
2
2
  import { PresentationFieldProps } from "../../components/PresentationContext";
3
3
  import { Value } from "../Value";
4
4
  import { BeamFocusableProps } from "../../interfaces";
5
- export interface BeamSelectFieldBaseProps<O, V extends Value> extends BeamFocusableProps, PresentationFieldProps {
5
+ export interface ComboBoxBaseProps<O, V extends Value> extends BeamFocusableProps, PresentationFieldProps {
6
6
  /** Renders `opt` in the dropdown menu, defaults to the `getOptionLabel` prop. `isUnsetOpt` is only defined for single SelectField */
7
7
  getOptionMenuLabel?: (opt: O, isUnsetOpt?: boolean) => string | ReactNode;
8
8
  getOptionValue: (opt: O) => V;
@@ -40,7 +40,7 @@ export interface BeamSelectFieldBaseProps<O, V extends Value> extends BeamFocusa
40
40
  hideErrorMessage?: boolean;
41
41
  }
42
42
  /**
43
- * Provides a non-native select/dropdown widget.
43
+ * Provides a non-native select/dropdown widget that allows the user to type to filter the options.
44
44
  *
45
45
  * The `O` type is a list of options to show, the `V` is the primitive value of a
46
46
  * given `O` (i.e. it's id) that you want to use as the current/selected value.
@@ -48,8 +48,8 @@ export interface BeamSelectFieldBaseProps<O, V extends Value> extends BeamFocusa
48
48
  * Note that the `V extends Key` constraint come from react-aria,
49
49
  * and so we cannot easily change them.
50
50
  */
51
- export declare function SelectFieldBase<O, V extends Value>(props: BeamSelectFieldBaseProps<O, V>): JSX.Element;
52
- type OptionsOrLoad<O> = O[] | {
51
+ export declare function ComboBoxBase<O, V extends Value>(props: ComboBoxBaseProps<O, V>): JSX.Element;
52
+ export type OptionsOrLoad<O> = O[] | {
53
53
  initial: O[];
54
54
  load: () => Promise<{
55
55
  options: O[];
@@ -61,4 +61,3 @@ export declare function disabledOptionToKeyedTuple(disabledOption: Value | {
61
61
  value: Value;
62
62
  reason: string;
63
63
  }): [React.Key, string | undefined];
64
- export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.disabledOptionToKeyedTuple = exports.unsetOption = exports.initializeOptions = exports.SelectFieldBase = void 0;
3
+ exports.disabledOptionToKeyedTuple = exports.unsetOption = exports.initializeOptions = exports.ComboBoxBase = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
@@ -9,12 +9,12 @@ const components_1 = require("../../components");
9
9
  const internal_1 = require("../../components/internal");
10
10
  const PresentationContext_1 = require("../../components/PresentationContext");
11
11
  const Css_1 = require("../../Css");
12
+ const ComboBoxInput_1 = require("./ComboBoxInput");
12
13
  const ListBox_1 = require("./ListBox");
13
- const SelectFieldInput_1 = require("./SelectFieldInput");
14
14
  const Value_1 = require("../Value");
15
15
  const utils_1 = require("../../utils");
16
16
  /**
17
- * Provides a non-native select/dropdown widget.
17
+ * Provides a non-native select/dropdown widget that allows the user to type to filter the options.
18
18
  *
19
19
  * The `O` type is a list of options to show, the `V` is the primitive value of a
20
20
  * given `O` (i.e. it's id) that you want to use as the current/selected value.
@@ -22,7 +22,7 @@ const utils_1 = require("../../utils");
22
22
  * Note that the `V extends Key` constraint come from react-aria,
23
23
  * and so we cannot easily change them.
24
24
  */
25
- function SelectFieldBase(props) {
25
+ function ComboBoxBase(props) {
26
26
  var _a, _b, _c, _d;
27
27
  const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
28
28
  const { disabled, readOnly, onSelect, options, multiselect = false, values = [], nothingSelectedText = "", contrast, disabledOptions, borderless, unsetLabel, ...otherProps } = props;
@@ -250,9 +250,11 @@ function SelectFieldBase(props) {
250
250
  // Ensures the menu never gets too small.
251
251
  minWidth: 200,
252
252
  };
253
- return ((0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).if(labelStyle === "left").maxw100.$, ref: comboBoxRef, children: [(0, jsx_runtime_1.jsx)(SelectFieldInput_1.SelectFieldInput, { ...otherProps, buttonProps: buttonProps, buttonRef: triggerRef, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, state: state, labelProps: labelProps, selectedOptions: fieldState.selectedOptions, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, contrast: contrast, nothingSelectedText: nothingSelectedText, borderless: borderless, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly), resetField: resetField }), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, { triggerRef: triggerRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen, minWidth: 200, children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, { ...listBoxProps, positionProps: positionProps, state: state, listBoxRef: listBoxRef, selectedOptions: fieldState.selectedOptions, getOptionLabel: getOptionLabel, getOptionValue: (o) => (0, Value_1.valueToKey)(getOptionValue(o)), contrast: contrast, horizontalLayout: labelStyle === "left", loading: fieldState.optionsLoading, disabledOptionsWithReasons: disabledOptionsWithReasons }) }))] }));
253
+ return ((0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).if(labelStyle === "left").maxw100.$, ref: comboBoxRef, children: [(0, jsx_runtime_1.jsx)(ComboBoxInput_1.ComboBoxInput, { ...otherProps, buttonProps: buttonProps, buttonRef: triggerRef, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, state: state, labelProps: labelProps, selectedOptions: fieldState.selectedOptions, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, contrast: contrast, nothingSelectedText: nothingSelectedText, borderless: borderless, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly), resetField: resetField,
254
+ // If there are 10 or fewer options and it is not the multiselect, then we disable the typeahead filter for a better UX.
255
+ typeToFilter: !(!multiselect && Array.isArray(options) && options.length <= 10) }), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, { triggerRef: triggerRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen, minWidth: 200, children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, { ...listBoxProps, positionProps: positionProps, state: state, listBoxRef: listBoxRef, selectedOptions: fieldState.selectedOptions, getOptionLabel: getOptionLabel, getOptionValue: (o) => (0, Value_1.valueToKey)(getOptionValue(o)), contrast: contrast, horizontalLayout: labelStyle === "left", loading: fieldState.optionsLoading, disabledOptionsWithReasons: disabledOptionsWithReasons }) }))] }));
254
256
  }
255
- exports.SelectFieldBase = SelectFieldBase;
257
+ exports.ComboBoxBase = ComboBoxBase;
256
258
  function getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText) {
257
259
  return selectedOptions.length === 1
258
260
  ? getOptionLabel(selectedOptions[0])
@@ -26,6 +26,7 @@ interface SelectFieldInputProps<O, V extends Value> extends PresentationFieldPro
26
26
  tooltip?: ReactNode;
27
27
  resetField: VoidFunction;
28
28
  hideErrorMessage?: boolean;
29
+ typeToFilter: boolean;
29
30
  }
30
- export declare function SelectFieldInput<O, V extends Value>(props: SelectFieldInputProps<O, V>): import("@emotion/react/jsx-runtime").JSX.Element;
31
+ export declare function ComboBoxInput<O, V extends Value>(props: SelectFieldInputProps<O, V>): import("@emotion/react/jsx-runtime").JSX.Element;
31
32
  export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SelectFieldInput = void 0;
3
+ exports.ComboBoxInput = void 0;
4
4
  const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const react_aria_1 = require("react-aria");
@@ -8,7 +8,7 @@ const components_1 = require("../../components");
8
8
  const Css_1 = require("../../Css");
9
9
  const TextFieldBase_1 = require("../TextFieldBase");
10
10
  const utils_1 = require("../../utils");
11
- function SelectFieldInput(props) {
11
+ function ComboBoxInput(props) {
12
12
  const { inputProps, buttonProps, buttonRef, errorMsg, state, fieldDecoration, onBlur, onFocus, selectedOptions, getOptionValue, getOptionLabel, sizeToContent = false, contrast = false, nothingSelectedText, resetField, ...otherProps } = props;
13
13
  const [isFocused, setIsFocused] = (0, react_1.useState)(false);
14
14
  const isMultiSelect = state.selectionManager.selectionMode === "multiple";
@@ -99,4 +99,4 @@ function SelectFieldInput(props) {
99
99
  },
100
100
  } }));
101
101
  }
102
- exports.SelectFieldInput = SelectFieldInput;
102
+ exports.ComboBoxInput = ComboBoxInput;
@@ -37,6 +37,9 @@ function toGroupState(values, onChange) {
37
37
  toggleValue: (value) => (values.includes(value) ? addValue(value) : removeValue(value)),
38
38
  isDisabled: false,
39
39
  isReadOnly: false,
40
+ // We do not use the validation state, as our Switch groups do not support error states. However, this field is required by the `CheckboxGroupState` so we need to include it.
41
+ // If we ever update our SwitchGroup component to support error states, we'll need to update this.
42
+ validationState: "valid",
40
43
  };
41
44
  }
42
45
  exports.toGroupState = toGroupState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.261.0",
3
+ "version": "2.263.0",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -43,12 +43,12 @@
43
43
  "fast-deep-equal": "^3.1.3",
44
44
  "framer-motion": "^9.0.4",
45
45
  "memoize-one": "^5.2.1",
46
- "react-aria": "^3.18.0",
46
+ "react-aria": "^3.24.0",
47
47
  "react-day-picker": "8.0.7",
48
48
  "react-popper": "^2.3.0",
49
49
  "react-router": "^5.3.4",
50
50
  "react-router-dom": "^5.3.4",
51
- "react-stately": "^3.16.0",
51
+ "react-stately": "^3.22.0",
52
52
  "react-virtuoso": "2.10.2",
53
53
  "tributejs": "^5.1.3",
54
54
  "trix": "^1.3.1",