@homebound/beam 2.101.4 → 2.102.2
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/Table/GridTable.js +11 -7
- package/dist/components/Table/SortHeader.d.ts +1 -0
- package/dist/components/Table/SortHeader.js +8 -5
- package/dist/components/Table/columns.d.ts +2 -0
- package/dist/components/Table/columns.js +7 -1
- package/dist/components/Table/styles.d.ts +2 -0
- package/dist/components/Table/styles.js +11 -1
- package/dist/forms/BoundCheckboxField.js +1 -1
- package/dist/forms/BoundCheckboxGroupField.d.ts +1 -1
- package/dist/forms/BoundCheckboxGroupField.js +11 -2
- package/dist/forms/BoundChipSelectField.js +11 -3
- package/dist/forms/BoundDateField.d.ts +1 -1
- package/dist/forms/BoundDateField.js +14 -2
- package/dist/forms/BoundMultiSelectField.d.ts +1 -1
- package/dist/forms/BoundMultiSelectField.js +12 -2
- package/dist/forms/BoundNumberField.d.ts +1 -1
- package/dist/forms/BoundNumberField.js +11 -2
- package/dist/forms/BoundRadioGroupField.d.ts +1 -1
- package/dist/forms/BoundRadioGroupField.js +11 -2
- package/dist/forms/BoundRichTextField.d.ts +1 -1
- package/dist/forms/BoundRichTextField.js +8 -2
- package/dist/forms/BoundSelectField.d.ts +1 -1
- package/dist/forms/BoundSelectField.js +12 -2
- package/dist/forms/BoundSwitchField.js +1 -2
- package/dist/forms/BoundTextAreaField.d.ts +1 -1
- package/dist/forms/BoundTextAreaField.js +11 -2
- package/dist/forms/BoundTextField.js +1 -2
- package/dist/inputs/Checkbox.d.ts +1 -0
- package/dist/inputs/CheckboxBase.d.ts +1 -0
- package/dist/inputs/CheckboxBase.js +6 -3
- package/dist/inputs/ChipSelectField.js +3 -11
- package/dist/inputs/DateField.d.ts +3 -1
- package/dist/inputs/DateField.js +2 -2
- package/dist/inputs/NumberField.d.ts +5 -1
- package/dist/inputs/NumberField.js +22 -23
- package/dist/inputs/TextAreaField.d.ts +2 -0
- package/dist/inputs/TextAreaField.js +3 -2
- package/dist/inputs/TextField.js +2 -0
- package/dist/inputs/internal/SelectFieldBase.js +2 -9
- package/dist/interfaces.d.ts +4 -2
- package/dist/utils/rtl.js +2 -2
- package/package.json +3 -2
- package/dist/forms/BoundSwitchFieldTest.d.ts +0 -1
- package/dist/forms/BoundSwitchFieldTest.js +0 -29
|
@@ -81,7 +81,7 @@ exports.setGridTableDefaults = setGridTableDefaults;
|
|
|
81
81
|
*/
|
|
82
82
|
function GridTable(props) {
|
|
83
83
|
var _a;
|
|
84
|
-
const { id = "
|
|
84
|
+
const { id = "gridTable", as = "div", columns, rows, style = defaults.style, rowStyles, stickyHeader = defaults.stickyHeader, stickyOffset = "0", xss, sorting, filter, filterMaxRows, fallbackMessage = "No rows found.", infoMessage, setRowCount, observeRows, persistCollapse, api, } = props;
|
|
85
85
|
const [collapsedIds, collapseAllContext, collapseRowContext] = useToggleIds(rows, persistCollapse);
|
|
86
86
|
// We only use this in as=virtual mode, but keep this here for rowLookup to use
|
|
87
87
|
const virtuosoRef = (0, react_1.useRef)(null);
|
|
@@ -492,7 +492,9 @@ function GridRow(props) {
|
|
|
492
492
|
currentColspan = isGridCellContent(maybeContent) ? (_a = maybeContent.colspan) !== null && _a !== void 0 ? _a : 1 : 1;
|
|
493
493
|
const canSortColumn = ((sorting === null || sorting === void 0 ? void 0 : sorting.on) === "client" && column.clientSideSort !== false) ||
|
|
494
494
|
((sorting === null || sorting === void 0 ? void 0 : sorting.on) === "server" && !!column.serverSideSortKey);
|
|
495
|
-
const
|
|
495
|
+
const alignment = getAlignment(column, maybeContent);
|
|
496
|
+
const justificationCss = getJustification(column, maybeContent, as, alignment);
|
|
497
|
+
const content = toContent(maybeContent, isHeader, canSortColumn, (sorting === null || sorting === void 0 ? void 0 : sorting.on) === "client", style, as, alignment);
|
|
496
498
|
(0, sortRows_1.ensureClientSideSortValueIsSortable)(sorting, isHeader, column, columnIndex, maybeContent);
|
|
497
499
|
const maybeNestedCardColumnIndex = columnIndex + (style.nestedCards ? 1 : 0);
|
|
498
500
|
// Note that it seems expensive to calc a per-cell class name/CSS-in-JS output,
|
|
@@ -512,7 +514,7 @@ function GridRow(props) {
|
|
|
512
514
|
// Then override with first/last cell styling
|
|
513
515
|
...getFirstOrLastCellCss(style, columnIndex, columns),
|
|
514
516
|
// Then override with per-cell/per-row justification/indentation
|
|
515
|
-
...
|
|
517
|
+
...justificationCss,
|
|
516
518
|
...getIndentationCss(style, rowStyle, columnIndex, maybeContent),
|
|
517
519
|
// Then apply any header-specific override
|
|
518
520
|
...(isHeader && style.headerCellCss),
|
|
@@ -553,7 +555,7 @@ function isJSX(content) {
|
|
|
553
555
|
return typeof content === "object" && content && "type" in content && "props" in content;
|
|
554
556
|
}
|
|
555
557
|
/** If a column def return just string text for a given row, apply some default styling. */
|
|
556
|
-
function toContent(content, isHeader, canSortColumn, isClientSideSorting, style, as) {
|
|
558
|
+
function toContent(content, isHeader, canSortColumn, isClientSideSorting, style, as, alignment) {
|
|
557
559
|
content = isGridCellContent(content) ? content.content : content;
|
|
558
560
|
if (typeof content === "function") {
|
|
559
561
|
// Actually create the JSX by calling `content()` here (which should be as late as
|
|
@@ -572,7 +574,7 @@ function toContent(content, isHeader, canSortColumn, isClientSideSorting, style,
|
|
|
572
574
|
throw new Error("GridTables with as=virtual & sortable columns should use functions that return JSX, instead of JSX");
|
|
573
575
|
}
|
|
574
576
|
if (content && typeof content === "string" && isHeader && canSortColumn) {
|
|
575
|
-
return (0, jsx_runtime_1.jsx)(SortHeader_1.SortHeader, { content: content }, void 0);
|
|
577
|
+
return (0, jsx_runtime_1.jsx)(SortHeader_1.SortHeader, { content: content, iconOnLeft: alignment === "right" }, void 0);
|
|
576
578
|
}
|
|
577
579
|
else if (style.emptyCell && isContentEmpty(content)) {
|
|
578
580
|
// If the content is empty and the user specified an `emptyCell` node, return that.
|
|
@@ -650,9 +652,11 @@ const alignmentToTextAlign = {
|
|
|
650
652
|
center: "center",
|
|
651
653
|
right: "right",
|
|
652
654
|
};
|
|
655
|
+
function getAlignment(column, maybeContent) {
|
|
656
|
+
return (isGridCellContent(maybeContent) && maybeContent.alignment) || column.align || "left";
|
|
657
|
+
}
|
|
653
658
|
// For alignment, use: 1) cell def, else 2) column def, else 3) left.
|
|
654
|
-
function getJustification(column, maybeContent, as) {
|
|
655
|
-
const alignment = (isGridCellContent(maybeContent) && maybeContent.alignment) || column.align || "left";
|
|
659
|
+
function getJustification(column, maybeContent, as, alignment) {
|
|
656
660
|
// Always apply text alignment.
|
|
657
661
|
const textAlign = Css_1.Css.add("textAlign", alignmentToTextAlign[alignment]).$;
|
|
658
662
|
if (as === "table") {
|
|
@@ -20,13 +20,16 @@ const useTestIds_1 = require("../../utils/useTestIds");
|
|
|
20
20
|
* current sort state + `toggleSort` function
|
|
21
21
|
*/
|
|
22
22
|
function SortHeader(props) {
|
|
23
|
-
const { content, xss } = props;
|
|
23
|
+
const { content, xss, iconOnLeft = false } = props;
|
|
24
24
|
const { isHovered, hoverProps } = (0, hooks_1.useHover)({});
|
|
25
25
|
const { sorted, toggleSort } = (0, react_1.useContext)(GridSortContext_1.GridSortContext);
|
|
26
26
|
const tid = (0, useTestIds_1.useTestIds)(props, "sortHeader");
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const icon = ((0, jsx_runtime_1.jsx)("span", Object.assign({ css: Css_1.Css.fs0.$ }, { children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, Object.assign({ icon: sorted === "DESC" ? "sortDown" : "sortUp", color: sorted !== undefined ? Css_1.Palette.LightBlue700 : Css_1.Palette.Gray400, xss: {
|
|
28
|
+
...Css_1.Css.ml1.if(iconOnLeft).mr1.ml0.$,
|
|
29
|
+
...Css_1.Css.visibility("hidden")
|
|
30
|
+
.if(isHovered || sorted !== undefined)
|
|
31
|
+
.visibility("visible").$,
|
|
32
|
+
}, inc: 2 }, tid.icon), void 0) }), void 0));
|
|
33
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({}, tid, { css: { ...Css_1.Css.df.aic.h100.cursorPointer.selectNone.$, ...xss } }, hoverProps, { onClick: toggleSort }, { children: [iconOnLeft && icon, content, !iconOnLeft && icon] }), void 0));
|
|
31
34
|
}
|
|
32
35
|
exports.SortHeader = SortHeader;
|
|
@@ -8,3 +8,5 @@ export declare function dateColumn<T extends Kinded, S = {}>(columnDef: GridColu
|
|
|
8
8
|
export declare function numericColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
9
9
|
/** Provides default styling for a GridColumn representing an Action. */
|
|
10
10
|
export declare function actionColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
11
|
+
/** Provides default styling for a GridColumn containing a checkbox. */
|
|
12
|
+
export declare function selectColumn<T extends Kinded, S = {}>(columnDef: GridColumn<T, S>): GridColumn<T, S>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.actionColumn = exports.numericColumn = exports.dateColumn = exports.column = void 0;
|
|
3
|
+
exports.selectColumn = exports.actionColumn = exports.numericColumn = exports.dateColumn = exports.column = void 0;
|
|
4
4
|
/** Provides default styling for a GridColumn representing a Date. */
|
|
5
5
|
function column(columnDef) {
|
|
6
6
|
return { ...columnDef };
|
|
@@ -22,3 +22,9 @@ function actionColumn(columnDef) {
|
|
|
22
22
|
return { clientSideSort: false, ...columnDef, align: "center" };
|
|
23
23
|
}
|
|
24
24
|
exports.actionColumn = actionColumn;
|
|
25
|
+
/** Provides default styling for a GridColumn containing a checkbox. */
|
|
26
|
+
function selectColumn(columnDef) {
|
|
27
|
+
// Defining `w: 48px` to accommodate for the `16px` wide checkbox and `16px` of padding on either side.
|
|
28
|
+
return { clientSideSort: false, ...columnDef, align: "center", w: "48px" };
|
|
29
|
+
}
|
|
30
|
+
exports.selectColumn = selectColumn;
|
|
@@ -5,3 +5,5 @@ export declare const defaultStyle: GridStyle;
|
|
|
5
5
|
export declare const condensedStyle: GridStyle;
|
|
6
6
|
/** Renders each row as a card. */
|
|
7
7
|
export declare const cardStyle: GridStyle;
|
|
8
|
+
export declare const beamFixedStyle: GridStyle;
|
|
9
|
+
export declare const beamFlexibleStyle: GridStyle;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.cardStyle = exports.condensedStyle = exports.defaultStyle = void 0;
|
|
3
|
+
exports.beamFlexibleStyle = exports.beamFixedStyle = exports.cardStyle = exports.condensedStyle = exports.defaultStyle = void 0;
|
|
4
4
|
const Css_1 = require("../../Css");
|
|
5
5
|
/** Our original table look & feel/style. */
|
|
6
6
|
exports.defaultStyle = {
|
|
@@ -39,3 +39,13 @@ exports.cardStyle = {
|
|
|
39
39
|
}).p1.m0.xsEm.gray700.$,
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
|
+
// Once completely rolled out across all tables in Blueprint, this will change to be the `defaultStyle`.
|
|
43
|
+
exports.beamFixedStyle = {
|
|
44
|
+
rootCss: Css_1.Css.gray700.$,
|
|
45
|
+
// Doing a mix of `min` and `max` height of 40 as each cell is currently defining `h100`.
|
|
46
|
+
headerCellCss: Css_1.Css.xsEm.bgGray200.aic.nowrap.px2.mhPx(40).maxhPx(40).$,
|
|
47
|
+
// TODO: `cellCss` has incomplete styling at the moment. Will be done as part of SC-8145
|
|
48
|
+
cellCss: Css_1.Css.xs.bgWhite.aic.nowrap.px2.hPx(40).boxShadow(`inset 0 -1px 0 ${Css_1.Palette.Gray100}`).$,
|
|
49
|
+
};
|
|
50
|
+
// TODO: `cellCss` has incomplete styling at the moment. Will be done as part of SC-8145
|
|
51
|
+
exports.beamFlexibleStyle = { ...exports.beamFixedStyle, cellCss: Css_1.Css.p2.$ };
|
|
@@ -15,7 +15,7 @@ function BoundCheckboxField(props) {
|
|
|
15
15
|
return ((0, jsx_runtime_1.jsx)(inputs_1.Checkbox, Object.assign({ label: label, selected: (_a = field.value) !== null && _a !== void 0 ? _a : false, onChange: (selected) => {
|
|
16
16
|
// We are triggering blur manually for checkbox fields due to its transactional nature
|
|
17
17
|
onChange(selected);
|
|
18
|
-
field.
|
|
18
|
+
field.maybeAutoSave();
|
|
19
19
|
}, errorMsg: field.touched ? field.errors.join(" ") : undefined, onFocus: () => {
|
|
20
20
|
field.focus();
|
|
21
21
|
(0, utils_1.maybeCall)(onFocus);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state";
|
|
2
2
|
import { CheckboxGroupProps } from "../inputs";
|
|
3
|
-
export declare type BoundCheckboxGroupFieldProps = Omit<CheckboxGroupProps, "values" | "onChange" | "label"
|
|
3
|
+
export declare type BoundCheckboxGroupFieldProps = Omit<CheckboxGroupProps, "values" | "onChange" | "label"> & {
|
|
4
4
|
field: FieldState<any, string[] | null | undefined>;
|
|
5
5
|
/** Make optional so that callers can override if they want to. */
|
|
6
6
|
onChange?: (values: string[]) => void;
|
|
@@ -8,8 +8,17 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `TextField` and binds it to a form field. */
|
|
10
10
|
function BoundCheckboxGroupField(props) {
|
|
11
|
-
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
11
|
+
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.CheckboxGroup, Object.assign({ label: label, values: field.value || [], onChange:
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.CheckboxGroup, Object.assign({ label: label, values: field.value || [], onChange: (values) => {
|
|
14
|
+
onChange(values);
|
|
15
|
+
field.maybeAutoSave();
|
|
16
|
+
}, errorMsg: field.touched ? field.errors.join(" ") : undefined, onBlur: () => {
|
|
17
|
+
field.blur();
|
|
18
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
19
|
+
}, onFocus: () => {
|
|
20
|
+
field.focus();
|
|
21
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
22
|
+
} }, testId, others), void 0)) }, void 0));
|
|
14
23
|
}
|
|
15
24
|
exports.BoundCheckboxGroupField = BoundCheckboxGroupField;
|
|
@@ -9,17 +9,25 @@ const defaultLabel_1 = require("../utils/defaultLabel");
|
|
|
9
9
|
function BoundChipSelectField(props) {
|
|
10
10
|
const { field, getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
|
|
11
11
|
getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
|
|
12
|
-
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
12
|
+
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, onCreateNew, ...others } = props;
|
|
13
13
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
14
14
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => {
|
|
15
15
|
var _a;
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)(ChipSelectField_1.ChipSelectField, Object.assign({ label: label, value: (_a = field.value) !== null && _a !== void 0 ? _a : undefined, onSelect:
|
|
16
|
+
return ((0, jsx_runtime_1.jsx)(ChipSelectField_1.ChipSelectField, Object.assign({ label: label, value: (_a = field.value) !== null && _a !== void 0 ? _a : undefined, onSelect: (value) => {
|
|
17
|
+
onSelect(value);
|
|
18
|
+
field.maybeAutoSave();
|
|
19
|
+
}, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, onBlur: () => {
|
|
17
20
|
field.blur();
|
|
18
21
|
(0, utils_1.maybeCall)(onBlur);
|
|
19
22
|
}, onFocus: () => {
|
|
20
23
|
field.focus();
|
|
21
24
|
(0, utils_1.maybeCall)(onFocus);
|
|
22
|
-
}
|
|
25
|
+
}, onCreateNew: onCreateNew
|
|
26
|
+
? async (v) => {
|
|
27
|
+
await onCreateNew(v);
|
|
28
|
+
field.maybeAutoSave();
|
|
29
|
+
}
|
|
30
|
+
: undefined }, others, testId), void 0));
|
|
23
31
|
} }, void 0));
|
|
24
32
|
}
|
|
25
33
|
exports.BoundChipSelectField = BoundChipSelectField;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state";
|
|
2
2
|
import { DateFieldProps } from "../inputs";
|
|
3
|
-
export declare type BoundDateFieldProps = Omit<DateFieldProps, "label" | "value" | "onChange"
|
|
3
|
+
export declare type BoundDateFieldProps = Omit<DateFieldProps, "label" | "value" | "onChange"> & {
|
|
4
4
|
field: FieldState<any, Date | null | undefined>;
|
|
5
5
|
label?: string;
|
|
6
6
|
onChange?: (value: Date) => void;
|
|
@@ -8,8 +8,20 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `TextField` and binds it to a form field. */
|
|
10
10
|
function BoundDateField(props) {
|
|
11
|
-
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
11
|
+
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, onEnter, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.DateField, Object.assign({ label: label, value: field.value || undefined, onChange:
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.DateField, Object.assign({ label: label, value: field.value || undefined, onChange: (value) => {
|
|
14
|
+
onChange(value);
|
|
15
|
+
field.maybeAutoSave();
|
|
16
|
+
}, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onBlur: () => {
|
|
17
|
+
field.blur();
|
|
18
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
19
|
+
}, onFocus: () => {
|
|
20
|
+
field.focus();
|
|
21
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
22
|
+
}, onEnter: () => {
|
|
23
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
24
|
+
field.maybeAutoSave();
|
|
25
|
+
} }, testId, others), void 0)) }, void 0));
|
|
14
26
|
}
|
|
15
27
|
exports.BoundDateField = BoundDateField;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state/dist/formState";
|
|
2
2
|
import { MultiSelectFieldProps, Value } from "../inputs";
|
|
3
3
|
import { HasIdAndName, Optional } from "../types";
|
|
4
|
-
export declare type BoundMultiSelectFieldProps<O, V extends Value> = Omit<MultiSelectFieldProps<O, V>, "values" | "onSelect" | "
|
|
4
|
+
export declare type BoundMultiSelectFieldProps<O, V extends Value> = Omit<MultiSelectFieldProps<O, V>, "values" | "onSelect" | "label"> & {
|
|
5
5
|
onSelect?: (values: V[], opts: O[]) => void;
|
|
6
6
|
field: FieldState<any, V[] | null | undefined>;
|
|
7
7
|
label?: string;
|
|
@@ -4,16 +4,26 @@ exports.BoundMultiSelectField = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const mobx_react_1 = require("mobx-react");
|
|
6
6
|
const inputs_1 = require("../inputs");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
7
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
8
9
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
9
10
|
function BoundMultiSelectField(props) {
|
|
10
11
|
const { field, options, readOnly, getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
|
|
11
12
|
getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
|
|
12
|
-
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
13
|
+
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
13
14
|
const testId = (0, useTestIds_1.useTestIds)(props, field.key);
|
|
14
15
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => {
|
|
15
16
|
var _a;
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)(inputs_1.MultiSelectField, Object.assign({ label: label, values: (_a = field.value) !== null && _a !== void 0 ? _a : [], onSelect:
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(inputs_1.MultiSelectField, Object.assign({ label: label, values: (_a = field.value) !== null && _a !== void 0 ? _a : [], onSelect: (values, options) => {
|
|
18
|
+
onSelect(values, options);
|
|
19
|
+
field.maybeAutoSave();
|
|
20
|
+
}, options: options, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, onBlur: () => {
|
|
21
|
+
field.blur();
|
|
22
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
23
|
+
}, onFocus: () => {
|
|
24
|
+
field.focus();
|
|
25
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
26
|
+
} }, others, testId), void 0));
|
|
17
27
|
} }, void 0));
|
|
18
28
|
}
|
|
19
29
|
exports.BoundMultiSelectField = BoundMultiSelectField;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state";
|
|
2
2
|
import { NumberFieldProps } from "../inputs/NumberField";
|
|
3
|
-
export declare type BoundNumberFieldProps = Omit<NumberFieldProps, "value" | "onChange" | "
|
|
3
|
+
export declare type BoundNumberFieldProps = Omit<NumberFieldProps, "value" | "onChange" | "label"> & {
|
|
4
4
|
label?: string;
|
|
5
5
|
field: FieldState<any, number | null | undefined>;
|
|
6
6
|
onChange?: (value: number | undefined) => void;
|
|
@@ -8,8 +8,17 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `NumberField` and binds it to a form field. */
|
|
10
10
|
function BoundNumberField(props) {
|
|
11
|
-
const { field, readOnly, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key.replace(/InCents$/, "")), type = field.key.endsWith("InCents") ? "cents" : undefined, ...others } = props;
|
|
11
|
+
const { field, readOnly, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key.replace(/InCents$/, "")), type = field.key.endsWith("InCents") ? "cents" : undefined, onFocus, onBlur, onEnter, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, label || field.key);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(NumberField_1.NumberField, Object.assign({ label: label, value: typeof field.value === "number" ? field.value : undefined, onChange: onChange, type: type, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onFocus: () =>
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(NumberField_1.NumberField, Object.assign({ label: label, value: typeof field.value === "number" ? field.value : undefined, onChange: onChange, type: type, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onFocus: () => {
|
|
14
|
+
field.focus();
|
|
15
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
16
|
+
}, onBlur: () => {
|
|
17
|
+
field.blur();
|
|
18
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
19
|
+
}, onEnter: () => {
|
|
20
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
21
|
+
field.maybeAutoSave();
|
|
22
|
+
} }, testId, others), void 0)) }, void 0));
|
|
14
23
|
}
|
|
15
24
|
exports.BoundNumberField = BoundNumberField;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state";
|
|
2
2
|
import { RadioGroupFieldProps } from "../inputs";
|
|
3
|
-
export declare type BoundRadioGroupFieldProps<K extends string> = Omit<RadioGroupFieldProps<K>, "value" | "onChange" | "label"
|
|
3
|
+
export declare type BoundRadioGroupFieldProps<K extends string> = Omit<RadioGroupFieldProps<K>, "value" | "onChange" | "label"> & {
|
|
4
4
|
field: FieldState<any, K | null | undefined>;
|
|
5
5
|
/** Make optional so that callers can override if they want to. */
|
|
6
6
|
onChange?: (value: K) => void;
|
|
@@ -8,8 +8,17 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `TextField` and binds it to a form field. */
|
|
10
10
|
function BoundRadioGroupField(props) {
|
|
11
|
-
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
11
|
+
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.RadioGroupField, Object.assign({ label: label, value: field.value || undefined, onChange:
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.RadioGroupField, Object.assign({ label: label, value: field.value || undefined, onChange: (value) => {
|
|
14
|
+
onChange(value);
|
|
15
|
+
field.maybeAutoSave();
|
|
16
|
+
}, errorMsg: field.touched ? field.errors.join(" ") : undefined, onBlur: () => {
|
|
17
|
+
field.blur();
|
|
18
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
19
|
+
}, onFocus: () => {
|
|
20
|
+
field.focus();
|
|
21
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
22
|
+
} }, testId, others), void 0)) }, void 0));
|
|
14
23
|
}
|
|
15
24
|
exports.BoundRadioGroupField = BoundRadioGroupField;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state";
|
|
2
2
|
import { RichTextFieldProps } from "../inputs/RichTextField";
|
|
3
|
-
export declare type BoundRichTextFieldProps = Omit<RichTextFieldProps, "value" | "onChange"
|
|
3
|
+
export declare type BoundRichTextFieldProps = Omit<RichTextFieldProps, "value" | "onChange"> & {
|
|
4
4
|
field: FieldState<any, string | null | undefined>;
|
|
5
5
|
onChange?: (value: string | undefined) => void;
|
|
6
6
|
};
|
|
@@ -8,11 +8,17 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `RichTextField` and binds it to a form field. */
|
|
10
10
|
function BoundRichTextField(props) {
|
|
11
|
-
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), readOnly, ...others } = props;
|
|
11
|
+
const { field, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), readOnly, onFocus, onBlur, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
13
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(RichTextField_1.RichTextField, Object.assign({ label: label, value: field.value || undefined, onChange: onChange,
|
|
14
14
|
// TODO: Potentially support this in the future?
|
|
15
15
|
// errorMsg={field.touched ? field.errors.join(" ") : undefined}
|
|
16
|
-
onBlur: () =>
|
|
16
|
+
onBlur: () => {
|
|
17
|
+
field.blur();
|
|
18
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
19
|
+
}, onFocus: () => {
|
|
20
|
+
field.focus();
|
|
21
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
22
|
+
}, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly }, testId, others), void 0)) }, void 0));
|
|
17
23
|
}
|
|
18
24
|
exports.BoundRichTextField = BoundRichTextField;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FieldState } from "@homebound/form-state/dist/formState";
|
|
2
2
|
import { SelectFieldProps, Value } from "../inputs";
|
|
3
3
|
import { HasIdAndName, Optional } from "../types";
|
|
4
|
-
export declare type BoundSelectFieldProps<T, V extends Value> = Omit<SelectFieldProps<T, V>, "value" | "onSelect" | "
|
|
4
|
+
export declare type BoundSelectFieldProps<T, V extends Value> = Omit<SelectFieldProps<T, V>, "value" | "onSelect" | "label"> & {
|
|
5
5
|
onSelect?: (option: V | undefined) => void;
|
|
6
6
|
field: FieldState<any, V | null | undefined>;
|
|
7
7
|
label?: string;
|
|
@@ -4,16 +4,26 @@ exports.BoundSelectField = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const mobx_react_1 = require("mobx-react");
|
|
6
6
|
const inputs_1 = require("../inputs");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
7
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
8
9
|
const useTestIds_1 = require("../utils/useTestIds");
|
|
9
10
|
function BoundSelectField(props) {
|
|
10
11
|
const { field, options, readOnly, getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
|
|
11
12
|
getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
|
|
12
|
-
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
13
|
+
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
13
14
|
const testId = (0, useTestIds_1.useTestIds)(props, field.key);
|
|
14
15
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => {
|
|
15
16
|
var _a;
|
|
16
|
-
return ((0, jsx_runtime_1.jsx)(inputs_1.SelectField, Object.assign({ label: label, value: (_a = field.value) !== null && _a !== void 0 ? _a : undefined, onSelect:
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(inputs_1.SelectField, Object.assign({ label: label, value: (_a = field.value) !== null && _a !== void 0 ? _a : undefined, onSelect: (value) => {
|
|
18
|
+
onSelect(value);
|
|
19
|
+
field.maybeAutoSave();
|
|
20
|
+
}, options: options, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, onBlur: () => {
|
|
21
|
+
field.blur();
|
|
22
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
23
|
+
}, onFocus: () => {
|
|
24
|
+
field.focus();
|
|
25
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
26
|
+
} }, others, testId), void 0));
|
|
17
27
|
} }, void 0));
|
|
18
28
|
}
|
|
19
29
|
exports.BoundSelectField = BoundSelectField;
|
|
@@ -13,9 +13,8 @@ function BoundSwitchField(props) {
|
|
|
13
13
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => {
|
|
14
14
|
var _a;
|
|
15
15
|
return ((0, jsx_runtime_1.jsx)(inputs_1.Switch, Object.assign({ label: label, labelStyle: "form", selected: (_a = field.value) !== null && _a !== void 0 ? _a : false, onChange: (selected) => {
|
|
16
|
-
// We are triggering blur manually for checkbox fields due to its transactional nature
|
|
17
16
|
onChange(selected);
|
|
18
|
-
field.
|
|
17
|
+
field.maybeAutoSave();
|
|
19
18
|
} }, testId, others), void 0));
|
|
20
19
|
} }, void 0));
|
|
21
20
|
}
|
|
@@ -2,7 +2,7 @@ import { FieldState } from "@homebound/form-state";
|
|
|
2
2
|
import { Only } from "../Css";
|
|
3
3
|
import { TextAreaFieldProps } from "../inputs";
|
|
4
4
|
import { TextFieldXss } from "../interfaces";
|
|
5
|
-
export declare type BoundTextAreaFieldProps<X> = Omit<TextAreaFieldProps<X>, "value" | "onChange" | "
|
|
5
|
+
export declare type BoundTextAreaFieldProps<X> = Omit<TextAreaFieldProps<X>, "value" | "onChange" | "label"> & {
|
|
6
6
|
label?: string;
|
|
7
7
|
field: FieldState<any, string | null | undefined>;
|
|
8
8
|
onChange?: (value: string | undefined) => void;
|
|
@@ -8,8 +8,17 @@ const utils_1 = require("../utils");
|
|
|
8
8
|
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
9
|
/** Wraps `TextAreaField` and binds it to a form field. */
|
|
10
10
|
function BoundTextAreaField(props) {
|
|
11
|
-
const { field, readOnly, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), ...others } = props;
|
|
11
|
+
const { field, readOnly, onChange = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onFocus, onBlur, onEnter, ...others } = props;
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
|
-
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.TextAreaField, Object.assign({ label: label, value: field.value || undefined, onChange: onChange, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, onBlur: () =>
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.TextAreaField, Object.assign({ label: label, value: field.value || undefined, onChange: onChange, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, onBlur: () => {
|
|
14
|
+
field.blur();
|
|
15
|
+
(0, utils_1.maybeCall)(onBlur);
|
|
16
|
+
}, onFocus: () => {
|
|
17
|
+
field.focus();
|
|
18
|
+
(0, utils_1.maybeCall)(onFocus);
|
|
19
|
+
}, onEnter: () => {
|
|
20
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
21
|
+
field.maybeAutoSave();
|
|
22
|
+
} }, testId, others), void 0)) }, void 0));
|
|
14
23
|
}
|
|
15
24
|
exports.BoundTextAreaField = BoundTextAreaField;
|
|
@@ -12,8 +12,7 @@ function BoundTextField(props) {
|
|
|
12
12
|
const testId = (0, utils_1.useTestIds)(props, field.key);
|
|
13
13
|
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsx)(inputs_1.TextField, Object.assign({ label: label, value: field.value || undefined, onChange: onChange, readOnly: readOnly !== null && readOnly !== void 0 ? readOnly : field.readOnly, errorMsg: field.touched ? field.errors.join(" ") : undefined, required: field.required, onBlur: () => field.blur(), onFocus: () => field.focus(), onEnter: () => {
|
|
14
14
|
(0, utils_1.maybeCall)(onEnter);
|
|
15
|
-
|
|
16
|
-
field.blur();
|
|
15
|
+
field.maybeAutoSave();
|
|
17
16
|
} }, testId, others), void 0)) }, void 0));
|
|
18
17
|
}
|
|
19
18
|
exports.BoundTextField = BoundTextField;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
export interface CheckboxProps {
|
|
3
3
|
label: string;
|
|
4
|
+
checkboxOnly?: boolean;
|
|
4
5
|
/** Handler that is called when the element's selection state changes. */
|
|
5
6
|
onChange: (selected: boolean) => void;
|
|
6
7
|
/** Additional text displayed below label */
|
|
@@ -10,7 +10,7 @@ const ErrorMessage_1 = require("./ErrorMessage");
|
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
12
12
|
function CheckboxBase(props) {
|
|
13
|
-
const { ariaProps, description, isDisabled = false, isIndeterminate = false, isSelected, inputProps, label, errorMsg, helperText, } = props;
|
|
13
|
+
const { ariaProps, description, isDisabled = false, isIndeterminate = false, isSelected, inputProps, label, errorMsg, helperText, checkboxOnly = false, } = props;
|
|
14
14
|
const ref = (0, react_1.useRef)(null);
|
|
15
15
|
const { isFocusVisible, focusProps } = (0, react_aria_1.useFocusRing)(ariaProps);
|
|
16
16
|
const { hoverProps, isHovered } = (0, react_aria_1.useHover)({ isDisabled });
|
|
@@ -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
|
|
26
|
+
.if(isDisabled).cursorNotAllowed.$, "aria-label": label }, { children: [(0, jsx_runtime_1.jsx)(react_aria_1.VisuallyHidden, { children: (0, jsx_runtime_1.jsx)("input", Object.assign({ ref: ref }, (0, react_aria_1.mergeProps)(inputProps, focusProps), tid), void 0) }, void 0), (0, jsx_runtime_1.jsx)("span", Object.assign({}, hoverProps, { css: {
|
|
27
27
|
...baseStyles,
|
|
28
28
|
...((isSelected || isIndeterminate) && filledBoxStyles),
|
|
29
29
|
...((isSelected || isIndeterminate) && isHovered && filledBoxHoverStyles),
|
|
@@ -31,7 +31,10 @@ function CheckboxBase(props) {
|
|
|
31
31
|
...(isFocusVisible && focusRingStyles),
|
|
32
32
|
...(isHovered && hoverBorderStyles),
|
|
33
33
|
...markStyles,
|
|
34
|
-
}, "aria-hidden": "true" }, { children: markIcon }), void 0),
|
|
34
|
+
}, "aria-hidden": "true" }, { children: markIcon }), void 0), !checkboxOnly && (
|
|
35
|
+
// Use a mtPx(-2) to better align the label with the checkbox.
|
|
36
|
+
// Not using align-items: center as the checkbox would align with all content below, where we really want it to stay only aligned with the label
|
|
37
|
+
(0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.ml1.mtPx(-2).$ }, { children: [label && (0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...labelStyles, ...(isDisabled && disabledColor) } }, { children: label }), void 0), description && (0, jsx_runtime_1.jsx)("div", Object.assign({ css: { ...descStyles, ...(isDisabled && disabledColor) } }, { children: description }), void 0), errorMsg && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, Object.assign({ errorMsg: errorMsg }, tid.errorMsg), void 0), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, Object.assign({ helperText: helperText }, tid.helperText), void 0)] }), void 0))] }), void 0));
|
|
35
38
|
}
|
|
36
39
|
exports.CheckboxBase = CheckboxBase;
|
|
37
40
|
const baseStyles = Css_1.Css.hPx(16).mw((0, Css_1.px)(16)).relative.ba.bGray300.br4.bgWhite.transition.$;
|
|
@@ -114,10 +114,8 @@ function ChipSelectField(props) {
|
|
|
114
114
|
if (selectedItem) {
|
|
115
115
|
onSelect(key, selectedItem);
|
|
116
116
|
}
|
|
117
|
-
// Per UX,
|
|
118
|
-
// We cannot simply call `buttonRef.current.blur()` here because `state.isOpen === true` and we keep the visualFocus shown when the menu is open.
|
|
117
|
+
// Per UX, we do not want to show visual focus upon selection change.
|
|
119
118
|
setVisualFocus(false);
|
|
120
|
-
(0, utils_1.maybeCall)(onBlur);
|
|
121
119
|
},
|
|
122
120
|
onOpenChange: (isOpen) => {
|
|
123
121
|
var _a;
|
|
@@ -152,14 +150,9 @@ function ChipSelectField(props) {
|
|
|
152
150
|
};
|
|
153
151
|
// State management for the "Create new" flow with ChipTextField.
|
|
154
152
|
const [showInput, setShowInput] = (0, react_1.useState)(false);
|
|
155
|
-
|
|
156
|
-
setShowInput(false);
|
|
157
|
-
// Trigger onBlur to initiate any auto-saving behavior.
|
|
158
|
-
(0, utils_1.maybeCall)(onBlur);
|
|
159
|
-
}, [setShowInput]);
|
|
160
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showInput && onCreateNew && ((0, jsx_runtime_1.jsx)(CreateNewField, Object.assign({ onBlur: removeCreateNewField, onEnter: async (value) => {
|
|
153
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showInput && onCreateNew && ((0, jsx_runtime_1.jsx)(CreateNewField, Object.assign({ onBlur: () => setShowInput(false), onEnter: async (value) => {
|
|
161
154
|
await onCreateNew(value);
|
|
162
|
-
|
|
155
|
+
setShowInput(false);
|
|
163
156
|
} }, tid.createNewField), void 0)), (0, components_1.maybeTooltip)({
|
|
164
157
|
title: (0, components_1.resolveTooltip)(disabled),
|
|
165
158
|
placement: "top",
|
|
@@ -178,7 +171,6 @@ function ChipSelectField(props) {
|
|
|
178
171
|
...(isClearFocused ? Css_1.Css.boxShadow(`0px 0px 0px 2px rgba(3,105,161,1)`).$ : {}),
|
|
179
172
|
}, onClick: () => {
|
|
180
173
|
onSelect(undefined, undefined);
|
|
181
|
-
(0, utils_1.maybeCall)(onBlur);
|
|
182
174
|
setIsClearFocused(false);
|
|
183
175
|
}, "aria-label": "Remove" }, tid.clearButton, { children: (0, jsx_runtime_1.jsx)(components_1.Icon, { icon: "x", inc: typeScale === "xs" ? 2 : undefined }, void 0) }), void 0))] }), void 0)),
|
|
184
176
|
}), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, Object.assign({ triggerRef: buttonRef, popoverRef: popoverRef, positionProps: overlayProps, onClose: state.close, isOpen: state.isOpen, shouldCloseOnBlur: true }, { children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, Object.assign({}, menuProps, { listBoxRef: listBoxRef, state: state, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, positionProps: overlayProps }), void 0) }), void 0))] }, void 0));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { Modifier } from "react-day-picker";
|
|
3
3
|
import { TextFieldBaseProps } from "./TextFieldBase";
|
|
4
|
+
import { Callback } from "../types";
|
|
4
5
|
import "./DateField.css";
|
|
5
6
|
export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
|
|
6
7
|
value: Date | undefined;
|
|
@@ -23,8 +24,9 @@ export interface DateFieldProps extends Pick<TextFieldBaseProps<{}>, "borderless
|
|
|
23
24
|
/**
|
|
24
25
|
* Set custom logic for individual dates or date ranges to be disabled in the picker
|
|
25
26
|
* exposed from `react-day-picker`: https://react-day-picker.js.org/api/DayPicker#modifiers
|
|
26
|
-
|
|
27
|
+
*/
|
|
27
28
|
disabledDays?: Modifier;
|
|
29
|
+
onEnter?: Callback;
|
|
28
30
|
}
|
|
29
31
|
export declare function DateField(props: DateFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
30
32
|
declare const dateFormats: {
|
package/dist/inputs/DateField.js
CHANGED
|
@@ -16,7 +16,7 @@ const utils_1 = require("../utils");
|
|
|
16
16
|
const defaultTestId_1 = require("../utils/defaultTestId");
|
|
17
17
|
require("./DateField.css");
|
|
18
18
|
function DateField(props) {
|
|
19
|
-
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, disabledDays, ...others } = props;
|
|
19
|
+
const { label, disabled, required, value, onChange, onFocus, onBlur, errorMsg, helperText, inlineLabel = false, readOnly = false, format = "short", iconLeft = false, disabledDays, onEnter, ...others } = props;
|
|
20
20
|
const inputRef = (0, react_1.useRef)(null);
|
|
21
21
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
22
22
|
const buttonRef = (0, react_1.useRef)(null);
|
|
@@ -79,7 +79,7 @@ function DateField(props) {
|
|
|
79
79
|
onKeyDown: (e) => {
|
|
80
80
|
var _a;
|
|
81
81
|
if (e.key === "Enter") {
|
|
82
|
-
|
|
82
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
83
83
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
84
84
|
}
|
|
85
85
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { Xss } from "../Css";
|
|
3
|
+
import { Callback } from "../types";
|
|
3
4
|
export declare type NumberFieldType = "cents" | "percent" | "basisPoints" | "days";
|
|
4
5
|
export interface NumberFieldProps {
|
|
5
6
|
label: string;
|
|
@@ -19,6 +20,9 @@ export interface NumberFieldProps {
|
|
|
19
20
|
/** Styles overrides */
|
|
20
21
|
xss?: Xss<"textAlign" | "justifyContent">;
|
|
21
22
|
displayDirection?: boolean;
|
|
23
|
+
numFractionDigits?: number;
|
|
24
|
+
truncate?: boolean;
|
|
25
|
+
onEnter?: Callback;
|
|
22
26
|
}
|
|
23
27
|
export declare function NumberField(props: NumberFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
24
|
-
export declare function
|
|
28
|
+
export declare function formatValue(value: number, factor: number, numFractionDigits: number | undefined): number | undefined;
|
|
@@ -1,45 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.formatValue = exports.NumberField = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const number_1 = require("@internationalized/number");
|
|
5
6
|
const react_1 = require("react");
|
|
6
7
|
const react_aria_1 = require("react-aria");
|
|
7
8
|
const react_stately_1 = require("react-stately");
|
|
8
9
|
const PresentationContext_1 = require("../components/PresentationContext");
|
|
9
10
|
const Css_1 = require("../Css");
|
|
11
|
+
const utils_1 = require("../utils");
|
|
10
12
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
11
13
|
function NumberField(props) {
|
|
12
14
|
// Determine default alignment based on presentation context
|
|
13
15
|
const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
|
|
14
16
|
const alignment = (fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.numberAlignment) === "right" ? Css_1.Css.tr.jcfe.$ : Css_1.Css.tl.jcfs.$;
|
|
15
|
-
const { disabled = false, required, readOnly = false, type, label, onBlur, onFocus, errorMsg, helperText, value, onChange, xss, displayDirection = false, ...otherProps } = props;
|
|
17
|
+
const { disabled = false, required, readOnly = false, type, label, onBlur, onFocus, errorMsg, helperText, value, onChange, xss, displayDirection = false, numFractionDigits, truncate = false, onEnter, ...otherProps } = props;
|
|
16
18
|
const factor = type === "percent" || type === "cents" ? 100 : type === "basisPoints" ? 10000 : 1;
|
|
17
19
|
const signDisplay = displayDirection ? "exceptZero" : "auto";
|
|
20
|
+
const fractionFormatOptions = { [truncate ? "maximumFractionDigits" : "minimumFractionDigits"]: numFractionDigits };
|
|
21
|
+
const { locale } = (0, react_aria_1.useLocale)();
|
|
18
22
|
// If formatOptions isn't memo'd, a useEffect in useNumberStateField will cause jank,
|
|
19
23
|
// see: https://github.com/adobe/react-spectrum/issues/1893.
|
|
20
24
|
const formatOptions = (0, react_1.useMemo)(() => {
|
|
21
25
|
return type === "percent"
|
|
22
|
-
? { style: "percent", signDisplay }
|
|
26
|
+
? { style: "percent", signDisplay, ...fractionFormatOptions }
|
|
23
27
|
: type === "basisPoints"
|
|
24
28
|
? { style: "percent", minimumFractionDigits: 2, signDisplay }
|
|
25
29
|
: type === "cents"
|
|
26
30
|
? { style: "currency", currency: "USD", minimumFractionDigits: 2, signDisplay }
|
|
27
31
|
: type === "days"
|
|
28
32
|
? { style: "unit", unit: "day", unitDisplay: "long", maximumFractionDigits: 0, signDisplay }
|
|
29
|
-
:
|
|
33
|
+
: fractionFormatOptions;
|
|
30
34
|
}, [type]);
|
|
35
|
+
const numberParser = (0, react_1.useMemo)(() => new number_1.NumberParser(locale, formatOptions), [locale, formatOptions]);
|
|
31
36
|
const valueRef = (0, react_1.useRef)({ wip: false });
|
|
32
|
-
const { locale } = (0, react_aria_1.useLocale)();
|
|
33
37
|
// We can use this for both useNumberFieldState + useNumberField
|
|
34
38
|
const useProps = {
|
|
35
39
|
locale,
|
|
36
40
|
// We want percents && cents to be integers, useNumberFieldState excepts them as decimals
|
|
37
41
|
value: valueRef.current.wip ? valueRef.current.value : value === undefined ? Number.NaN : value / factor,
|
|
38
|
-
// This is called on blur with the final/committed value.
|
|
42
|
+
// // This is called on blur with the final/committed value.
|
|
39
43
|
onChange: (value) => {
|
|
40
|
-
|
|
41
|
-
// Reverse the integer/decimal conversion
|
|
42
|
-
onChange(Number.isNaN(value) ? undefined : factor !== 1 ? Math.round(value * factor) : value);
|
|
44
|
+
onChange(formatValue(value, factor, numFractionDigits));
|
|
43
45
|
},
|
|
44
46
|
onFocus: () => {
|
|
45
47
|
valueRef.current = { wip: true, value: value === undefined ? Number.NaN : value / factor };
|
|
@@ -50,7 +52,7 @@ function NumberField(props) {
|
|
|
50
52
|
onKeyDown: (e) => {
|
|
51
53
|
var _a;
|
|
52
54
|
if (e.key === "Enter") {
|
|
53
|
-
|
|
55
|
+
(0, utils_1.maybeCall)(onEnter);
|
|
54
56
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
55
57
|
}
|
|
56
58
|
},
|
|
@@ -71,20 +73,17 @@ function NumberField(props) {
|
|
|
71
73
|
return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, Object.assign({ xss: { ...alignment, ...xss }, groupProps: groupProps, labelProps: labelProps, label: label, required: required, inputProps: inputProps,
|
|
72
74
|
// This is called on each DOM change, to push the latest value into the field
|
|
73
75
|
onChange: (rawInputValue) => {
|
|
74
|
-
const
|
|
75
|
-
onChange(
|
|
76
|
+
const parsedValue = numberParser.parse(rawInputValue || "");
|
|
77
|
+
onChange(formatValue(parsedValue, factor, numFractionDigits));
|
|
76
78
|
}, inputRef: inputRef, onBlur: onBlur, onFocus: onFocus, errorMsg: errorMsg, helperText: helperText, readOnly: readOnly }, otherProps), void 0));
|
|
77
79
|
}
|
|
78
80
|
exports.NumberField = NumberField;
|
|
79
|
-
function
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
const value = type === "percent" || type === "basisPoints" ? wip / 100 : wip;
|
|
87
|
-
// Since the values returned is exactly what is in the field
|
|
88
|
-
return factor !== 1 ? Math.round(value * factor) : value;
|
|
81
|
+
function formatValue(value, factor, numFractionDigits) {
|
|
82
|
+
// We treat percents & cents as (mostly) integers, while useNumberField wants decimals, so
|
|
83
|
+
// undo that via `* factor` and `Math.round`, but also keep any specifically-requested `numFractionDigits`,
|
|
84
|
+
// i.e. for `type=percent value=12.34`, `value` will be `0.1234` that we want turn into `12.34`.
|
|
85
|
+
const maybeAdjustForDecimals = numFractionDigits ? Math.pow(10, numFractionDigits) : 1;
|
|
86
|
+
// Reverse the integer/decimal conversion
|
|
87
|
+
return Number.isNaN(value) ? undefined : Math.round(value * factor * maybeAdjustForDecimals) / maybeAdjustForDecimals;
|
|
89
88
|
}
|
|
90
|
-
exports.
|
|
89
|
+
exports.formatValue = formatValue;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Only } from "../Css";
|
|
2
2
|
import { BeamTextFieldProps, TextFieldXss } from "../interfaces";
|
|
3
|
+
import { Callback } from "../types";
|
|
3
4
|
export interface TextAreaFieldProps<X> extends BeamTextFieldProps<X> {
|
|
4
5
|
preventNewLines?: boolean;
|
|
6
|
+
onEnter?: Callback;
|
|
5
7
|
}
|
|
6
8
|
/** Returns a <textarea /> element that auto-adjusts height based on the field's value */
|
|
7
9
|
export declare function TextAreaField<X extends Only<TextFieldXss, X>>(props: TextAreaFieldProps<X>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -6,9 +6,10 @@ const utils_1 = require("@react-aria/utils");
|
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const react_aria_1 = require("react-aria");
|
|
8
8
|
const TextFieldBase_1 = require("./TextFieldBase");
|
|
9
|
+
const utils_2 = require("../utils");
|
|
9
10
|
/** Returns a <textarea /> element that auto-adjusts height based on the field's value */
|
|
10
11
|
function TextAreaField(props) {
|
|
11
|
-
const { value = "", disabled = false, readOnly = false, onBlur, onFocus, preventNewLines, ...otherProps } = props;
|
|
12
|
+
const { value = "", disabled = false, readOnly = false, onBlur, onFocus, preventNewLines, onEnter, ...otherProps } = props;
|
|
12
13
|
const textFieldProps = { ...otherProps, value, isDisabled: disabled, isReadOnly: readOnly };
|
|
13
14
|
const inputRef = (0, react_1.useRef)(null);
|
|
14
15
|
const inputWrapRef = (0, react_1.useRef)(null);
|
|
@@ -47,7 +48,7 @@ function TextAreaField(props) {
|
|
|
47
48
|
// Prevent user from typing the new line character
|
|
48
49
|
if (e.key === "Enter") {
|
|
49
50
|
e.preventDefault();
|
|
50
|
-
|
|
51
|
+
(0, utils_2.maybeCall)(onEnter);
|
|
51
52
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
52
53
|
}
|
|
53
54
|
},
|
package/dist/inputs/TextField.js
CHANGED
|
@@ -20,8 +20,10 @@ function TextField(props) {
|
|
|
20
20
|
const { labelProps, inputProps } = (0, react_aria_1.useTextField)({
|
|
21
21
|
...textFieldProps,
|
|
22
22
|
onKeyDown: (e) => {
|
|
23
|
+
var _a;
|
|
23
24
|
if (e.key === "Enter") {
|
|
24
25
|
(0, utils_1.maybeCall)(onEnter);
|
|
26
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
|
|
25
27
|
}
|
|
26
28
|
},
|
|
27
29
|
}, inputRef);
|
|
@@ -32,7 +32,6 @@ function SelectFieldBase(props) {
|
|
|
32
32
|
const initOptions = Array.isArray(maybeOptions) ? maybeOptions : maybeOptions.initial;
|
|
33
33
|
const selectedOptions = initOptions.filter((o) => values.includes(getOptionValue(o)));
|
|
34
34
|
return {
|
|
35
|
-
isOpen: false,
|
|
36
35
|
selectedKeys: (_a = selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.map((o) => (0, Value_1.valueToKey)(getOptionValue(o)))) !== null && _a !== void 0 ? _a : [],
|
|
37
36
|
inputValue: getInputValue(initOptions.filter((o) => values === null || values === void 0 ? void 0 : values.includes(getOptionValue(o))), getOptionLabel, multiselect, nothingSelectedText),
|
|
38
37
|
filteredOptions: initOptions,
|
|
@@ -48,14 +47,12 @@ function SelectFieldBase(props) {
|
|
|
48
47
|
if (inputValue !== fieldState.inputValue || fieldState.filteredOptions.length !== fieldState.allOptions.length) {
|
|
49
48
|
setFieldState((prevState) => ({
|
|
50
49
|
...prevState,
|
|
51
|
-
isOpen: false,
|
|
52
50
|
inputValue,
|
|
53
51
|
filteredOptions: prevState.allOptions,
|
|
54
52
|
}));
|
|
55
53
|
}
|
|
56
54
|
}
|
|
57
55
|
function onSelectionChange(keys) {
|
|
58
|
-
var _a;
|
|
59
56
|
// We don't currently handle the "all" case
|
|
60
57
|
if (keys === "all") {
|
|
61
58
|
return;
|
|
@@ -68,7 +65,6 @@ function SelectFieldBase(props) {
|
|
|
68
65
|
if (multiselect && keys.size === 0) {
|
|
69
66
|
setFieldState({
|
|
70
67
|
...fieldState,
|
|
71
|
-
isOpen: true,
|
|
72
68
|
inputValue: state.isOpen ? "" : nothingSelectedText,
|
|
73
69
|
selectedKeys: [],
|
|
74
70
|
selectedOptions: [],
|
|
@@ -81,8 +77,6 @@ function SelectFieldBase(props) {
|
|
|
81
77
|
const firstSelectedOption = selectedOptions[0];
|
|
82
78
|
setFieldState((prevState) => ({
|
|
83
79
|
...prevState,
|
|
84
|
-
// Close menu upon selection change only for Single selection mode
|
|
85
|
-
isOpen: multiselect,
|
|
86
80
|
// If menu is open then reset inputValue to "". Otherwise set inputValue depending on number of options selected.
|
|
87
81
|
inputValue: multiselect && (state.isOpen || selectedKeys.length > 1)
|
|
88
82
|
? ""
|
|
@@ -95,8 +89,8 @@ function SelectFieldBase(props) {
|
|
|
95
89
|
}));
|
|
96
90
|
selectionChanged && onSelect(selectedKeys.map(Value_1.keyToValue), selectedOptions);
|
|
97
91
|
if (!multiselect) {
|
|
98
|
-
//
|
|
99
|
-
|
|
92
|
+
// Close menu upon selection change only for Single selection mode
|
|
93
|
+
state.close();
|
|
100
94
|
}
|
|
101
95
|
}
|
|
102
96
|
function onInputChange(value) {
|
|
@@ -130,7 +124,6 @@ function SelectFieldBase(props) {
|
|
|
130
124
|
...prevState,
|
|
131
125
|
// When using the multiselect field, always empty the input upon open.
|
|
132
126
|
inputValue: multiselect && isOpen ? "" : prevState.inputValue,
|
|
133
|
-
isOpen,
|
|
134
127
|
}));
|
|
135
128
|
}
|
|
136
129
|
// Used to calculate the rendered width of the combo box (input + button)
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { PressEvent } from "@react-types/shared";
|
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
3
|
import { PresentationFieldProps } from "./components/PresentationContext";
|
|
4
4
|
import { Xss } from "./Css";
|
|
5
|
+
import { Callback } from "./types";
|
|
5
6
|
/** Base Interfaced */
|
|
6
7
|
export interface BeamFocusableProps {
|
|
7
8
|
/** Whether the element should receive focus on render. */
|
|
@@ -35,8 +36,9 @@ export interface BeamTextFieldProps<X> extends BeamFocusableProps, PresentationF
|
|
|
35
36
|
/** Handler called when the interactive element state changes. */
|
|
36
37
|
onChange: (value: string | undefined) => void;
|
|
37
38
|
/** Called when the component loses focus, mostly for BoundTextField to use. */
|
|
38
|
-
onBlur?:
|
|
39
|
-
onFocus?:
|
|
39
|
+
onBlur?: Callback;
|
|
40
|
+
onFocus?: Callback;
|
|
41
|
+
onEnter?: Callback;
|
|
40
42
|
readOnly?: boolean;
|
|
41
43
|
placeholder?: string;
|
|
42
44
|
/** Styles overrides */
|
package/dist/utils/rtl.js
CHANGED
|
@@ -34,7 +34,7 @@ function render(component, wrapperOrOpts, ...otherWrappers) {
|
|
|
34
34
|
}
|
|
35
35
|
exports.render = render;
|
|
36
36
|
function cell(r, row, column) {
|
|
37
|
-
return cellOf(r, "
|
|
37
|
+
return cellOf(r, "gridTable", row, column);
|
|
38
38
|
}
|
|
39
39
|
exports.cell = cell;
|
|
40
40
|
function cellOf(r, tableTestId, rowNum, column) {
|
|
@@ -47,7 +47,7 @@ function cellAnd(r, row, column, testId) {
|
|
|
47
47
|
fail(`Element not found ${(0, react_1.prettyDOM)(cell(r, row, column))}`));
|
|
48
48
|
}
|
|
49
49
|
exports.cellAnd = cellAnd;
|
|
50
|
-
function row(r, row, tableTestId = "
|
|
50
|
+
function row(r, row, tableTestId = "gridTable") {
|
|
51
51
|
const nonChromeRows = Array.from(r.getByTestId(tableTestId).childNodes).filter((node) => !("chrome" in node.dataset));
|
|
52
52
|
return nonChromeRows[row];
|
|
53
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homebound/beam",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.102.2",
|
|
4
4
|
"author": "Homebound",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"format": "prettier --loglevel warn --write \"**/*.{ts,tsx,css,md}\""
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@homebound/form-state": "
|
|
36
|
+
"@homebound/form-state": "2.5.0",
|
|
37
|
+
"@internationalized/number": "^3.0.3",
|
|
37
38
|
"@react-aria/utils": "^3.9.0",
|
|
38
39
|
"@react-hook/resize-observer": "^1.2.2",
|
|
39
40
|
"@types/tinycolor2": "^1.4.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
4
|
-
const form_state_1 = require("@homebound/form-state");
|
|
5
|
-
const rtl_utils_1 = require("@homebound/rtl-utils");
|
|
6
|
-
const forms_1 = require("./");
|
|
7
|
-
describe("BoundSwitchField", () => {
|
|
8
|
-
it("should be checked", async () => {
|
|
9
|
-
// Given a formState with true boolean field
|
|
10
|
-
const formState = (0, form_state_1.createObjectState)(formConfig, { isAvailable: true });
|
|
11
|
-
// When rendered
|
|
12
|
-
const r = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(forms_1.BoundSwitchField, { field: formState.isAvailable }, void 0));
|
|
13
|
-
// Expect the BoundSwitchField to be checked
|
|
14
|
-
expect(r.isAvailable()).toBeChecked();
|
|
15
|
-
});
|
|
16
|
-
it("should uncheck when clicked", async () => {
|
|
17
|
-
// Given a rendered checked BoundSwitchField
|
|
18
|
-
const formState = (0, form_state_1.createObjectState)(formConfig, { isAvailable: true });
|
|
19
|
-
const { isAvailable } = await (0, rtl_utils_1.render)((0, jsx_runtime_1.jsx)(forms_1.BoundSwitchField, { field: formState.isAvailable }, void 0));
|
|
20
|
-
// When interacting with a BoundSwitchField
|
|
21
|
-
(0, rtl_utils_1.click)(isAvailable());
|
|
22
|
-
// Then expect the checkbox to be unchecked and the formState to reflect that state
|
|
23
|
-
expect(isAvailable()).not.toBeChecked();
|
|
24
|
-
expect(formState.isAvailable.value).toBeFalsy();
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
const formConfig = {
|
|
28
|
-
isAvailable: { type: "value", rules: [form_state_1.required] },
|
|
29
|
-
};
|