@homebound/beam 2.119.0 → 2.121.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/IconButton.d.ts +5 -0
- package/dist/components/IconButton.js +8 -4
- package/dist/components/Table/RowState.js +2 -0
- package/dist/inputs/DateField.d.ts +3 -1
- package/dist/inputs/DateField.js +6 -5
- package/dist/inputs/DateField.mock.js +1 -1
- package/dist/inputs/MultiSelectField.mock.js +3 -2
- package/dist/inputs/NumberField.d.ts +3 -2
- package/dist/inputs/NumberField.js +7 -4
- package/dist/inputs/SelectField.mock.js +3 -2
- package/dist/inputs/TextAreaField.js +5 -2
- package/dist/inputs/TextField.js +6 -3
- package/dist/inputs/TextFieldBase.d.ts +1 -1
- package/dist/inputs/TextFieldBase.js +5 -5
- package/dist/inputs/internal/SelectFieldInput.js +1 -1
- package/dist/interfaces.d.ts +4 -3
- package/package.json +1 -1
|
@@ -14,8 +14,13 @@ export interface IconButtonProps extends BeamButtonProps, BeamFocusableProps {
|
|
|
14
14
|
buttonRef?: RefObject<HTMLButtonElement>;
|
|
15
15
|
/** Whether to show a 16x16px version of the IconButton */
|
|
16
16
|
compact?: boolean;
|
|
17
|
+
/** Whether to display the contrast variant */
|
|
18
|
+
contrast?: boolean;
|
|
17
19
|
}
|
|
18
20
|
export declare function IconButton(props: IconButtonProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
19
21
|
export declare const iconButtonStylesHover: {
|
|
20
22
|
backgroundColor: import("csstype").Property.BackgroundColor | undefined;
|
|
21
23
|
};
|
|
24
|
+
export declare const iconButtonContrastStylesHover: {
|
|
25
|
+
backgroundColor: import("csstype").Property.BackgroundColor | undefined;
|
|
26
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.iconButtonStylesHover = exports.IconButton = void 0;
|
|
3
|
+
exports.iconButtonContrastStylesHover = exports.iconButtonStylesHover = exports.IconButton = 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");
|
|
@@ -10,7 +10,7 @@ const Css_1 = require("../Css");
|
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
12
12
|
function IconButton(props) {
|
|
13
|
-
const { onClick: onPress, disabled, color, icon, autoFocus, inc, buttonRef, tooltip, menuTriggerProps, openInNew, compact = false, } = props;
|
|
13
|
+
const { onClick: onPress, disabled, color, icon, autoFocus, inc, buttonRef, tooltip, menuTriggerProps, openInNew, compact = false, contrast = false, } = props;
|
|
14
14
|
const isDisabled = !!disabled;
|
|
15
15
|
const ariaProps = { onPress, isDisabled, autoFocus, ...menuTriggerProps };
|
|
16
16
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
@@ -26,12 +26,13 @@ function IconButton(props) {
|
|
|
26
26
|
const styles = (0, react_1.useMemo)(() => ({
|
|
27
27
|
...iconButtonStylesReset,
|
|
28
28
|
...(compact ? iconButtonCompact : iconButtonNormal),
|
|
29
|
-
...(isHovered && exports.iconButtonStylesHover),
|
|
29
|
+
...(isHovered && (contrast ? exports.iconButtonContrastStylesHover : exports.iconButtonStylesHover)),
|
|
30
30
|
...(isFocusVisible && iconButtonStylesFocus),
|
|
31
31
|
...(isDisabled && iconButtonStylesDisabled),
|
|
32
32
|
}), [isHovered, isFocusVisible, isDisabled, compact]);
|
|
33
|
+
const iconColor = contrast ? contrastIconColor : defaultIconColor;
|
|
33
34
|
const buttonAttrs = { ...testIds, ...buttonProps, ...focusProps, ...hoverProps, ref: ref, css: styles };
|
|
34
|
-
const buttonContent = ((0, jsx_runtime_1.jsx)(components_1.Icon, { icon: icon, color: color || (isDisabled ? Css_1.Palette.Gray400 :
|
|
35
|
+
const buttonContent = ((0, jsx_runtime_1.jsx)(components_1.Icon, { icon: icon, color: color || (isDisabled ? Css_1.Palette.Gray400 : iconColor), inc: compact ? 2 : inc }, void 0));
|
|
35
36
|
const button = typeof onPress === "string" ? ((0, utils_1.isAbsoluteUrl)(onPress) || openInNew ? ((0, jsx_runtime_1.jsx)("a", Object.assign({}, buttonAttrs, { href: onPress, className: components_1.navLink, target: "_blank", rel: "noreferrer noopener" }, { children: buttonContent }), void 0)) : ((0, jsx_runtime_1.jsx)(react_router_dom_1.Link, Object.assign({}, buttonAttrs, { to: onPress, className: components_1.navLink }, { children: buttonContent }), void 0))) : ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonAttrs, { children: buttonContent }), void 0));
|
|
36
37
|
// If we're disabled b/c of a non-boolean ReactNode, or the caller specified tooltip text, then show it in a tooltip
|
|
37
38
|
return (0, components_1.maybeTooltip)({
|
|
@@ -41,9 +42,12 @@ function IconButton(props) {
|
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
exports.IconButton = IconButton;
|
|
45
|
+
const defaultIconColor = Css_1.Palette.Gray900;
|
|
46
|
+
const contrastIconColor = Css_1.Palette.White;
|
|
44
47
|
const iconButtonStylesReset = Css_1.Css.bTransparent.bsSolid.bgTransparent.cursorPointer.outline0.dif.aic.jcc.transition.$;
|
|
45
48
|
const iconButtonNormal = Css_1.Css.hPx(28).wPx(28).br8.bw2.$;
|
|
46
49
|
const iconButtonCompact = Css_1.Css.hPx(18).wPx(18).br4.bw1.$;
|
|
47
50
|
exports.iconButtonStylesHover = Css_1.Css.bgGray200.$;
|
|
51
|
+
exports.iconButtonContrastStylesHover = Css_1.Css.bgGray700.$;
|
|
48
52
|
const iconButtonStylesFocus = Css_1.Css.bLightBlue700.$;
|
|
49
53
|
const iconButtonStylesDisabled = Css_1.Css.cursorNotAllowed.$;
|
|
@@ -34,6 +34,8 @@ class RowState {
|
|
|
34
34
|
this.visibleRows = new mobx_1.ObservableSet();
|
|
35
35
|
// The current list of rows, basically a useRef.current. Not reactive.
|
|
36
36
|
this.rows = [];
|
|
37
|
+
// Keeps track of the 'active' row, formatted `${row.kind}_${row.id}`
|
|
38
|
+
this.activeRowId = undefined;
|
|
37
39
|
// Make ourselves an observable so that mobx will do caching of .collapseIds so
|
|
38
40
|
// that it'll be a stable identity for GridTable to useMemo against.
|
|
39
41
|
(0, mobx_1.makeAutoObservable)(this, { rows: false }); // as any b/c rows is private, so the mapped type doesn't see it
|
|
@@ -10,10 +10,12 @@ export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless
|
|
|
10
10
|
onBlur?: () => void;
|
|
11
11
|
/** Called when the component is in focus. */
|
|
12
12
|
onFocus?: () => void;
|
|
13
|
+
/** Whether the field is disabled. If a ReactNode, it's treated as a "disabled reason" that's shown in a tooltip. */
|
|
13
14
|
disabled?: boolean | ReactNode;
|
|
14
15
|
errorMsg?: string;
|
|
15
16
|
required?: boolean;
|
|
16
|
-
readOnly
|
|
17
|
+
/** Whether the field is readOnly. If a ReactNode, it's treated as a "readOnly reason" that's shown in a tooltip. */
|
|
18
|
+
readOnly?: boolean | ReactNode;
|
|
17
19
|
helperText?: string | ReactNode;
|
|
18
20
|
/** Renders the label inside the input field, i.e. for filters. */
|
|
19
21
|
inlineLabel?: boolean;
|
package/dist/inputs/DateField.js
CHANGED
|
@@ -15,7 +15,7 @@ const TextFieldBase_1 = require("./TextFieldBase");
|
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
17
17
|
function DateField(props) {
|
|
18
|
-
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly
|
|
18
|
+
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly, format = "short", iconLeft = false, disabledDays, onEnter, defaultOpen, ...others } = props;
|
|
19
19
|
const inputRef = (0, react_1.useRef)(null);
|
|
20
20
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
21
21
|
const buttonRef = (0, react_1.useRef)(null);
|
|
@@ -26,6 +26,7 @@ function DateField(props) {
|
|
|
26
26
|
const [inputValue, setInputValue] = (0, react_1.useState)(value ? formatDate(value, dateFormat) : "");
|
|
27
27
|
const tid = (0, utils_1.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
|
|
28
28
|
const isDisabled = !!disabled;
|
|
29
|
+
const isReadOnly = !!readOnly;
|
|
29
30
|
(0, react_1.useEffect)(() => {
|
|
30
31
|
// Avoid updating any WIP values.
|
|
31
32
|
if (!isFocused) {
|
|
@@ -36,7 +37,7 @@ function DateField(props) {
|
|
|
36
37
|
...others,
|
|
37
38
|
label,
|
|
38
39
|
isDisabled,
|
|
39
|
-
isReadOnly
|
|
40
|
+
isReadOnly,
|
|
40
41
|
"aria-haspopup": "dialog",
|
|
41
42
|
value: inputValue,
|
|
42
43
|
};
|
|
@@ -87,7 +88,7 @@ function DateField(props) {
|
|
|
87
88
|
const { triggerProps, overlayProps } = (0, react_aria_1.useOverlayTrigger)({ type: "dialog" }, state, buttonRef);
|
|
88
89
|
const { buttonProps } = (0, react_aria_1.useButton)({
|
|
89
90
|
...triggerProps,
|
|
90
|
-
isDisabled: isDisabled ||
|
|
91
|
+
isDisabled: isDisabled || isReadOnly,
|
|
91
92
|
// When pressed or focused then move focus the input, which will select the text and trigger the DatePicker to open
|
|
92
93
|
onPress: () => { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
|
|
93
94
|
onFocus: () => { var _a; return (_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
|
|
@@ -110,7 +111,7 @@ function DateField(props) {
|
|
|
110
111
|
// But would also need to allow for the input to be `fullWidth`, which is basically also what we're accomplishing here... so maybe fine?
|
|
111
112
|
const inputSize = format === "short" ? 8 : format === "medium" ? 10 : undefined;
|
|
112
113
|
const calendarButton = ((0, jsx_runtime_1.jsx)("button", Object.assign({ ref: buttonRef }, buttonProps, { disabled: isDisabled, css: Css_1.Css.if(isDisabled).cursorNotAllowed.$, tabIndex: -1 }, tid.calendarButton, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "calendar", color: Css_1.Palette.Gray700 }, void 0) }), void 0));
|
|
113
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, textFieldProps, {
|
|
114
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, textFieldProps, { errorMsg: errorMsg, helperText: helperText, required: required, labelProps: labelProps, inputProps: { ...triggerProps, ...inputProps, size: inputSize }, inputRef: inputRef, inputWrapRef: inputWrapRef, inlineLabel: inlineLabel, onChange: (v) => {
|
|
114
115
|
// hide the calendar if the user is manually entering the date
|
|
115
116
|
state.close();
|
|
116
117
|
if (v) {
|
|
@@ -121,7 +122,7 @@ function DateField(props) {
|
|
|
121
122
|
onChange(parsed);
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
|
-
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip:
|
|
125
|
+
}, endAdornment: !iconLeft && calendarButton, startAdornment: iconLeft && calendarButton, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }, others), void 0), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: inputWrapRef, popoverRef: overlayRef, positionProps: positionProps, onClose: state.close, isOpen: state.isOpen }, { children: (0, jsx_runtime_1.jsx)(DatePickerOverlay_1.DatePickerOverlay, Object.assign({ value: value, onSelect: (d) => {
|
|
125
126
|
setInputValue(formatDate(d, dateFormat));
|
|
126
127
|
onChange(d);
|
|
127
128
|
}, state: state, disabledDays: disabledDays, overlayProps: overlayProps }, tid.datePicker), void 0) }), void 0))] }, void 0));
|
|
@@ -14,6 +14,6 @@ function DateField(props) {
|
|
|
14
14
|
const { value } = e.target;
|
|
15
15
|
setValue(value);
|
|
16
16
|
onChange((0, date_fns_1.parse)(value, "MM/dd/yy", new Date()));
|
|
17
|
-
}, onBlur: () => (0, utils_1.maybeCall)(onBlur), onFocus: () => (0, utils_1.maybeCall)(onFocus), disabled: !!props.disabled, readOnly: props.readOnly, "data-disabled-days": JSON.stringify(props.disabledDays) }), void 0));
|
|
17
|
+
}, onBlur: () => (0, utils_1.maybeCall)(onBlur), onFocus: () => (0, utils_1.maybeCall)(onFocus), disabled: !!props.disabled, readOnly: !!props.readOnly, "data-disabled-days": JSON.stringify(props.disabledDays) }), void 0));
|
|
18
18
|
}
|
|
19
19
|
exports.DateField = DateField;
|
|
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MultiSelectField = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
|
+
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
6
7
|
/** Mocks out `MultiSelectField` as a multiple `<select>` field. */
|
|
7
8
|
function MultiSelectField(props) {
|
|
8
9
|
const { getOptionValue = (o) => o.id, // if unset, assume O implements HasId
|
|
9
10
|
getOptionLabel = (o) => o.name, // if unset, assume O implements HasName
|
|
10
|
-
values, options, onSelect, readOnly = false, errorMsg, onFocus, onBlur, disabled, } = props;
|
|
11
|
-
const tid = (0, utils_1.useTestIds)(props,
|
|
11
|
+
values, options, onSelect, readOnly = false, errorMsg, onFocus, onBlur, disabled, label, } = props;
|
|
12
|
+
const tid = (0, utils_1.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
|
|
12
13
|
return ((0, jsx_runtime_1.jsxs)("select", Object.assign({}, tid, {
|
|
13
14
|
// We're cheating and assume the values are strings...what we should really do is either:
|
|
14
15
|
// a) use beam's valueToKey mapping to string-encode any Value, or
|
|
@@ -10,13 +10,14 @@ export interface NumberFieldProps {
|
|
|
10
10
|
value: number | undefined;
|
|
11
11
|
onChange: (value: number | undefined) => void;
|
|
12
12
|
compact?: boolean;
|
|
13
|
-
disabled
|
|
13
|
+
/** Whether the field is disabled. If a ReactNode, it's treated as a "disabled reason" that's shown in a tooltip. */
|
|
14
|
+
disabled?: boolean | ReactNode;
|
|
14
15
|
required?: boolean;
|
|
15
16
|
errorMsg?: string;
|
|
16
17
|
helperText?: string | ReactNode;
|
|
17
18
|
onBlur?: () => void;
|
|
18
19
|
onFocus?: () => void;
|
|
19
|
-
readOnly?: boolean;
|
|
20
|
+
readOnly?: boolean | ReactNode;
|
|
20
21
|
/** Styles overrides */
|
|
21
22
|
xss?: Xss<"textAlign" | "justifyContent">;
|
|
22
23
|
displayDirection?: boolean;
|
|
@@ -6,6 +6,7 @@ const number_1 = require("@internationalized/number");
|
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const react_aria_1 = require("react-aria");
|
|
8
8
|
const react_stately_1 = require("react-stately");
|
|
9
|
+
const components_1 = require("../components");
|
|
9
10
|
const PresentationContext_1 = require("../components/PresentationContext");
|
|
10
11
|
const Css_1 = require("../Css");
|
|
11
12
|
const utils_1 = require("../utils");
|
|
@@ -14,7 +15,9 @@ function NumberField(props) {
|
|
|
14
15
|
// Determine default alignment based on presentation context
|
|
15
16
|
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
16
17
|
const alignment = (fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.numberAlignment) === "right" ? Css_1.Css.tr.jcfe.$ : Css_1.Css.tl.jcfs.$;
|
|
17
|
-
const { disabled
|
|
18
|
+
const { disabled, required, readOnly, type, label, onBlur, onFocus, errorMsg, helperText, value, onChange, xss, displayDirection = false, numFractionDigits, truncate = false, onEnter, ...otherProps } = props;
|
|
19
|
+
const isDisabled = !!disabled;
|
|
20
|
+
const isReadOnly = !!readOnly;
|
|
18
21
|
const factor = type === "percent" || type === "cents" ? 100 : type === "basisPoints" ? 10000 : 1;
|
|
19
22
|
const signDisplay = displayDirection ? "exceptZero" : "auto";
|
|
20
23
|
const fractionFormatOptions = { [truncate ? "maximumFractionDigits" : "minimumFractionDigits"]: numFractionDigits };
|
|
@@ -58,8 +61,8 @@ function NumberField(props) {
|
|
|
58
61
|
},
|
|
59
62
|
validationState: errorMsg !== undefined ? "invalid" : "valid",
|
|
60
63
|
label: label,
|
|
61
|
-
isDisabled
|
|
62
|
-
isReadOnly
|
|
64
|
+
isDisabled,
|
|
65
|
+
isReadOnly,
|
|
63
66
|
formatOptions,
|
|
64
67
|
};
|
|
65
68
|
const state = (0, react_stately_1.useNumberFieldState)(useProps);
|
|
@@ -75,7 +78,7 @@ function NumberField(props) {
|
|
|
75
78
|
onChange: (rawInputValue) => {
|
|
76
79
|
const parsedValue = numberParser.parse(rawInputValue || "");
|
|
77
80
|
onChange(formatValue(parsedValue, factor, numFractionDigits));
|
|
78
|
-
}, inputRef: inputRef, onBlur: onBlur, onFocus: onFocus, errorMsg: errorMsg, helperText: helperText,
|
|
81
|
+
}, inputRef: inputRef, onBlur: onBlur, onFocus: onFocus, errorMsg: errorMsg, helperText: helperText, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }, otherProps), void 0));
|
|
79
82
|
}
|
|
80
83
|
exports.NumberField = NumberField;
|
|
81
84
|
function formatValue(value, factor, numFractionDigits) {
|
|
@@ -4,12 +4,13 @@ exports.SelectField = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
7
|
+
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
7
8
|
/** Mocks out `SelectField` as a `<select>` field. */
|
|
8
9
|
function SelectField(props) {
|
|
9
10
|
const { getOptionValue = (o) => o.id, // if unset, assume O implements HasId
|
|
10
11
|
getOptionLabel = (o) => o.name, // if unset, assume O implements HasName
|
|
11
|
-
value, options: maybeOptions, onSelect, readOnly = false, errorMsg, onBlur, onFocus, disabled, disabledOptions = [], } = props;
|
|
12
|
-
const tid = (0, utils_1.useTestIds)(props,
|
|
12
|
+
value, options: maybeOptions, onSelect, readOnly = false, errorMsg, onBlur, onFocus, disabled, disabledOptions = [], label, } = props;
|
|
13
|
+
const tid = (0, utils_1.useTestIds)(props, (0, defaultTestId_1.defaultTestId)(label));
|
|
13
14
|
const [options, setOptions] = (0, react_1.useState)(Array.isArray(maybeOptions) ? maybeOptions : maybeOptions.initial);
|
|
14
15
|
const currentOption = options.find((o) => getOptionValue(o) === value) || options[0];
|
|
15
16
|
(0, react_1.useEffect)(() => {
|
|
@@ -5,12 +5,15 @@ const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
|
5
5
|
const utils_1 = require("@react-aria/utils");
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const react_aria_1 = require("react-aria");
|
|
8
|
+
const components_1 = require("../components");
|
|
8
9
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
9
10
|
const utils_2 = require("../utils");
|
|
10
11
|
/** Returns a <textarea /> element that auto-adjusts height based on the field's value */
|
|
11
12
|
function TextAreaField(props) {
|
|
12
13
|
const { value = "", disabled = false, readOnly = false, onBlur, onFocus, preventNewLines, onEnter, ...otherProps } = props;
|
|
13
|
-
const
|
|
14
|
+
const isDisabled = !!disabled;
|
|
15
|
+
const isReadOnly = !!readOnly;
|
|
16
|
+
const textFieldProps = { ...otherProps, value, isDisabled, isReadOnly };
|
|
14
17
|
const inputRef = (0, react_1.useRef)(null);
|
|
15
18
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
16
19
|
// not in stately because this is so we know when to re-measure, which is a spectrum design
|
|
@@ -60,6 +63,6 @@ function TextAreaField(props) {
|
|
|
60
63
|
}
|
|
61
64
|
: {}),
|
|
62
65
|
}, inputRef);
|
|
63
|
-
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, (0, react_aria_1.mergeProps)(otherProps, { onBlur, onFocus }), { multiline: true, labelProps: labelProps, inputProps: inputProps, inputRef: inputRef,
|
|
66
|
+
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, (0, react_aria_1.mergeProps)(otherProps, { onBlur, onFocus }), { multiline: true, labelProps: labelProps, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, textAreaMinHeight: preventNewLines ? 0 : undefined, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }), void 0));
|
|
64
67
|
}
|
|
65
68
|
exports.TextAreaField = TextAreaField;
|
package/dist/inputs/TextField.js
CHANGED
|
@@ -4,14 +4,17 @@ exports.TextField = 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");
|
|
7
|
+
const components_1 = require("../components");
|
|
7
8
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
8
9
|
const utils_1 = require("../utils");
|
|
9
10
|
function TextField(props) {
|
|
10
|
-
const { disabled
|
|
11
|
+
const { disabled = false, readOnly = false, required, errorMsg, value = "", onBlur, onFocus, api, onEnter, ...otherProps } = props;
|
|
12
|
+
const isDisabled = !!disabled;
|
|
13
|
+
const isReadOnly = !!readOnly;
|
|
11
14
|
const textFieldProps = {
|
|
12
15
|
...otherProps,
|
|
13
16
|
isDisabled,
|
|
14
|
-
isReadOnly
|
|
17
|
+
isReadOnly,
|
|
15
18
|
isRequired: required,
|
|
16
19
|
validationState: errorMsg ? "invalid" : "valid",
|
|
17
20
|
value,
|
|
@@ -33,6 +36,6 @@ function TextField(props) {
|
|
|
33
36
|
focus: () => inputRef.current && inputRef.current.focus(),
|
|
34
37
|
};
|
|
35
38
|
}
|
|
36
|
-
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, (0, react_aria_1.mergeProps)(textFieldProps, { onBlur, onFocus }), {
|
|
39
|
+
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, (0, react_aria_1.mergeProps)(textFieldProps, { onBlur, onFocus }), { errorMsg: errorMsg, required: required, labelProps: labelProps, inputProps: inputProps, inputRef: inputRef, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly) }), void 0));
|
|
37
40
|
}
|
|
38
41
|
exports.TextField = TextField;
|
|
@@ -2,7 +2,7 @@ import type { NumberFieldAria } from "@react-aria/numberfield";
|
|
|
2
2
|
import { InputHTMLAttributes, LabelHTMLAttributes, MutableRefObject, ReactNode, TextareaHTMLAttributes } from "react";
|
|
3
3
|
import { Only } from "../Css";
|
|
4
4
|
import { BeamTextFieldProps, TextFieldXss } from "../interfaces";
|
|
5
|
-
export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "required" | "
|
|
5
|
+
export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "required" | "errorMsg" | "onBlur" | "onFocus" | "helperText" | "hideLabel" | "placeholder" | "compact" | "borderless" | "visuallyDisabled" | "xss">, Partial<Pick<BeamTextFieldProps<X>, "onChange">> {
|
|
6
6
|
labelProps?: LabelHTMLAttributes<HTMLLabelElement>;
|
|
7
7
|
inputProps: InputHTMLAttributes<HTMLInputElement> | TextareaHTMLAttributes<HTMLTextAreaElement>;
|
|
8
8
|
inputRef?: MutableRefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
@@ -17,7 +17,7 @@ const useTestIds_1 = require("../utils/useTestIds");
|
|
|
17
17
|
function TextFieldBase(props) {
|
|
18
18
|
var _a, _b, _c, _d, _e, _f;
|
|
19
19
|
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
20
|
-
const { label, required, labelProps, hideLabel = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.hideLabel) !== null && _a !== void 0 ? _a : false, inputProps, inputRef, inputWrapRef, groupProps, compact = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _b !== void 0 ? _b : false, errorMsg, helperText, multiline = false,
|
|
20
|
+
const { label, required, labelProps, hideLabel = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.hideLabel) !== null && _a !== void 0 ? _a : false, inputProps, inputRef, inputWrapRef, groupProps, compact = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _b !== void 0 ? _b : false, errorMsg, helperText, multiline = false, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, inlineLabel, 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, } = props;
|
|
21
21
|
const typeScale = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _e !== void 0 ? _e : "sm";
|
|
22
22
|
const internalProps = props.internalProps || {};
|
|
23
23
|
const { compound = false } = internalProps;
|
|
@@ -80,7 +80,7 @@ function TextFieldBase(props) {
|
|
|
80
80
|
(0, jsx_runtime_1.jsx)(Label_1.Label, Object.assign({ labelProps: labelProps, hidden: hideLabel || compound, label: label, suffix: labelSuffix, contrast: contrast }, tid.label), void 0)), (0, components_1.maybeTooltip)({
|
|
81
81
|
title: tooltip,
|
|
82
82
|
placement: "top",
|
|
83
|
-
children: readOnly ? ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
83
|
+
children: inputProps.readOnly ? ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
84
84
|
// Use input wrapper to get common styles, but then we need to override some
|
|
85
85
|
...fieldStyles.inputWrapperReadOnly,
|
|
86
86
|
...(multiline ? Css_1.Css.fdc.aifs.childGap2.$ : Css_1.Css.truncate.$),
|
|
@@ -90,14 +90,14 @@ function TextFieldBase(props) {
|
|
|
90
90
|
: inputProps.value] }), void 0)) : ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: {
|
|
91
91
|
...fieldStyles.inputWrapper,
|
|
92
92
|
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
93
|
-
...(isFocused && !readOnly ? fieldStyles.focus : {}),
|
|
94
|
-
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
93
|
+
...(isFocused && !inputProps.readOnly ? fieldStyles.focus : {}),
|
|
94
|
+
...(isHovered && !inputProps.disabled && !inputProps.readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
95
95
|
...(errorMsg ? fieldStyles.error : {}),
|
|
96
96
|
...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
|
|
97
97
|
} }, hoverProps, { ref: inputWrapRef }, { children: [!multiline && inlineLabel && label && !hideLabel && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, Object.assign({ labelProps: labelProps, label: label }, tid.label), void 0)), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.df.aic.fs0.br4.pr1.$ }, { children: startAdornment }), void 0), (0, jsx_runtime_1.jsx)(ElementType, Object.assign({}, (0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(hideLabel ? { "aria-label": label } : {}) }), (errorMsg ? { "aria-errormessage": errorMessageId } : {}), { ref: fieldRef, rows: multiline ? 1 : undefined, css: {
|
|
98
98
|
...fieldStyles.input,
|
|
99
99
|
...(inputProps.disabled ? fieldStyles.disabled : {}),
|
|
100
|
-
...(isHovered && !inputProps.disabled && !readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
100
|
+
...(isHovered && !inputProps.disabled && !inputProps.readOnly && !isFocused ? fieldStyles.hover : {}),
|
|
101
101
|
...(multiline ? Css_1.Css.h100.p1.add("resize", "none").if(borderless).pPx(4).$ : Css_1.Css.truncate.$),
|
|
102
102
|
...xss,
|
|
103
103
|
} }, tid), void 0), isFocused && clearable && onChange && inputProps.value && ((0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "xCircle", color: Css_1.Palette.Gray700, onClick: () => {
|
|
@@ -15,7 +15,7 @@ function SelectFieldInput(props) {
|
|
|
15
15
|
const showNumSelection = isMultiSelect && state.selectionManager.selectedKeys.size > 1;
|
|
16
16
|
// For MultiSelect only show the `fieldDecoration` when input is not in focus.
|
|
17
17
|
const showFieldDecoration = (!isMultiSelect || (isMultiSelect && !isFocused)) && fieldDecoration && selectedOptions.length === 1;
|
|
18
|
-
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, otherProps, {
|
|
18
|
+
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({}, otherProps, { inlineLabel: inlineLabel, errorMsg: errorMsg, contrast: contrast, xss: !inlineLabel && !inputProps.readOnly ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgLightBlue700.white.tinyEm.df.aic.jcc.$ }, { children: state.selectionManager.selectedKeys.size }), void 0))) ||
|
|
19
19
|
(showFieldDecoration && fieldDecoration(selectedOptions[0])), endAdornment: !inputProps.readOnly && ((0, jsx_runtime_1.jsx)("button", Object.assign({}, buttonProps, { disabled: inputProps.disabled, ref: buttonRef, css: {
|
|
20
20
|
...Css_1.Css.br4.outline0.gray700.if(contrast).gray400.$,
|
|
21
21
|
...(inputProps.disabled ? Css_1.Css.cursorNotAllowed.gray400.if(contrast).gray600.$ : {}),
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ export interface BeamButtonProps {
|
|
|
24
24
|
}
|
|
25
25
|
export declare type TextFieldXss = Xss<"textAlign" | "justifyContent" | "fontWeight" | "fontSize" | "lineHeight">;
|
|
26
26
|
export interface BeamTextFieldProps<X> extends BeamFocusableProps, PresentationFieldProps {
|
|
27
|
-
/** Whether the
|
|
28
|
-
disabled?: boolean;
|
|
27
|
+
/** Whether the field is disabled. If a ReactNode, it's treated as a "disabled reason" that's shown in a tooltip. */
|
|
28
|
+
disabled?: boolean | ReactNode;
|
|
29
29
|
errorMsg?: string;
|
|
30
30
|
helperText?: string | ReactNode;
|
|
31
31
|
/** Input label */
|
|
@@ -39,7 +39,8 @@ export interface BeamTextFieldProps<X> extends BeamFocusableProps, PresentationF
|
|
|
39
39
|
onBlur?: Callback;
|
|
40
40
|
onFocus?: Callback;
|
|
41
41
|
onEnter?: Callback;
|
|
42
|
-
readOnly
|
|
42
|
+
/** Whether the field is readOnly. If a ReactNode, it's treated as a "readOnly reason" that's shown in a tooltip. */
|
|
43
|
+
readOnly?: boolean | ReactNode;
|
|
43
44
|
placeholder?: string;
|
|
44
45
|
/** Styles overrides */
|
|
45
46
|
xss?: X;
|