@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.
- package/dist/components/Filters/MultiFilter.js +2 -2
- package/dist/components/internal/MenuItem.d.ts +1 -1
- package/dist/components/internal/MenuItem.js +3 -0
- package/dist/inputs/CheckboxBase.js +1 -1
- package/dist/inputs/DateFields/DateFieldBase.js +12 -8
- package/dist/inputs/MultiLineSelectField.d.ts +2 -2
- package/dist/inputs/MultiSelectField.d.ts +2 -2
- package/dist/inputs/MultiSelectField.js +2 -2
- package/dist/inputs/SelectField.d.ts +2 -2
- package/dist/inputs/SelectField.js +3 -3
- package/dist/inputs/TextFieldBase.d.ts +4 -0
- package/dist/inputs/TextFieldBase.js +5 -3
- package/dist/inputs/internal/{SelectFieldBase.d.ts → ComboBoxBase.d.ts} +4 -5
- package/dist/inputs/internal/{SelectFieldBase.js → ComboBoxBase.js} +8 -6
- package/dist/inputs/internal/{SelectFieldInput.d.ts → ComboBoxInput.d.ts} +2 -1
- package/dist/inputs/internal/{SelectFieldInput.js → ComboBoxInput.js} +3 -3
- package/dist/utils/index.js +3 -0
- package/package.json +3 -3
|
@@ -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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
49
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
3
|
+
import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
|
|
4
4
|
import { Optional } from "../types";
|
|
5
|
-
export interface MultiLineSelectFieldProps<O, V extends Value> extends Exclude<
|
|
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 {
|
|
3
|
+
import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
|
|
4
4
|
import { HasIdAndName, Optional } from "../types";
|
|
5
|
-
export interface MultiSelectFieldProps<O, V extends Value> extends Exclude<
|
|
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
|
|
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)(
|
|
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 {
|
|
3
|
+
import { ComboBoxBaseProps } from "./internal/ComboBoxBase";
|
|
4
4
|
import { HasIdAndName, Optional } from "../types";
|
|
5
|
-
export interface SelectFieldProps<O, V extends Value> extends Omit<
|
|
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
|
|
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)(
|
|
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 ===
|
|
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,
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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)(
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
102
|
+
exports.ComboBoxInput = ComboBoxInput;
|
package/dist/utils/index.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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",
|