@homebound/beam 2.227.1 → 2.228.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.
Files changed (35) hide show
  1. package/dist/components/Filters/BooleanFilter.js +1 -1
  2. package/dist/components/Filters/DateFilter.js +1 -1
  3. package/dist/components/Filters/DateRangeFilter.js +1 -1
  4. package/dist/components/Filters/Filters.js +1 -1
  5. package/dist/components/Filters/MultiFilter.js +1 -1
  6. package/dist/components/Filters/NumberRangeFilter.js +4 -4
  7. package/dist/components/Filters/SingleFilter.js +1 -1
  8. package/dist/components/Layout/ScrollableContent.d.ts +9 -1
  9. package/dist/components/Layout/ScrollableContent.js +9 -1
  10. package/dist/components/Layout/ScrollableParent.d.ts +24 -0
  11. package/dist/components/Layout/ScrollableParent.js +24 -0
  12. package/dist/components/Modal/TestModalContent.js +1 -1
  13. package/dist/components/PresentationContext.d.ts +2 -1
  14. package/dist/components/Table/GridTable.js +1 -1
  15. package/dist/components/Table/components/EditColumnsButton.js +1 -1
  16. package/dist/components/internal/Menu.js +2 -2
  17. package/dist/forms/FormStateApp.js +1 -1
  18. package/dist/inputs/CheckboxGroup.d.ts +2 -3
  19. package/dist/inputs/CheckboxGroup.js +5 -2
  20. package/dist/inputs/DateFields/DateFieldBase.d.ts +1 -3
  21. package/dist/inputs/DateFields/DateFieldBase.js +2 -2
  22. package/dist/inputs/NumberField.d.ts +2 -3
  23. package/dist/inputs/RadioGroupField.d.ts +2 -2
  24. package/dist/inputs/RadioGroupField.js +3 -3
  25. package/dist/inputs/Switch.d.ts +1 -1
  26. package/dist/inputs/Switch.js +3 -2
  27. package/dist/inputs/TextField.d.ts +0 -1
  28. package/dist/inputs/TextFieldBase.d.ts +1 -2
  29. package/dist/inputs/TextFieldBase.js +10 -10
  30. package/dist/inputs/internal/MenuSearchField.d.ts +0 -1
  31. package/dist/inputs/internal/SelectFieldBase.d.ts +0 -2
  32. package/dist/inputs/internal/SelectFieldBase.js +1 -1
  33. package/dist/inputs/internal/SelectFieldInput.d.ts +0 -1
  34. package/dist/inputs/internal/SelectFieldInput.js +2 -2
  35. package/package.json +1 -1
@@ -14,7 +14,7 @@ class BooleanFilter extends BaseFilter_1.BaseFilter {
14
14
  const { options = defaultBooleanOptions, label, defaultValue, ...props } = this.props;
15
15
  return ((0, jsx_runtime_1.jsx)(SelectField_1.SelectField, { ...props, compact: !vertical, label: this.label,
16
16
  // We use `String(value)` so that `undefined` becomes "undefined"
17
- value: String(value), hideLabel: inModal, inlineLabel: !inModal && !vertical, sizeToContent: !inModal && !vertical, options: options, getOptionValue: (o) => String(o[0]), getOptionLabel: (o) => o[1], onSelect: (value) => {
17
+ value: String(value), labelStyle: inModal ? "hidden" : !inModal && !vertical ? "inline" : "above", sizeToContent: !inModal && !vertical, options: options, getOptionValue: (o) => String(o[0]), getOptionLabel: (o) => o[1], onSelect: (value) => {
18
18
  // Change our string "true" / "false" / "undefined" back to boolean | undefined
19
19
  const parsedValue = value === "undefined" ? undefined : value === "true";
20
20
  setValue(parsedValue);
@@ -22,6 +22,6 @@ class DateFilter extends BaseFilter_1.BaseFilter {
22
22
  ...operations,
23
23
  ], getOptionValue: (o) => (o === anyOption ? undefined : getOperationValue(o)), getOptionLabel: (o) => (o === anyOption ? "Any" : getOperationLabel(o)), value: value === null || value === void 0 ? void 0 : value.op, onSelect: (op) =>
24
24
  // default the selected date to today if it doesn't exist in the filter's value
25
- setValue(op ? { op, value: (value === null || value === void 0 ? void 0 : value.value) ? new Date(value.value) : new Date() } : undefined), label: inModal ? `${label} date filter operation` : label, inlineLabel: !inModal && !vertical, hideLabel: inModal || vertical, nothingSelectedText: "Any", ...tid[`${(0, defaultTestId_1.defaultTestId)(this.label)}_dateOperation`] }), (0, jsx_runtime_1.jsx)(inputs_1.DateField, { compact: true, inlineLabel: true, value: (value === null || value === void 0 ? void 0 : value.value) ? new Date(value.value) : new Date(), label: "Date", onChange: (d) => setValue({ ...value, value: d }), disabled: !value, ...tid[`${(0, defaultTestId_1.defaultTestId)(this.label)}_dateField`] })] })] }));
25
+ setValue(op ? { op, value: (value === null || value === void 0 ? void 0 : value.value) ? new Date(value.value) : new Date() } : undefined), label: inModal ? `${label} date filter operation` : label, labelStyle: !inModal && !vertical ? "inline" : inModal || vertical ? "hidden" : "above", nothingSelectedText: "Any", ...tid[`${(0, defaultTestId_1.defaultTestId)(this.label)}_dateOperation`] }), (0, jsx_runtime_1.jsx)(inputs_1.DateField, { compact: true, labelStyle: "inline", value: (value === null || value === void 0 ? void 0 : value.value) ? new Date(value.value) : new Date(), label: "Date", onChange: (d) => setValue({ ...value, value: d }), disabled: !value, ...tid[`${(0, defaultTestId_1.defaultTestId)(this.label)}_dateField`] })] })] }));
26
26
  }
27
27
  }
@@ -13,7 +13,7 @@ exports.dateRangeFilter = dateRangeFilter;
13
13
  class DateRangeFilter extends BaseFilter_1.BaseFilter {
14
14
  render(value, setValue, tid, inModal, vertical) {
15
15
  const { label, placeholderText, disabledDays, testFieldLabel, defaultValue } = this.props;
16
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [vertical && (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }), (0, jsx_runtime_1.jsx)(inputs_1.DateRangeField, { compact: true, inlineLabel: true, isRangeFilterField: true, placeholder: placeholderText, label: testFieldLabel !== null && testFieldLabel !== void 0 ? testFieldLabel : "Date",
16
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [vertical && (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }), (0, jsx_runtime_1.jsx)(inputs_1.DateRangeField, { compact: true, labelStyle: "inline", isRangeFilterField: true, placeholder: placeholderText, label: testFieldLabel !== null && testFieldLabel !== void 0 ? testFieldLabel : "Date",
17
17
  // Making sure that DateRange is Date type and not string before passing. Will never have undefined from/to
18
18
  value: (value === null || value === void 0 ? void 0 : value.value)
19
19
  ? { from: new Date(value.value.from), to: new Date(value.value.to) }
@@ -28,7 +28,7 @@ function Filters(props) {
28
28
  return [Object.fromEntries(impls), {}];
29
29
  }, [numberOfInlineFilters, vertical, filterDefs]);
30
30
  const numModalFilters = (0, utils_1.safeKeys)(modalFilters).filter((fk) => filter[fk] !== undefined).length;
31
- const maybeGroupByField = groupBy ? ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SelectField_1.SelectField, { label: "Group by", compact: !vertical, inlineLabel: !vertical, sizeToContent: !vertical, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }) })) : null;
31
+ const maybeGroupByField = groupBy ? ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SelectField_1.SelectField, { label: "Group by", compact: !vertical, labelStyle: !vertical ? "inline" : "above", sizeToContent: !vertical, options: groupBy.options, getOptionValue: (o) => o.id, getOptionLabel: (o) => o.name, value: groupBy.value, onSelect: (g) => g && groupBy.setValue(g) }) })) : null;
32
32
  // Return list of filter components. `onSelect` should update the `filter`
33
33
  return ((0, jsx_runtime_1.jsxs)("div", { css: {
34
34
  ...(vertical ? Css_1.Css.df.fdc.gap2.$ : Css_1.Css.df.aic.gap1.$),
@@ -21,7 +21,7 @@ class MultiFilter extends BaseFilter_1.BaseFilter {
21
21
  }, values: value || [], hideLabel: true, ...tid[(0, defaultTestId_1.defaultTestId)(this.label)] }));
22
22
  }
23
23
  const { defaultValue, ...props } = this.props;
24
- return ((0, jsx_runtime_1.jsx)(MultiSelectField_1.MultiSelectField, { ...props, compact: !vertical, label: this.label, values: value || [], hideLabel: inModal, inlineLabel: !inModal && !vertical, sizeToContent: !inModal && !vertical, onSelect: (values) => {
24
+ return ((0, jsx_runtime_1.jsx)(MultiSelectField_1.MultiSelectField, { ...props, compact: !vertical, label: this.label, values: value || [], labelStyle: inModal ? "hidden" : !inModal && !vertical ? "inline" : "above", sizeToContent: !inModal && !vertical, onSelect: (values) => {
25
25
  setValue(values.length === 0 ? undefined : values);
26
26
  }, nothingSelectedText: "All", ...this.testId(tid) }));
27
27
  }
@@ -18,18 +18,18 @@ class NumberRangeFilter extends BaseFilter_1.BaseFilter {
18
18
  const { label, numberFieldType } = this.props;
19
19
  const min = (_a = value === null || value === void 0 ? void 0 : value.min) !== null && _a !== void 0 ? _a : undefined;
20
20
  const max = (_b = value === null || value === void 0 ? void 0 : value.max) !== null && _b !== void 0 ? _b : undefined;
21
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [vertical && ((0, jsx_runtime_1.jsxs)("div", { ...tid, children: [(0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.pb1.$, children: (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { inlineLabel: true, clearable: true, label: "Min", value: min, type: numberFieldType, onChange: (minVal) => {
21
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [vertical && ((0, jsx_runtime_1.jsxs)("div", { ...tid, children: [(0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.pb1.$, children: (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { labelStyle: "inline", clearable: true, label: "Min", value: min, type: numberFieldType, onChange: (minVal) => {
22
22
  const maxValue = max ? { max } : {};
23
23
  setValue(minVal || max ? { min: minVal, ...maxValue } : undefined);
24
- }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_min_vertical`] }) }), (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { inlineLabel: true, clearable: true, label: "Max", value: max, type: numberFieldType, onChange: (maxVal) => {
24
+ }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_min_vertical`] }) }), (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { labelStyle: "inline", clearable: true, label: "Max", value: max, type: numberFieldType, onChange: (maxVal) => {
25
25
  const minValue = min ? { min } : {};
26
26
  setValue(maxVal || min ? { max: maxVal, ...minValue } : undefined);
27
- }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_max_vertical`] })] })), !vertical && ((0, jsx_runtime_1.jsxs)(CompoundField_1.CompoundField, { ...tid, children: [(0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { compact: true, sizeToContent: !inModal, inlineLabel: true, clearable: true,
27
+ }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_max_vertical`] })] })), !vertical && ((0, jsx_runtime_1.jsxs)(CompoundField_1.CompoundField, { ...tid, children: [(0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { compact: true, sizeToContent: !inModal, labelStyle: "inline", clearable: true,
28
28
  // When in horizontal view, we combine the filter label with the min / max labels as all filter labels are displayed inline
29
29
  label: !inModal ? `${label} Min` : "Min", value: min, type: numberFieldType, onChange: (minVal) => {
30
30
  const maxValue = max ? { max } : {};
31
31
  setValue(minVal || max ? { min: minVal, ...maxValue } : undefined);
32
- }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_min`] }), (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { compact: true, sizeToContent: !inModal, inlineLabel: true, clearable: true, label: !inModal ? `${label} Max` : "Max", value: max, type: numberFieldType, onChange: (maxVal) => {
32
+ }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_min`] }), (0, jsx_runtime_1.jsx)(NumberField_1.NumberField, { compact: true, sizeToContent: !inModal, labelStyle: "inline", clearable: true, label: !inModal ? `${label} Max` : "Max", value: max, type: numberFieldType, onChange: (maxVal) => {
33
33
  const minValue = min ? { min } : {};
34
34
  setValue(maxVal || min ? { max: maxVal, ...minValue } : undefined);
35
35
  }, ...tid[`${(0, defaultTestId_1.defaultTestId)(label)}_max`] })] }))] }));
@@ -16,6 +16,6 @@ class SingleFilter extends BaseFilter_1.BaseFilter {
16
16
  const options = Array.isArray(maybeOptions)
17
17
  ? [allOption, ...maybeOptions]
18
18
  : { ...maybeOptions, initial: [allOption, ...maybeOptions.initial] };
19
- return ((0, jsx_runtime_1.jsx)(SelectField_1.SelectField, { ...props, options: options, getOptionValue: (o) => (o === allOption ? undefined : getOptionValue(o)), getOptionLabel: (o) => (o === allOption ? "All" : getOptionLabel(o)), compact: !vertical, value: value, label: this.label, inlineLabel: !inModal && !vertical, hideLabel: inModal, sizeToContent: !inModal && !vertical, nothingSelectedText: "All", onSelect: (value) => setValue(value || undefined), ...this.testId(tid) }));
19
+ return ((0, jsx_runtime_1.jsx)(SelectField_1.SelectField, { ...props, options: options, getOptionValue: (o) => (o === allOption ? undefined : getOptionValue(o)), getOptionLabel: (o) => (o === allOption ? "All" : getOptionLabel(o)), compact: !vertical, value: value, label: this.label, labelStyle: inModal ? "hidden" : !inModal && !vertical ? "inline" : "above", sizeToContent: !inModal && !vertical, nothingSelectedText: "All", onSelect: (value) => setValue(value || undefined), ...this.testId(tid) }));
20
20
  }
21
21
  }
@@ -6,6 +6,14 @@ interface ScrollableContentProps {
6
6
  omitBottomPadding?: true;
7
7
  bgColor?: Palette;
8
8
  }
9
- /** Helper component for placing scrollable content within a `ScrollableParent`. */
9
+ /**
10
+ * Helper component for placing scrollable content within a `ScrollableParent`.
11
+ *
12
+ * See the docs on `ScrollableParent.
13
+ *
14
+ * Note that you should not use this "just to get a scrollbar", instead just use `Css.overflowAuto.$`
15
+ * or what not; this is only for implementing page-level patterns that need multiple stickied
16
+ * components (page header, tab bar, table filter & actions).
17
+ */
10
18
  export declare function ScrollableContent(props: ScrollableContentProps): ReactPortal | JSX.Element;
11
19
  export {};
@@ -6,7 +6,15 @@ const react_1 = require("react");
6
6
  const react_dom_1 = require("react-dom");
7
7
  const ScrollableParent_1 = require("./ScrollableParent");
8
8
  const Css_1 = require("../../Css");
9
- /** Helper component for placing scrollable content within a `ScrollableParent`. */
9
+ /**
10
+ * Helper component for placing scrollable content within a `ScrollableParent`.
11
+ *
12
+ * See the docs on `ScrollableParent.
13
+ *
14
+ * Note that you should not use this "just to get a scrollbar", instead just use `Css.overflowAuto.$`
15
+ * or what not; this is only for implementing page-level patterns that need multiple stickied
16
+ * components (page header, tab bar, table filter & actions).
17
+ */
10
18
  function ScrollableContent(props) {
11
19
  const { children, virtualized = false, omitBottomPadding, bgColor } = props;
12
20
  const { scrollableEl, setPortalTick, pl, pr } = (0, ScrollableParent_1.useScrollableParent)();
@@ -10,6 +10,30 @@ interface ScrollableParentContextProviderProps {
10
10
  xss?: Properties;
11
11
  tagName?: keyof JSX.IntrinsicElements;
12
12
  }
13
+ /**
14
+ * Provides a pattern for implementing "multiple sticky" components.
15
+ *
16
+ * In css, `position: sticky` is great for pinning 1 element to the top of a container.
17
+ *
18
+ * However, in UX patterns, we're often asked to pin multiple DOM elements that are actually
19
+ * spread across multiple React components. For example:
20
+ *
21
+ * - Sticky a Header (in FooPage)
22
+ * - Sticky the table filter & actions (in FooTable)
23
+ * - Sticky the table header row(s) (in GridTable)
24
+ *
25
+ * Historically the way we did this was passing `stickyOffset`s around, where the header would be
26
+ * `top: 0px`, the filter & actions would be `top: ${headerPx}px`, and the table header rows would
27
+ * be `top: ${headerPx + filterActionsPx}px`.
28
+ *
29
+ * However, this is brittle as the `headerPx` / `filterActionsPx` are likely dynamic.
30
+ *
31
+ * `ScrollableParent` solves this by putting all the stickied content (except the table header rows)
32
+ * into a single div, and then having the page use `ScrollableContent` to mark what should actually
33
+ * scroll, which then we "pull up" to be a sibling div of "everything that was stickied".
34
+ *
35
+ * See [this miro](https://miro.com/app/board/o9J_l-FQ-RU=/) and how we need to "cut the component in half".
36
+ */
13
37
  export declare function ScrollableParent(props: PropsWithChildren<ScrollableParentContextProviderProps>): import("@emotion/react/jsx-runtime").JSX.Element;
14
38
  export declare function useScrollableParent(): ScrollableParentContextProps;
15
39
  export declare const scrollContainerBottomPadding: {
@@ -10,6 +10,30 @@ const ScrollableParentContext = (0, react_1.createContext)({
10
10
  pl: 0,
11
11
  setPortalTick: (v) => { },
12
12
  });
13
+ /**
14
+ * Provides a pattern for implementing "multiple sticky" components.
15
+ *
16
+ * In css, `position: sticky` is great for pinning 1 element to the top of a container.
17
+ *
18
+ * However, in UX patterns, we're often asked to pin multiple DOM elements that are actually
19
+ * spread across multiple React components. For example:
20
+ *
21
+ * - Sticky a Header (in FooPage)
22
+ * - Sticky the table filter & actions (in FooTable)
23
+ * - Sticky the table header row(s) (in GridTable)
24
+ *
25
+ * Historically the way we did this was passing `stickyOffset`s around, where the header would be
26
+ * `top: 0px`, the filter & actions would be `top: ${headerPx}px`, and the table header rows would
27
+ * be `top: ${headerPx + filterActionsPx}px`.
28
+ *
29
+ * However, this is brittle as the `headerPx` / `filterActionsPx` are likely dynamic.
30
+ *
31
+ * `ScrollableParent` solves this by putting all the stickied content (except the table header rows)
32
+ * into a single div, and then having the page use `ScrollableContent` to mark what should actually
33
+ * scroll, which then we "pull up" to be a sibling div of "everything that was stickied".
34
+ *
35
+ * See [this miro](https://miro.com/app/board/o9J_l-FQ-RU=/) and how we need to "cut the component in half".
36
+ */
13
37
  function ScrollableParent(props) {
14
38
  const { children, xss, tagName: Tag = "div" } = props;
15
39
  const scrollableEl = (0, react_1.useMemo)(() => {
@@ -24,7 +24,7 @@ function TestModalContent(props) {
24
24
  const [date, setDate] = (0, react_1.useState)(formStateDomain_1.jan1);
25
25
  const [internalValue, setValue] = (0, react_1.useState)("");
26
26
  const { triggerNotice } = (0, Snackbar_1.useSnackbar)();
27
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { children: props.withTag ? ((0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.aic.$, children: [(0, jsx_runtime_1.jsx)("span", { children: "Modal Title with Tag" }), (0, jsx_runtime_1.jsx)(Tag_1.Tag, { text: "In progress", type: "info", xss: Css_1.Css.ml1.$ })] })) : props.withTextArea ? ((0, jsx_runtime_1.jsx)(inputs_1.TextAreaField, { label: "Title", placeholder: "Test title", value: internalValue, onChange: (v) => setValue(v), preventNewLines: true, hideLabel: true, borderless: true, xss: Css_1.Css.xl.$ })) : ("The title of the modal that might wrap") }), (0, jsx_runtime_1.jsxs)(Modal_1.ModalBody, { children: [(0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.fdc.aifs.$, children: [(0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.$, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { label: "More", onClick: () => setNumSentences(numSentences + 2) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Clear", onClick: () => setNumSentences(0) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Primary", onClick: () => setPrimaryDisabled(!primaryDisabled) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Trigger Snackbar", onClick: () => triggerNotice({ message: "Snackbar message" }) }), showLeftAction && ((0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Left Action", onClick: () => setLeftActionDisabled(!leftActionDisabled) }))] }), (0, jsx_runtime_1.jsx)("p", { children: "The body content of the modal. This content can be anything!".repeat(numSentences) })] }), withDateField && (0, jsx_runtime_1.jsx)(inputs_1.DateField, { value: date, label: "Date", onChange: setDate })] }), (0, jsx_runtime_1.jsxs)(Modal_1.ModalFooter, { xss: showLeftAction ? Css_1.Css.jcsb.$ : undefined, children: [showLeftAction && ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Clear", onClick: (0, addon_actions_1.action)("Clear Action"), variant: "tertiary", disabled: leftActionDisabled }) })), (0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.$, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Cancel", onClick: closeModal, variant: "tertiary" }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Apply", onClick: (0, addon_actions_1.action)("Primary action"), disabled: primaryDisabled })] })] })] }));
27
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Modal_1.ModalHeader, { children: props.withTag ? ((0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.aic.$, children: [(0, jsx_runtime_1.jsx)("span", { children: "Modal Title with Tag" }), (0, jsx_runtime_1.jsx)(Tag_1.Tag, { text: "In progress", type: "info", xss: Css_1.Css.ml1.$ })] })) : props.withTextArea ? ((0, jsx_runtime_1.jsx)(inputs_1.TextAreaField, { label: "Title", placeholder: "Test title", value: internalValue, onChange: (v) => setValue(v), preventNewLines: true, labelStyle: "hidden", borderless: true, xss: Css_1.Css.xl.$ })) : ("The title of the modal that might wrap") }), (0, jsx_runtime_1.jsxs)(Modal_1.ModalBody, { children: [(0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.fdc.aifs.$, children: [(0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.$, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { label: "More", onClick: () => setNumSentences(numSentences + 2) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Clear", onClick: () => setNumSentences(0) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Primary", onClick: () => setPrimaryDisabled(!primaryDisabled) }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Trigger Snackbar", onClick: () => triggerNotice({ message: "Snackbar message" }) }), showLeftAction && ((0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Left Action", onClick: () => setLeftActionDisabled(!leftActionDisabled) }))] }), (0, jsx_runtime_1.jsx)("p", { children: "The body content of the modal. This content can be anything!".repeat(numSentences) })] }), withDateField && (0, jsx_runtime_1.jsx)(inputs_1.DateField, { value: date, label: "Date", onChange: setDate })] }), (0, jsx_runtime_1.jsxs)(Modal_1.ModalFooter, { xss: showLeftAction ? Css_1.Css.jcsb.$ : undefined, children: [showLeftAction && ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Clear", onClick: (0, addon_actions_1.action)("Clear Action"), variant: "tertiary", disabled: leftActionDisabled }) })), (0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.gap1.$, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Cancel", onClick: closeModal, variant: "tertiary" }), (0, jsx_runtime_1.jsx)(Button_1.Button, { label: "Apply", onClick: (0, addon_actions_1.action)("Primary action"), disabled: primaryDisabled })] })] })] }));
28
28
  }
29
29
  exports.TestModalContent = TestModalContent;
30
30
  function TestModalFilterTable() {
@@ -3,7 +3,8 @@ import { GridStyle } from "./Table";
3
3
  import { Typography } from "../Css";
4
4
  export interface PresentationFieldProps {
5
5
  numberAlignment?: "left" | "right";
6
- hideLabel?: boolean;
6
+ /** Sets the label position or visibility. Defaults to "above" */
7
+ labelStyle?: "inline" | "hidden" | "above" | "left";
7
8
  labelSuffix?: LabelSuffixStyle;
8
9
  borderless?: boolean;
9
10
  compact?: boolean;
@@ -216,7 +216,7 @@ function GridTable(props) {
216
216
  const borderless = (_a = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _a === void 0 ? void 0 : _a.borderless;
217
217
  const typeScale = (_b = style === null || style === void 0 ? void 0 : style.presentationSettings) === null || _b === void 0 ? void 0 : _b.typeScale;
218
218
  const fieldProps = (0, react_1.useMemo)(() => ({
219
- hideLabel: true,
219
+ labelStyle: "hidden",
220
220
  numberAlignment: "right",
221
221
  compact: true,
222
222
  errorInTooltip: true,
@@ -37,6 +37,6 @@ function EditColumnsButton(props) {
37
37
  return ((0, jsx_runtime_1.jsx)(OverlayTrigger_1.OverlayTrigger, { ...props, menuTriggerProps: menuTriggerProps, state: state, buttonRef: buttonRef, ...tid, children: (0, jsx_runtime_1.jsxs)("div", { css: {
38
38
  ...Css_1.Css.bgWhite.py5.px3.maxwPx(380).bshBasic.$,
39
39
  "&:hover": Css_1.Css.bshHover.$,
40
- }, children: [(0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.gray500.xsSb.mb1.ttu.$, children: title || "Select columns to show" }), (0, jsx_runtime_1.jsx)(inputs_1.CheckboxGroup, { label: title || "Select columns to show", onChange: (values) => setSelectedValues(values), values: selectedValues, options: options, columns: 2, hideLabel: true }), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.mt1.$, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "tertiary", label: "Clear selections", onClick: () => setSelectedValues([]) }) })] }) }));
40
+ }, children: [(0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.gray500.xsSb.mb1.ttu.$, children: title || "Select columns to show" }), (0, jsx_runtime_1.jsx)(inputs_1.CheckboxGroup, { label: title || "Select columns to show", onChange: (values) => setSelectedValues(values), values: selectedValues, options: options, columns: 2, labelStyle: "hidden" }), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.mt1.$, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { variant: "tertiary", label: "Clear selections", onClick: () => setSelectedValues([]) }) })] }) }));
41
41
  }
42
42
  exports.EditColumnsButton = EditColumnsButton;
@@ -20,7 +20,7 @@ function Menu(props) {
20
20
  getChildren: (item) => { var _a; return (_a = item.items) !== null && _a !== void 0 ? _a : []; },
21
21
  });
22
22
  const [search, setSearch] = (0, react_1.useState)(undefined);
23
- let { contains } = (0, react_aria_1.useFilter)({
23
+ const { contains } = (0, react_aria_1.useFilter)({
24
24
  sensitivity: "base",
25
25
  });
26
26
  // Filter our tree data items based on the search term
@@ -62,6 +62,6 @@ function Menu(props) {
62
62
  css: {
63
63
  ...Css_1.Css.df.fdc.myPx(4).bgWhite.outline0.br4.bshBasic.maxh("inherit").overflowAuto.$,
64
64
  "&:hover": Css_1.Css.bshHover.$,
65
- }, children: [searchable && ((0, jsx_runtime_1.jsx)(MenuSearchField_1.MenuSearchField, { label: "", value: search, placeholder: "Search...", inlineLabel: true, onChange: setSearch, ...tid })), (0, jsx_runtime_1.jsx)("ul", { css: Css_1.Css.listReset.$, ...menuProps, ref: menuRef, ...tid.menu, children: [...state.collection].map((item) => ((0, jsx_runtime_1.jsx)(MenuSection_1.MenuSectionImpl, { section: item, state: state, onClose: onClose, ...tid }, item.key))) })] }) }));
65
+ }, children: [searchable && ((0, jsx_runtime_1.jsx)(MenuSearchField_1.MenuSearchField, { label: "", value: search, placeholder: "Search...", labelStyle: "inline", onChange: setSearch, ...tid })), (0, jsx_runtime_1.jsx)("ul", { css: Css_1.Css.listReset.$, ...menuProps, ref: menuRef, ...tid.menu, children: [...state.collection].map((item) => ((0, jsx_runtime_1.jsx)(MenuSection_1.MenuSectionImpl, { section: item, state: state, onClose: onClose, ...tid }, item.key))) })] }) }));
66
66
  }
67
67
  exports.Menu = Menu;
@@ -68,7 +68,7 @@ function createColumns(formState) {
68
68
  { header: "#", data: ({ id }) => (0, jsx_runtime_1.jsx)("span", { children: id.value }) },
69
69
  {
70
70
  header: "Title",
71
- data: ({ title }) => (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { label: "Book Title", hideLabel: true, compact: true, field: title }),
71
+ data: ({ title }) => (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { label: "Book Title", labelStyle: "hidden", compact: true, field: title }),
72
72
  },
73
73
  {
74
74
  header: "Actions",
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from "react";
2
+ import { PresentationFieldProps } from "../components/PresentationContext";
2
3
  export interface CheckboxGroupItemOption {
3
4
  /** Additional text displayed below label */
4
5
  description?: string;
@@ -7,7 +8,7 @@ export interface CheckboxGroupItemOption {
7
8
  /** The value of the CheckboxGroup item, stored in value array in state. */
8
9
  value: string;
9
10
  }
10
- export interface CheckboxGroupProps {
11
+ export interface CheckboxGroupProps extends Pick<PresentationFieldProps, "labelStyle"> {
11
12
  label: string;
12
13
  /** Called when a checkbox is selected or deselected */
13
14
  onChange: (values: string[]) => void;
@@ -23,7 +24,5 @@ export interface CheckboxGroupProps {
23
24
  onFocus?: () => void;
24
25
  /** Number of columns to display checkboxes */
25
26
  columns?: number;
26
- /** Hide label if it is not needed */
27
- hideLabel?: boolean;
28
27
  }
29
28
  export declare function CheckboxGroup(props: CheckboxGroupProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -7,16 +7,19 @@ const react_aria_1 = require("react-aria");
7
7
  const react_stately_1 = require("react-stately");
8
8
  const HelperText_1 = require("../components/HelperText");
9
9
  const Label_1 = require("../components/Label");
10
+ const PresentationContext_1 = require("../components/PresentationContext");
10
11
  const Css_1 = require("../Css");
11
12
  const CheckboxBase_1 = require("./CheckboxBase");
12
13
  const ErrorMessage_1 = require("./ErrorMessage");
13
14
  const utils_1 = require("../utils");
14
15
  function CheckboxGroup(props) {
15
- const { options, label, values, errorMsg, helperText, onBlur, onFocus, columns = 1, hideLabel = false } = props;
16
+ var _a;
17
+ const { fieldProps } = (0, PresentationContext_1.usePresentationContext)();
18
+ const { options, label, labelStyle = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.labelStyle) !== null && _a !== void 0 ? _a : "above", values, errorMsg, helperText, onBlur, onFocus, columns = 1, } = props;
16
19
  const state = (0, react_stately_1.useCheckboxGroupState)({ ...props, value: values });
17
20
  const { groupProps, labelProps } = (0, react_aria_1.useCheckboxGroup)(props, state);
18
21
  const tid = (0, utils_1.useTestIds)(props);
19
- return ((0, jsx_runtime_1.jsxs)("div", { ...groupProps, onBlur: onBlur, onFocus: onFocus, ...tid, children: [!hideLabel && (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label, ...labelProps, ...tid.label }), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.dg.gtc(`repeat(${columns}, auto)`).gap2.$, children: options.map((option) => ((0, jsx_runtime_1.jsx)(CheckboxGroupItem, { ...option, groupState: state, selected: state.value.includes(option.value) }, option.value))) }), errorMsg && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { errorMsg: errorMsg, ...tid.errorMsg }), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, { helperText: helperText, ...tid.helperText })] }));
22
+ return ((0, jsx_runtime_1.jsxs)("div", { ...groupProps, css: Css_1.Css.if(labelStyle === "left").df.fdr.$, onBlur: onBlur, onFocus: onFocus, ...tid, children: [labelStyle !== "hidden" && ((0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.if(labelStyle === "left").w50.$, children: (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label, ...labelProps, ...tid.label }) })), (0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.dg.gtc(`repeat(${columns}, auto)`).gap2.$, children: options.map((option) => ((0, jsx_runtime_1.jsx)(CheckboxGroupItem, { ...option, groupState: state, selected: state.value.includes(option.value) }, option.value))) }), errorMsg && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { errorMsg: errorMsg, ...tid.errorMsg }), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, { helperText: helperText, ...tid.helperText })] }));
20
23
  }
21
24
  exports.CheckboxGroup = CheckboxGroup;
22
25
  function CheckboxGroupItem(props) {
@@ -3,7 +3,7 @@ import { Matcher } from "react-day-picker";
3
3
  import { DateFieldMode, dateFormats } from "./utils";
4
4
  import { TextFieldBaseProps } from "../TextFieldBase";
5
5
  import { DateRange } from "../../types";
6
- export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "hideLabel" | "compact"> {
6
+ export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<{}>, "borderless" | "visuallyDisabled" | "labelStyle" | "compact"> {
7
7
  label: string;
8
8
  /** Called when the component loses focus */
9
9
  onBlur?: () => void;
@@ -16,8 +16,6 @@ export interface DateFieldBaseProps extends Pick<TextFieldBaseProps<{}>, "border
16
16
  /** Whether the field is readOnly. If a ReactNode, it's treated as a "readOnly reason" that's shown in a tooltip. */
17
17
  readOnly?: boolean | ReactNode;
18
18
  helperText?: string | ReactNode;
19
- /** Renders the label inside the input field, i.e. for filters. */
20
- inlineLabel?: boolean;
21
19
  placeholder?: string;
22
20
  format?: keyof typeof dateFormats;
23
21
  iconLeft?: boolean;
@@ -18,7 +18,7 @@ function DateFieldBase(props) {
18
18
  var _a;
19
19
  const { label, disabled, required, value, onFocus, onBlur,
20
20
  // Pull `onChange` out of the props, but we're not directly using it. Do not want to keep it in `...others`
21
- onChange: _onChange, errorMsg, helperText, inlineLabel = false, readOnly, format = "short", iconLeft = false, hideCalendarIcon = false, disabledDays, onEnter, defaultOpen, mode, isRangeFilterField = false, ...others } = props;
21
+ onChange: _onChange, errorMsg, helperText, readOnly, format = "short", iconLeft = false, hideCalendarIcon = false, disabledDays, onEnter, defaultOpen, mode, isRangeFilterField = false, ...others } = props;
22
22
  const isRangeMode = mode === "range";
23
23
  const inputRef = (0, react_1.useRef)(null);
24
24
  const inputWrapRef = (0, react_1.useRef)(null);
@@ -160,7 +160,7 @@ function DateFieldBase(props) {
160
160
  } })) }));
161
161
  const calendarButton = ((0, jsx_runtime_1.jsx)("button", { 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: isDisabled ? Css_1.Palette.Gray400 : Css_1.Palette.Gray700 }) }));
162
162
  const EndFieldButtons = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [isRangeFilterField && clearButton, !hideCalendarIcon && calendarButton] }));
163
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, { ...textFieldProps, errorMsg: errorMsg, helperText: helperText, required: required, labelProps: labelProps, inputProps: { ...inputProps, size: inputSize }, inputRef: inputRef, inputWrapRef: inputWrapRef, inlineLabel: inlineLabel, onChange: (v) => {
163
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, { ...textFieldProps, errorMsg: errorMsg, helperText: helperText, required: required, labelProps: labelProps, inputProps: { ...inputProps, size: inputSize }, inputRef: inputRef, inputWrapRef: inputWrapRef, onChange: (v) => {
164
164
  // hide the calendar if the user is manually entering the date
165
165
  state.close();
166
166
  if (v) {
@@ -1,10 +1,10 @@
1
1
  import { ReactNode } from "react";
2
+ import { PresentationFieldProps } from "../components/PresentationContext";
2
3
  import { Xss } from "../Css";
3
4
  export type NumberFieldType = "cents" | "dollars" | "percent" | "basisPoints" | "days";
4
- export interface NumberFieldProps {
5
+ export interface NumberFieldProps extends Pick<PresentationFieldProps, "labelStyle"> {
5
6
  label: string;
6
7
  /** If set, the label will be defined as 'aria-label` on the input element */
7
- hideLabel?: boolean;
8
8
  type?: NumberFieldType;
9
9
  value: number | undefined;
10
10
  onChange: (value: number | undefined) => void;
@@ -33,7 +33,6 @@ export interface NumberFieldProps {
33
33
  useGrouping?: boolean;
34
34
  hideErrorMessage?: boolean;
35
35
  borderless?: boolean;
36
- inlineLabel?: boolean;
37
36
  sizeToContent?: boolean;
38
37
  }
39
38
  export declare function NumberField(props: NumberFieldProps): import("@emotion/react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from "react";
2
+ import { PresentationFieldProps } from "../components/PresentationContext";
2
3
  export interface RadioFieldOption<K extends string> {
3
4
  /** The label for a specific option, i.e. "Cheddar". */
4
5
  label: string;
@@ -7,10 +8,9 @@ export interface RadioFieldOption<K extends string> {
7
8
  /** The undisplayed value, i.e. an id of some sort. */
8
9
  value: K;
9
10
  }
10
- export interface RadioGroupFieldProps<K extends string> {
11
+ export interface RadioGroupFieldProps<K extends string> extends Pick<PresentationFieldProps, "labelStyle"> {
11
12
  /** The label for the choice itself, i.e. "Favorite Cheese". */
12
13
  label: string;
13
- hideLabel?: boolean;
14
14
  /** The currently selected option value (i.e. an id). */
15
15
  value: K | undefined;
16
16
  /** Called when an option is selected. We don't support unselecting. */
@@ -20,7 +20,7 @@ let nextNameId = 0;
20
20
  * TODO: Add hover (non selected and selected) styles
21
21
  */
22
22
  function RadioGroupField(props) {
23
- const { label, hideLabel, value, onChange, options, disabled = false, errorMsg, helperText, ...otherProps } = props;
23
+ const { label, labelStyle, value, onChange, options, disabled = false, errorMsg, helperText, ...otherProps } = props;
24
24
  // useRadioGroupState uses a random group name, so use our name
25
25
  const name = (0, react_1.useMemo)(() => `radio-group-${++nextNameId}`, []);
26
26
  const state = (0, react_stately_1.useRadioGroupState)({
@@ -37,8 +37,8 @@ function RadioGroupField(props) {
37
37
  // max-width is dependent on having descriptions
38
38
  const anyDescriptions = options.some((o) => !!o.description);
39
39
  return (
40
- // width of `max-content` is used to limit invisible label clicking
41
- (0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.w("max-content").maxw(anyDescriptions ? "344px" : "320px").$, children: [(0, jsx_runtime_1.jsx)(Label_1.Label, { label: label, ...labelProps, ...tid.label, hidden: hideLabel }), (0, jsx_runtime_1.jsx)("div", { ...radioGroupProps, children: options.map((option) => ((0, jsx_runtime_1.jsx)(Radio, { parentId: name, option: option, state: state, ...otherProps, ...tid[option.value] }, option.value))) }), errorMsg && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { errorMsg: errorMsg, ...tid.errorMsg }), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, { helperText: helperText })] }));
40
+ // default styling to position `<Label />` above.
41
+ (0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.fdc.gap1.aifs.if(labelStyle === "left").fdr.gap2.jcsb.$, children: [(0, jsx_runtime_1.jsx)(Label_1.Label, { label: label, ...labelProps, ...tid.label, hidden: labelStyle === "hidden" }), (0, jsx_runtime_1.jsxs)("div", { ...radioGroupProps, children: [options.map((option) => ((0, jsx_runtime_1.jsx)(Radio, { parentId: name, option: option, state: state, ...otherProps, ...tid[option.value] }, option.value))), errorMsg && (0, jsx_runtime_1.jsx)(ErrorMessage_1.ErrorMessage, { errorMsg: errorMsg, ...tid.errorMsg }), helperText && (0, jsx_runtime_1.jsx)(HelperText_1.HelperText, { helperText: helperText })] })] }));
42
42
  }
43
43
  exports.RadioGroupField = RadioGroupField;
44
44
  // Not meant to be standalone, but its own component so it can use hooks
@@ -9,7 +9,7 @@ export interface SwitchProps {
9
9
  /** Input label */
10
10
  label: string;
11
11
  /** Where to put the label. */
12
- labelStyle?: "form" | "inline" | "filter";
12
+ labelStyle?: "form" | "inline" | "filter" | "hidden" | "left";
13
13
  /** Whether or not to hide the label */
14
14
  hideLabel?: boolean;
15
15
  /** Handler when the interactive element state changes. */
@@ -25,10 +25,11 @@ function Switch(props) {
25
25
  children: ((0, jsx_runtime_1.jsxs)("label", { ...hoverProps, css: {
26
26
  ...Css_1.Css.relative.cursorPointer.df.w("max-content").smMd.selectNone.$,
27
27
  ...(labelStyle === "form" && Css_1.Css.fdc.$),
28
+ ...(labelStyle === "left" && Css_1.Css.w100.fdr.$),
28
29
  ...(labelStyle === "inline" && Css_1.Css.gap2.aic.$),
29
30
  ...(labelStyle === "filter" && Css_1.Css.jcsb.gap1.aic.w("auto").sm.$),
30
31
  ...(isDisabled && Css_1.Css.cursorNotAllowed.gray400.$),
31
- }, "aria-label": label, children: [!hideLabel && labelStyle === "form" && (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }), !hideLabel && labelStyle === "filter" && (0, jsx_runtime_1.jsx)("span", { children: label }), (0, jsx_runtime_1.jsx)("div", { "aria-hidden": "true", css: {
32
+ }, "aria-label": label, children: [(labelStyle === "form" || labelStyle === "left") && ((0, jsx_runtime_1.jsx)("div", { css: Css_1.Css.if(labelStyle === "left").w50.$, children: (0, jsx_runtime_1.jsx)(Label_1.Label, { label: label }) })), labelStyle === "filter" && (0, jsx_runtime_1.jsx)("span", { children: label }), (0, jsx_runtime_1.jsx)("div", { "aria-hidden": "true", css: {
32
33
  ...Css_1.Css.wPx(40).hPx(toggleHeight(compact)).bgGray200.br12.relative.transition.$,
33
34
  ...(isHovered && exports.switchHoverStyles),
34
35
  ...(isKeyboardFocus && exports.switchFocusStyles),
@@ -39,7 +40,7 @@ function Switch(props) {
39
40
  ...switchCircleDefaultStyles(compact),
40
41
  ...(isDisabled && Css_1.Css.bgGray100.$),
41
42
  ...(isSelected && switchCircleSelectedStyles(compact)),
42
- }, children: withIcon && ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: isSelected ? "check" : "x", color: isSelected ? Css_1.Palette.LightBlue700 : Css_1.Palette.Gray400 })) }) }), !hideLabel && labelStyle === "inline" && ((0, jsx_runtime_1.jsx)("span", { css: {
43
+ }, children: withIcon && ((0, jsx_runtime_1.jsx)(Icon_1.Icon, { icon: isSelected ? "check" : "x", color: isSelected ? Css_1.Palette.LightBlue700 : Css_1.Palette.Gray400 })) }) }), labelStyle === "inline" && ((0, jsx_runtime_1.jsx)("span", { css: {
43
44
  // LineHeight is conditionally applied to handle compact version text alignment
44
45
  ...Css_1.Css.if(compact).add("lineHeight", "1").$,
45
46
  }, children: label })), (0, jsx_runtime_1.jsx)(react_aria_1.VisuallyHidden, { children: (0, jsx_runtime_1.jsx)("input", { ref: ref, ...inputProps, ...focusProps }) })] })),
@@ -3,7 +3,6 @@ import { Only } from "../Css";
3
3
  import { BeamTextFieldProps, TextFieldXss } from "../interfaces";
4
4
  export interface TextFieldProps<X> extends BeamTextFieldProps<X> {
5
5
  compact?: boolean;
6
- inlineLabel?: boolean;
7
6
  clearable?: boolean;
8
7
  api?: MutableRefObject<TextFieldApi | undefined>;
9
8
  onEnter?: VoidFunction;
@@ -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" | "errorMsg" | "errorInTooltip" | "onBlur" | "onFocus" | "helperText" | "hideLabel" | "placeholder" | "compact" | "borderless" | "visuallyDisabled" | "xss">, Partial<Pick<BeamTextFieldProps<X>, "onChange">> {
5
+ export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "label" | "required" | "errorMsg" | "errorInTooltip" | "onBlur" | "onFocus" | "helperText" | "labelStyle" | "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>;
@@ -11,7 +11,6 @@ export interface TextFieldBaseProps<X> extends Pick<BeamTextFieldProps<X>, "labe
11
11
  groupProps?: NumberFieldAria["groupProps"];
12
12
  endAdornment?: ReactNode;
13
13
  startAdornment?: ReactNode;
14
- inlineLabel?: boolean;
15
14
  contrast?: boolean;
16
15
  clearable?: boolean;
17
16
  textAreaMinHeight?: number;
@@ -17,8 +17,8 @@ const useTestIds_1 = require("../utils/useTestIds");
17
17
  function TextFieldBase(props) {
18
18
  var _a, _b, _c, _d, _e, _f, _g;
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, 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, errorInTooltip = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.errorInTooltip) !== null && _e !== void 0 ? _e : false, hideErrorMessage = false, } = props;
21
- const typeScale = (_f = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _f !== void 0 ? _f : (inputProps.readOnly && !hideLabel ? "smMd" : "sm");
20
+ const { label, required, labelProps, inputProps, inputRef, inputWrapRef, groupProps, compact = (_a = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.compact) !== null && _a !== void 0 ? _a : false, errorMsg, helperText, multiline = false, onChange, onBlur, onFocus, xss, endAdornment, startAdornment, labelStyle = (_b = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.labelStyle) !== null && _b !== void 0 ? _b : "above", contrast = false, borderless = (_c = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.borderless) !== null && _c !== void 0 ? _c : false, textAreaMinHeight = 96, clearable = false, tooltip, visuallyDisabled = (_d = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.visuallyDisabled) !== null && _d !== void 0 ? _d : true, errorInTooltip = (_e = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.errorInTooltip) !== null && _e !== void 0 ? _e : false, hideErrorMessage = false, } = props;
21
+ const typeScale = (_f = fieldProps === null || fieldProps === void 0 ? void 0 : fieldProps.typeScale) !== null && _f !== void 0 ? _f : (inputProps.readOnly && labelStyle !== "hidden" ? "smMd" : "sm");
22
22
  const internalProps = props.internalProps || {};
23
23
  const { compound = false, forceFocus = false, forceHover = false } = internalProps;
24
24
  const errorMessageId = `${inputProps.id}-error`;
@@ -38,13 +38,15 @@ function TextFieldBase(props) {
38
38
  ? [Css_1.Palette.Gray100, Css_1.Palette.Gray200, Css_1.Palette.Gray200]
39
39
  : [Css_1.Palette.White, Css_1.Palette.Gray100, Css_1.Palette.Gray100];
40
40
  const fieldStyles = {
41
- container: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).relative.$,
41
+ container: Css_1.Css.df.fdc.w100.maxw((0, Css_1.px)(550)).relative.if(labelStyle === "left").fdr.gap2.jcsb.aic.$,
42
42
  inputWrapper: {
43
43
  ...Css_1.Css[typeScale].df.aic.br4.px1.w100
44
44
  .hPx(fieldHeight - maybeSmaller)
45
45
  .if(compact)
46
46
  .hPx(compactFieldHeight - maybeSmaller).$,
47
- ...Css_1.Css.bgColor(bgColor).gray900.if(contrast).white.$,
47
+ ...Css_1.Css.bgColor(bgColor)
48
+ .gray900.if(contrast)
49
+ .white.if(labelStyle === "left").maxw50.$,
48
50
  // When borderless then perceived vertical alignments are misaligned. As there is no longer a border, then the field looks oddly indented.
49
51
  // This typically happens in tables when a column has a mix of static text (i.e. "roll up" rows and table headers) and input fields.
50
52
  // To remedy this perceived misalignment then we increase the width by the horizontal padding applied (16px), and set a negative margin left margin to re-center the field.
@@ -58,7 +60,7 @@ function TextFieldBase(props) {
58
60
  inputWrapperReadOnly: {
59
61
  ...Css_1.Css[typeScale].df.aic.w100.gray900.if(contrast).white.$,
60
62
  // If we are hiding the label, then we are typically in a table. Keep the `mh` in this case to ensure editable and non-editable fields in a single table row line up properly
61
- ...(hideLabel &&
63
+ ...(labelStyle === "hidden" &&
62
64
  Css_1.Css.mhPx(fieldHeight - maybeSmaller)
63
65
  .if(compact)
64
66
  .mhPx(compactFieldHeight - maybeSmaller).$),
@@ -90,9 +92,7 @@ function TextFieldBase(props) {
90
92
  }, onFocus);
91
93
  const showFocus = (isFocused && !inputProps.readOnly) || forceFocus;
92
94
  const showHover = (isHovered && !inputProps.disabled && !inputProps.readOnly && !isFocused) || forceHover;
93
- return ((0, jsx_runtime_1.jsxs)("div", { css: fieldStyles.container, ...groupProps, ...focusWithinProps, children: [label && !inlineLabel && (
94
- // set `hidden` if being rendered as a compound field
95
- (0, jsx_runtime_1.jsx)(Label_1.Label, { labelProps: labelProps, hidden: hideLabel || compound, label: label, suffix: labelSuffix, contrast: contrast, ...tid.label })), (0, components_1.maybeTooltip)({
95
+ return ((0, jsx_runtime_1.jsxs)("div", { css: fieldStyles.container, ...groupProps, ...focusWithinProps, children: [label && labelStyle !== "inline" && ((0, jsx_runtime_1.jsx)(Label_1.Label, { labelProps: labelProps, hidden: labelStyle === "hidden" || compound, label: label, suffix: labelSuffix, contrast: contrast, ...tid.label })), (0, components_1.maybeTooltip)({
96
96
  title: tooltip,
97
97
  placement: "top",
98
98
  children: inputProps.readOnly ? ((0, jsx_runtime_1.jsxs)("div", { css: {
@@ -100,7 +100,7 @@ function TextFieldBase(props) {
100
100
  ...fieldStyles.inputWrapperReadOnly,
101
101
  ...(multiline ? Css_1.Css.fdc.aifs.gap2.$ : Css_1.Css.truncate.$),
102
102
  ...xss,
103
- }, "data-readonly": "true", ...tid, children: [!multiline && inlineLabel && label && !hideLabel && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), multiline
103
+ }, "data-readonly": "true", ...tid, children: [!multiline && labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), multiline
104
104
  ? (_g = inputProps.value) === null || _g === void 0 ? void 0 : _g.split("\n\n").map((p, i) => ((0, jsx_runtime_1.jsx)("p", { css: Css_1.Css.my1.$, children: p.split("\n").map((sentence, j) => ((0, jsx_runtime_1.jsxs)("span", { children: [sentence, (0, jsx_runtime_1.jsx)("br", {})] }, j))) }, i)))
105
105
  : inputProps.value] })) : ((0, jsx_runtime_1.jsxs)("div", { css: {
106
106
  ...fieldStyles.inputWrapper,
@@ -110,7 +110,7 @@ function TextFieldBase(props) {
110
110
  // Only show error styles if the field is not disabled, following the pattern that the error message is also hidden
111
111
  ...(errorMsg && !inputProps.disabled ? fieldStyles.error : {}),
112
112
  ...Css_1.Css.if(multiline).aifs.px0.mhPx(textAreaMinHeight).$,
113
- }, ...hoverProps, ref: inputWrapRef, children: [!multiline && inlineLabel && label && !hideLabel && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.fs0.br4.pr1.$, children: startAdornment }), (0, jsx_runtime_1.jsx)(ElementType, { ...(0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(hideLabel ? { "aria-label": label } : {}) }), ...(errorMsg ? { "aria-errormessage": errorMessageId } : {}), ref: fieldRef, rows: multiline ? 1 : undefined, css: {
113
+ }, ...hoverProps, ref: inputWrapRef, children: [!multiline && labelStyle === "inline" && label && ((0, jsx_runtime_1.jsx)(Label_1.InlineLabel, { labelProps: labelProps, label: label, ...tid.label })), !multiline && startAdornment && (0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.df.aic.fs0.br4.pr1.$, children: startAdornment }), (0, jsx_runtime_1.jsx)(ElementType, { ...(0, react_aria_1.mergeProps)(inputProps, { onBlur, onFocus: onFocusChained, onChange: onDomChange }, { "aria-invalid": Boolean(errorMsg), ...(labelStyle === "hidden" ? { "aria-label": label } : {}) }), ...(errorMsg ? { "aria-errormessage": errorMessageId } : {}), ref: fieldRef, rows: multiline ? 1 : undefined, css: {
114
114
  ...fieldStyles.input,
115
115
  ...(inputProps.disabled ? fieldStyles.disabled : {}),
116
116
  ...(showHover ? fieldStyles.hover : {}),
@@ -1,7 +1,6 @@
1
1
  import { Only } from "../../Css";
2
2
  import { BeamTextFieldProps, TextFieldXss } from "../../interfaces";
3
3
  interface TextFieldProps<X> extends BeamTextFieldProps<X> {
4
- inlineLabel: boolean;
5
4
  }
6
5
  export declare function MenuSearchField<X extends Only<TextFieldXss, X>>(props: TextFieldProps<X>): import("@emotion/react/jsx-runtime").JSX.Element;
7
6
  export {};
@@ -25,8 +25,6 @@ export interface BeamSelectFieldBaseProps<O, V extends Value> extends BeamFocusa
25
25
  fieldDecoration?: (opt: O) => ReactNode;
26
26
  /** Sets the form field label. */
27
27
  label: string;
28
- /** Renders the label inside the input field, i.e. for filters. */
29
- inlineLabel?: boolean;
30
28
  readOnly?: boolean | ReactNode;
31
29
  onBlur?: () => void;
32
30
  onFocus?: () => void;
@@ -172,7 +172,7 @@ function SelectFieldBase(props) {
172
172
  }
173
173
  },
174
174
  });
175
- //@ts-ignore - `selectionManager.state` exists, but not according to the types
175
+ // @ts-ignore - `selectionManager.state` exists, but not according to the types
176
176
  state.selectionManager.state = (0, react_stately_1.useMultipleSelectionState)({
177
177
  selectionMode: multiselect ? "multiple" : "single",
178
178
  // Do not allow an empty selection if single select mode
@@ -15,7 +15,6 @@ interface SelectFieldInputProps<O, V extends Value> extends PresentationFieldPro
15
15
  helperText?: string | ReactNode;
16
16
  onBlur?: () => void;
17
17
  onFocus?: () => void;
18
- inlineLabel?: boolean;
19
18
  labelProps: LabelHTMLAttributes<HTMLLabelElement>;
20
19
  label: string;
21
20
  selectedOptions: O[];
@@ -9,13 +9,13 @@ const Css_1 = require("../../Css");
9
9
  const TextFieldBase_1 = require("../TextFieldBase");
10
10
  const utils_1 = require("../../utils");
11
11
  function SelectFieldInput(props) {
12
- const { inputProps, buttonProps, buttonRef, errorMsg, state, fieldDecoration, onBlur, onFocus, inlineLabel, selectedOptions, getOptionValue, getOptionLabel, sizeToContent = false, contrast = false, nothingSelectedText, resetField, ...otherProps } = props;
12
+ const { inputProps, buttonProps, buttonRef, errorMsg, state, fieldDecoration, onBlur, onFocus, selectedOptions, getOptionValue, getOptionLabel, sizeToContent = false, contrast = false, nothingSelectedText, resetField, ...otherProps } = props;
13
13
  const [isFocused, setIsFocused] = (0, react_1.useState)(false);
14
14
  const isMultiSelect = state.selectionManager.selectionMode === "multiple";
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, { ...otherProps, inlineLabel: inlineLabel, errorMsg: errorMsg, contrast: contrast, xss: !inlineLabel && !inputProps.readOnly ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgLightBlue700.white.tinySb.df.aic.jcc.$, children: state.selectionManager.selectedKeys.size }))) ||
18
+ return ((0, jsx_runtime_1.jsx)(TextFieldBase_1.TextFieldBase, { ...otherProps, errorMsg: errorMsg, contrast: contrast, xss: otherProps.labelStyle !== "inline" && !inputProps.readOnly ? Css_1.Css.fw5.$ : {}, startAdornment: (showNumSelection && ((0, jsx_runtime_1.jsx)("span", { css: Css_1.Css.wPx(16).hPx(16).fs0.br100.bgLightBlue700.white.tinySb.df.aic.jcc.$, children: state.selectionManager.selectedKeys.size }))) ||
19
19
  (showFieldDecoration && fieldDecoration(selectedOptions[0])), endAdornment: !inputProps.readOnly && ((0, jsx_runtime_1.jsx)("button", { ...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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.227.1",
3
+ "version": "2.228.0",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",