@homebound/beam 2.231.1 → 2.233.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/Table/components/Row.d.ts +2 -0
- package/dist/components/Table/utils/TableState.js +13 -3
- package/dist/forms/BoundMultiLineSelectField.d.ts +13 -0
- package/dist/forms/BoundMultiLineSelectField.js +29 -0
- package/dist/forms/index.d.ts +1 -0
- package/dist/forms/index.js +1 -0
- package/dist/inputs/MultiLineSelectField.d.ts +11 -0
- package/dist/inputs/MultiLineSelectField.js +30 -0
- package/dist/inputs/index.d.ts +1 -0
- package/dist/inputs/index.js +1 -0
- package/package.json +1 -1
|
@@ -65,5 +65,7 @@ export type GridDataRow<R extends Kinded> = {
|
|
|
65
65
|
initSelected?: boolean;
|
|
66
66
|
/** Whether row can be selected */
|
|
67
67
|
selectable?: false;
|
|
68
|
+
/** Whether this row should infer its selected state based on its children's selected state */
|
|
69
|
+
inferSelectedState?: false;
|
|
68
70
|
} & IfAny<R, {}, DiscriminateUnion<R, "kind", R["kind"]>>;
|
|
69
71
|
export {};
|
|
@@ -258,7 +258,8 @@ class TableState {
|
|
|
258
258
|
(0, visitor_1.visit)([curr.row], (row) => this.matchedRows.has(row.id) && map.set(row.id, selected ? "checked" : "unchecked"));
|
|
259
259
|
// Now walk up the parents and see if they are now-all-checked/now-all-unchecked/some-of-each
|
|
260
260
|
for (const parent of [...curr.parents].reverse()) {
|
|
261
|
-
|
|
261
|
+
// Only derive selected state of the parent row if `inferSelectedState` is not `false`
|
|
262
|
+
if (parent.children && parent.inferSelectedState !== false) {
|
|
262
263
|
map.set(parent.id, deriveParentSelected(this.getMatchedChildrenStates(parent.children, map)));
|
|
263
264
|
}
|
|
264
265
|
}
|
|
@@ -327,14 +328,16 @@ class TableState {
|
|
|
327
328
|
}
|
|
328
329
|
}
|
|
329
330
|
getMatchedChildrenStates(children, map) {
|
|
330
|
-
|
|
331
|
+
const respectedChildren = children.flatMap(getChildrenForDerivingSelectState);
|
|
332
|
+
return respectedChildren
|
|
331
333
|
.filter((row) => row.id !== "header" && this.matchedRows.has(row.id))
|
|
332
334
|
.map((row) => map.get(row.id) || this.getSelected(row.id));
|
|
333
335
|
}
|
|
334
336
|
// Recursively traverse through rows to determine selected state of parent rows based on children
|
|
335
337
|
setNestedSelectedStates(row, map) {
|
|
336
338
|
if (this.matchedRows.has(row.id)) {
|
|
337
|
-
if
|
|
339
|
+
// do not derive selected state if there are no children, or if `inferSelectedState` is set to false
|
|
340
|
+
if (!row.children || row.inferSelectedState === false) {
|
|
338
341
|
return [this.getSelected(row.id)];
|
|
339
342
|
}
|
|
340
343
|
const childrenSelectedStates = row.children.flatMap((rc) => this.setNestedSelectedStates(rc, map));
|
|
@@ -346,6 +349,13 @@ class TableState {
|
|
|
346
349
|
}
|
|
347
350
|
}
|
|
348
351
|
exports.TableState = TableState;
|
|
352
|
+
/** Returns the child rows needed for deriving the selected state of a parent/group row */
|
|
353
|
+
function getChildrenForDerivingSelectState(row) {
|
|
354
|
+
if (row.children && row.inferSelectedState === false) {
|
|
355
|
+
return [row, ...row.children.flatMap(getChildrenForDerivingSelectState)];
|
|
356
|
+
}
|
|
357
|
+
return [row];
|
|
358
|
+
}
|
|
349
359
|
/** Provides a context for rows to access their table's `TableState`. */
|
|
350
360
|
exports.TableStateContext = react_1.default.createContext({
|
|
351
361
|
get tableState() {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FieldState } from "@homebound/form-state";
|
|
2
|
+
import { MultiLineSelectFieldProps, Value } from "../inputs";
|
|
3
|
+
import { HasIdAndName, Optional } from "../types";
|
|
4
|
+
export type BoundMultiLineSelectFieldProps<O, V extends Value> = Omit<MultiLineSelectFieldProps<O, V>, "values" | "onSelect" | "label"> & {
|
|
5
|
+
onSelect?: (values: V[], opts: O[]) => void;
|
|
6
|
+
field: FieldState<any, V[] | null | undefined>;
|
|
7
|
+
label?: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Wraps `MultiLineSelectField` and binds it to a form field.
|
|
11
|
+
*/
|
|
12
|
+
export declare function BoundMultiLineSelectField<O, V extends Value>(props: BoundMultiLineSelectFieldProps<O, V>): JSX.Element;
|
|
13
|
+
export declare function BoundMultiLineSelectField<O extends HasIdAndName<V>, V extends Value>(props: Optional<BoundMultiLineSelectFieldProps<O, V>, "getOptionLabel" | "getOptionValue">): JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BoundMultiLineSelectField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const mobx_react_1 = require("mobx-react");
|
|
6
|
+
const inputs_1 = require("../inputs");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
const defaultLabel_1 = require("../utils/defaultLabel");
|
|
9
|
+
const useTestIds_1 = require("../utils/useTestIds");
|
|
10
|
+
function BoundMultiLineSelectField(props) {
|
|
11
|
+
const { field, options, readOnly, getOptionValue = (opt) => opt.id, // if unset, assume O implements HasId
|
|
12
|
+
getOptionLabel = (opt) => opt.name, // if unset, assume O implements HasName
|
|
13
|
+
onSelect = (value) => field.set(value), label = (0, defaultLabel_1.defaultLabel)(field.key), onBlur, onFocus, ...others } = props;
|
|
14
|
+
const testId = (0, useTestIds_1.useTestIds)(props, field.key);
|
|
15
|
+
return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => {
|
|
16
|
+
var _a;
|
|
17
|
+
return ((0, jsx_runtime_1.jsx)(inputs_1.MultiLineSelectField, { 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 }));
|
|
27
|
+
} }));
|
|
28
|
+
}
|
|
29
|
+
exports.BoundMultiLineSelectField = BoundMultiLineSelectField;
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from "./BoundCheckboxGroupField";
|
|
|
3
3
|
export * from "./BoundChipSelectField";
|
|
4
4
|
export * from "./BoundDateField";
|
|
5
5
|
export * from "./BoundDateRangeField";
|
|
6
|
+
export * from "./BoundMultiLineSelectField";
|
|
6
7
|
export * from "./BoundMultiSelectField";
|
|
7
8
|
export * from "./BoundNumberField";
|
|
8
9
|
export * from "./BoundRadioGroupField";
|
package/dist/forms/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./BoundCheckboxGroupField"), exports);
|
|
|
19
19
|
__exportStar(require("./BoundChipSelectField"), exports);
|
|
20
20
|
__exportStar(require("./BoundDateField"), exports);
|
|
21
21
|
__exportStar(require("./BoundDateRangeField"), exports);
|
|
22
|
+
__exportStar(require("./BoundMultiLineSelectField"), exports);
|
|
22
23
|
__exportStar(require("./BoundMultiSelectField"), exports);
|
|
23
24
|
__exportStar(require("./BoundNumberField"), exports);
|
|
24
25
|
__exportStar(require("./BoundRadioGroupField"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Value } from "./";
|
|
2
|
+
import { BeamSelectFieldBaseProps } from "./internal/SelectFieldBase";
|
|
3
|
+
import { Optional } from "../types";
|
|
4
|
+
export interface MultiLineSelectFieldProps<O, V extends Value> extends Exclude<BeamSelectFieldBaseProps<O, V>, "unsetLabel"> {
|
|
5
|
+
values: V[];
|
|
6
|
+
options: O[];
|
|
7
|
+
getOptionValue: (opt: O) => V;
|
|
8
|
+
getOptionLabel: (opt: O) => string;
|
|
9
|
+
onSelect: (values: V[], opts: O[]) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function MultiLineSelectField<O, V extends Value>(props: Optional<MultiLineSelectFieldProps<O, V>, "getOptionLabel" | "getOptionValue">): JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiLineSelectField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const Button_1 = require("../components/Button");
|
|
7
|
+
const Label_1 = require("../components/Label");
|
|
8
|
+
const inputs_1 = require("./");
|
|
9
|
+
const __1 = require("..");
|
|
10
|
+
function MultiLineSelectField(props) {
|
|
11
|
+
const { options, values, onSelect, getOptionValue = (opt) => opt.id, getOptionLabel = (opt) => opt.name, labelStyle, ...otherProps } = props;
|
|
12
|
+
const tid = (0, __1.useTestIds)(props, "");
|
|
13
|
+
const [isDisplayed, setIsDisplayed] = (0, react_1.useState)(true);
|
|
14
|
+
// Set the available options by filtering already selected options
|
|
15
|
+
const currentOptions = options.filter((o) => !values.includes(getOptionValue(o)));
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("div", { css: __1.Css.mt1.if(labelStyle === "left").df.$, children: [labelStyle !== "hidden" && ((0, jsx_runtime_1.jsx)("div", { css: __1.Css.if(labelStyle === "left").w50.$, children: (0, jsx_runtime_1.jsx)(Label_1.Label, { ...tid.label, label: props.label }) })), (0, jsx_runtime_1.jsxs)("div", { css: __1.Css.if(labelStyle === "left").w50.$, children: [values.map((value, index) => {
|
|
17
|
+
return ((0, jsx_runtime_1.jsxs)("div", { css: __1.Css.mb1.pl1.df.$, children: [(0, jsx_runtime_1.jsx)("div", { css: __1.Css.truncate.w100.$, children: (0, jsx_runtime_1.jsx)(inputs_1.SelectField, { ...otherProps, ...tid.selectField, labelStyle: "hidden", value: value, onSelect: () => { }, options: options, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, compact: true, readOnly: true }) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { ...tid.deleteSelected, variant: "tertiary", label: "", "aria-label": `Delete selected ${otherProps.label}`, icon: "x", onClick: () => {
|
|
18
|
+
const selectedOptions = options.filter((o) => values.includes(getOptionValue(o)) && getOptionValue(o) !== value);
|
|
19
|
+
const selectedValues = selectedOptions.map((o) => getOptionValue(o));
|
|
20
|
+
onSelect(selectedValues, selectedOptions);
|
|
21
|
+
// Display the input field if there are no selected values
|
|
22
|
+
if (selectedOptions.length === 0)
|
|
23
|
+
setIsDisplayed(true);
|
|
24
|
+
} })] }, index));
|
|
25
|
+
}), isDisplayed && ((0, jsx_runtime_1.jsx)("div", { css: __1.Css.mb1.$, children: (0, jsx_runtime_1.jsx)(inputs_1.SelectField, { ...tid.selectField, label: otherProps.label, labelStyle: "hidden", getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, value: "", onSelect: (value) => {
|
|
26
|
+
onSelect([...values, value], options);
|
|
27
|
+
setIsDisplayed(false);
|
|
28
|
+
}, options: currentOptions, disabled: otherProps.disabled }) })), (0, jsx_runtime_1.jsx)(Button_1.Button, { ...tid.addAnother, label: "Add Another", variant: "tertiary", onClick: () => setIsDisplayed(true), disabled: isDisplayed || currentOptions.length === 0 })] })] }));
|
|
29
|
+
}
|
|
30
|
+
exports.MultiLineSelectField = MultiLineSelectField;
|
package/dist/inputs/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./Checkbox";
|
|
|
2
2
|
export * from "./CheckboxGroup";
|
|
3
3
|
export * from "./ChipSelectField";
|
|
4
4
|
export * from "./DateFields";
|
|
5
|
+
export * from "./MultiLineSelectField";
|
|
5
6
|
export * from "./MultiSelectField";
|
|
6
7
|
export * from "./NumberField";
|
|
7
8
|
export type { NumberFieldProps } from "./NumberField";
|
package/dist/inputs/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./Checkbox"), exports);
|
|
|
19
19
|
__exportStar(require("./CheckboxGroup"), exports);
|
|
20
20
|
__exportStar(require("./ChipSelectField"), exports);
|
|
21
21
|
__exportStar(require("./DateFields"), exports);
|
|
22
|
+
__exportStar(require("./MultiLineSelectField"), exports);
|
|
22
23
|
__exportStar(require("./MultiSelectField"), exports);
|
|
23
24
|
__exportStar(require("./NumberField"), exports);
|
|
24
25
|
var RadioGroupField_1 = require("./RadioGroupField");
|