@homebound/beam 2.380.0 → 2.381.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/index.js CHANGED
@@ -8046,8 +8046,9 @@ var BorderHoverParent = "BorderHoverParent";
8046
8046
  var BorderHoverChild = "BorderHoverChild";
8047
8047
 
8048
8048
  // src/forms/labelUtils.ts
8049
- function getLabelSuffix(required) {
8049
+ function useLabelSuffix(required, readOnly) {
8050
8050
  const { fieldProps } = usePresentationContext();
8051
+ if (readOnly) return void 0;
8051
8052
  if (required === true) {
8052
8053
  return fieldProps?.labelSuffix?.required;
8053
8054
  } else if (required === false) {
@@ -8117,7 +8118,7 @@ function TextFieldBase(props) {
8117
8118
  const internalProps = props.internalProps || {};
8118
8119
  const { compound = false, forceFocus = false, forceHover = false } = internalProps;
8119
8120
  const errorMessageId = `${inputProps.id}-error`;
8120
- const labelSuffix = getLabelSuffix(required);
8121
+ const labelSuffix = useLabelSuffix(required, inputProps.readOnly);
8121
8122
  const ElementType = multiline ? "textarea" : "input";
8122
8123
  const tid = useTestIds(props, defaultTestId(label));
8123
8124
  const [isFocused, setIsFocused] = useState11(false);
@@ -16489,6 +16490,9 @@ function BoundDateRangeField(props) {
16489
16490
  ) });
16490
16491
  }
16491
16492
 
16493
+ // src/forms/BoundForm.tsx
16494
+ import { useMemo as useMemo38 } from "react";
16495
+
16492
16496
  // src/forms/BoundIconCardField.tsx
16493
16497
  import { Observer as Observer6 } from "mobx-react";
16494
16498
  import { jsx as jsx138 } from "@emotion/react/jsx-runtime";
@@ -16817,35 +16821,9 @@ function BoundRichTextField(props) {
16817
16821
  ) });
16818
16822
  }
16819
16823
 
16820
- // src/forms/BoundSelectAndTextField.tsx
16821
- import { jsx as jsx146, jsxs as jsxs73 } from "@emotion/react/jsx-runtime";
16822
- function BoundSelectAndTextField(props) {
16823
- const { selectFieldProps, textFieldProps, compact = true } = props;
16824
- const tid = useTestIds(props);
16825
- return /* @__PURE__ */ jsxs73(CompoundField, { children: [
16826
- /* @__PURE__ */ jsx146(
16827
- BoundSelectField,
16828
- {
16829
- ...tid[defaultTestId(selectFieldProps.label ?? selectFieldProps.field.key)],
16830
- ...selectFieldProps,
16831
- sizeToContent: true,
16832
- compact
16833
- }
16834
- ),
16835
- /* @__PURE__ */ jsx146(
16836
- BoundTextField,
16837
- {
16838
- ...tid[defaultTestId(textFieldProps.label ?? textFieldProps.field.key)],
16839
- ...textFieldProps,
16840
- compact
16841
- }
16842
- )
16843
- ] });
16844
- }
16845
-
16846
16824
  // src/forms/BoundSelectField.tsx
16847
16825
  import { Observer as Observer13 } from "mobx-react";
16848
- import { jsx as jsx147 } from "@emotion/react/jsx-runtime";
16826
+ import { jsx as jsx146 } from "@emotion/react/jsx-runtime";
16849
16827
  function BoundSelectField(props) {
16850
16828
  const {
16851
16829
  field,
@@ -16860,7 +16838,7 @@ function BoundSelectField(props) {
16860
16838
  ...others
16861
16839
  } = props;
16862
16840
  const testId = useTestIds(props, field.key);
16863
- return /* @__PURE__ */ jsx147(Observer13, { children: () => /* @__PURE__ */ jsx147(
16841
+ return /* @__PURE__ */ jsx146(Observer13, { children: () => /* @__PURE__ */ jsx146(
16864
16842
  SelectField,
16865
16843
  {
16866
16844
  label,
@@ -16891,7 +16869,7 @@ function BoundSelectField(props) {
16891
16869
 
16892
16870
  // src/forms/BoundSwitchField.tsx
16893
16871
  import { Observer as Observer14 } from "mobx-react";
16894
- import { jsx as jsx148 } from "@emotion/react/jsx-runtime";
16872
+ import { jsx as jsx147 } from "@emotion/react/jsx-runtime";
16895
16873
  function BoundSwitchField(props) {
16896
16874
  const {
16897
16875
  field,
@@ -16902,7 +16880,7 @@ function BoundSwitchField(props) {
16902
16880
  ...others
16903
16881
  } = props;
16904
16882
  const testId = useTestIds(props, field.key);
16905
- return /* @__PURE__ */ jsx148(Observer14, { children: () => /* @__PURE__ */ jsx148(
16883
+ return /* @__PURE__ */ jsx147(Observer14, { children: () => /* @__PURE__ */ jsx147(
16906
16884
  Switch,
16907
16885
  {
16908
16886
  label,
@@ -16921,7 +16899,7 @@ function BoundSwitchField(props) {
16921
16899
 
16922
16900
  // src/forms/BoundTextAreaField.tsx
16923
16901
  import { Observer as Observer15 } from "mobx-react";
16924
- import { jsx as jsx149 } from "@emotion/react/jsx-runtime";
16902
+ import { jsx as jsx148 } from "@emotion/react/jsx-runtime";
16925
16903
  function BoundTextAreaField(props) {
16926
16904
  const {
16927
16905
  field,
@@ -16934,7 +16912,7 @@ function BoundTextAreaField(props) {
16934
16912
  ...others
16935
16913
  } = props;
16936
16914
  const testId = useTestIds(props, field.key);
16937
- return /* @__PURE__ */ jsx149(Observer15, { children: () => /* @__PURE__ */ jsx149(
16915
+ return /* @__PURE__ */ jsx148(Observer15, { children: () => /* @__PURE__ */ jsx148(
16938
16916
  TextAreaField,
16939
16917
  {
16940
16918
  label,
@@ -16963,7 +16941,7 @@ function BoundTextAreaField(props) {
16963
16941
 
16964
16942
  // src/forms/BoundTextField.tsx
16965
16943
  import { Observer as Observer16 } from "mobx-react";
16966
- import { jsx as jsx150 } from "@emotion/react/jsx-runtime";
16944
+ import { jsx as jsx149 } from "@emotion/react/jsx-runtime";
16967
16945
  function BoundTextField(props) {
16968
16946
  const {
16969
16947
  field,
@@ -16976,7 +16954,7 @@ function BoundTextField(props) {
16976
16954
  ...others
16977
16955
  } = props;
16978
16956
  const testId = useTestIds(props, field.key);
16979
- return /* @__PURE__ */ jsx150(Observer16, { children: () => /* @__PURE__ */ jsx150(
16957
+ return /* @__PURE__ */ jsx149(Observer16, { children: () => /* @__PURE__ */ jsx149(
16980
16958
  TextField,
16981
16959
  {
16982
16960
  label,
@@ -17005,16 +16983,16 @@ function BoundTextField(props) {
17005
16983
 
17006
16984
  // src/forms/BoundToggleChipGroupField.tsx
17007
16985
  import { Observer as Observer17 } from "mobx-react";
17008
- import { jsx as jsx151 } from "@emotion/react/jsx-runtime";
16986
+ import { jsx as jsx150 } from "@emotion/react/jsx-runtime";
17009
16987
  function BoundToggleChipGroupField(props) {
17010
16988
  const { field, onChange = (value) => field.set(value), label = defaultLabel(field.key), ...others } = props;
17011
16989
  const testId = useTestIds(props, field.key);
17012
- return /* @__PURE__ */ jsx151(Observer17, { children: () => /* @__PURE__ */ jsx151(ToggleChipGroup, { label, values: field.value || [], onChange, ...testId, ...others }) });
16990
+ return /* @__PURE__ */ jsx150(Observer17, { children: () => /* @__PURE__ */ jsx150(ToggleChipGroup, { label, values: field.value || [], onChange, ...testId, ...others }) });
17013
16991
  }
17014
16992
 
17015
16993
  // src/forms/BoundTreeSelectField.tsx
17016
16994
  import { Observer as Observer18 } from "mobx-react";
17017
- import { jsx as jsx152 } from "@emotion/react/jsx-runtime";
16995
+ import { jsx as jsx151 } from "@emotion/react/jsx-runtime";
17018
16996
  function BoundTreeSelectField(props) {
17019
16997
  const {
17020
16998
  field,
@@ -17031,7 +17009,7 @@ function BoundTreeSelectField(props) {
17031
17009
  ...others
17032
17010
  } = props;
17033
17011
  const testId = useTestIds(props, field.key);
17034
- return /* @__PURE__ */ jsx152(Observer18, { children: () => /* @__PURE__ */ jsx152(
17012
+ return /* @__PURE__ */ jsx151(Observer18, { children: () => /* @__PURE__ */ jsx151(
17035
17013
  TreeSelectField,
17036
17014
  {
17037
17015
  label,
@@ -17060,29 +17038,9 @@ function BoundTreeSelectField(props) {
17060
17038
  ) });
17061
17039
  }
17062
17040
 
17063
- // src/forms/FormHeading.tsx
17064
- import { jsx as jsx153 } from "@emotion/react/jsx-runtime";
17065
- function FormHeading(props) {
17066
- const { title, xss, isFirst = false, ...others } = props;
17067
- return /* @__PURE__ */ jsx153(
17068
- "h3",
17069
- {
17070
- css: {
17071
- ...Css.baseMd.$,
17072
- // Add space before the heading, but only if it's not first.
17073
- ...!isFirst && Css.mt4.$,
17074
- ...xss
17075
- },
17076
- ...others,
17077
- children: title
17078
- }
17079
- );
17080
- }
17081
- FormHeading.isFormHeading = true;
17082
-
17083
17041
  // src/forms/FormLines.tsx
17084
17042
  import { Children, cloneElement as cloneElement3 } from "react";
17085
- import { jsx as jsx154 } from "@emotion/react/jsx-runtime";
17043
+ import { jsx as jsx152 } from "@emotion/react/jsx-runtime";
17086
17044
  function FormLines(props) {
17087
17045
  const { inModal } = useModal();
17088
17046
  const {
@@ -17102,7 +17060,7 @@ function FormLines(props) {
17102
17060
  ..."labelLeftFieldWidth" in props ? { labelLeftFieldWidth } : {},
17103
17061
  ...width === "full" ? { fullWidth: true } : {}
17104
17062
  };
17105
- return /* @__PURE__ */ jsx154(PresentationProvider, { fieldProps: newFieldProps, children: /* @__PURE__ */ jsx154(
17063
+ return /* @__PURE__ */ jsx152(PresentationProvider, { fieldProps: newFieldProps, children: /* @__PURE__ */ jsx152(
17106
17064
  "div",
17107
17065
  {
17108
17066
  css: {
@@ -17124,7 +17082,7 @@ function FormLines(props) {
17124
17082
  ) });
17125
17083
  }
17126
17084
  function FormDivider() {
17127
- return /* @__PURE__ */ jsx154("div", { css: Css.hPx(1).my2.bgGray200.$ });
17085
+ return /* @__PURE__ */ jsx152("div", { css: Css.hPx(1).my2.bgGray200.$ });
17128
17086
  }
17129
17087
  function FieldGroup(props) {
17130
17088
  const { title, children, widths: widths2 = [] } = props;
@@ -17132,7 +17090,7 @@ function FieldGroup(props) {
17132
17090
  const width = widths2[i] || 1;
17133
17091
  return typeof width === `number` ? `${width}fr` : width;
17134
17092
  }).join(" ");
17135
- return /* @__PURE__ */ jsx154("div", { css: Css.dg.gap2.gtc(gtc).$, children });
17093
+ return /* @__PURE__ */ jsx152("div", { css: Css.dg.gap2.gtc(gtc).$, children });
17136
17094
  }
17137
17095
  var sizes = {
17138
17096
  full: "100%",
@@ -17141,29 +17099,206 @@ var sizes = {
17141
17099
  sm: "320px"
17142
17100
  };
17143
17101
 
17102
+ // src/forms/BoundForm.tsx
17103
+ import { jsx as jsx153 } from "@emotion/react/jsx-runtime";
17104
+ var reactNodePrefix = "reactNode";
17105
+ function BoundForm(props) {
17106
+ const { rows, formState } = props;
17107
+ const tid = useTestIds({}, "boundForm");
17108
+ return /* @__PURE__ */ jsx153("div", { ...tid, children: /* @__PURE__ */ jsx153(FormLines, { labelSuffix: { required: "*" }, width: "full", gap: 4, children: rows.map((row) => /* @__PURE__ */ jsx153(FormRow, { row, formState }, `fieldGroup-${Object.keys(row).join("-")}`)) }) });
17109
+ }
17110
+ function FormRow({ row, formState }) {
17111
+ const tid = useTestIds({}, "boundFormRow");
17112
+ const componentsWithConfig = useMemo38(() => {
17113
+ return safeEntries(row).map(([key, fieldFnOrCustomNode]) => {
17114
+ if (typeof fieldFnOrCustomNode === "function" && !isCustomReactNodeKey(key)) {
17115
+ const field = formState[key] ?? fail(`Field ${key.toString()} not found in formState`);
17116
+ const fieldFn = fieldFnOrCustomNode ?? fail(`Field function not defined for key ${key.toLocaleString()}`);
17117
+ const { component, minWidth } = fieldFn(field);
17118
+ return { component, key, minWidth };
17119
+ }
17120
+ return { component: fieldFnOrCustomNode, key };
17121
+ });
17122
+ }, [row, formState]);
17123
+ const isLoading = useComputed(() => formState.loading, [formState]);
17124
+ const itemFlexBasis = 100 / componentsWithConfig.length - 3;
17125
+ return /* @__PURE__ */ jsx153("div", { css: Css.df.fww.gap2.$, ...tid, children: componentsWithConfig.map(({ component, key, minWidth }) => /* @__PURE__ */ jsx153("div", { css: Css.mw(minWidth).fb(`${itemFlexBasis}%`).fg1.$, children: isLoading ? /* @__PURE__ */ jsx153(LoadingSkeleton, { size: "lg" }) : component }, key.toString())) });
17126
+ }
17127
+ function isCustomReactNodeKey(key) {
17128
+ return key.toString().startsWith(reactNodePrefix);
17129
+ }
17130
+ function boundSelectField(props) {
17131
+ return (field) => ({
17132
+ component: /* @__PURE__ */ jsx153(BoundSelectField, { field, ...props }),
17133
+ minWidth: "200px"
17134
+ });
17135
+ }
17136
+ function boundMultiSelectField(props) {
17137
+ return (field) => ({
17138
+ component: /* @__PURE__ */ jsx153(BoundMultiSelectField, { field, ...props }),
17139
+ minWidth: "200px"
17140
+ });
17141
+ }
17142
+ function boundMultilineSelectField(props) {
17143
+ return (field) => ({
17144
+ component: /* @__PURE__ */ jsx153(BoundMultiLineSelectField, { field, ...props }),
17145
+ minWidth: "200px"
17146
+ });
17147
+ }
17148
+ function boundTextField(props) {
17149
+ return (field) => ({
17150
+ component: /* @__PURE__ */ jsx153(BoundTextField, { field, ...props }),
17151
+ minWidth: "150px"
17152
+ });
17153
+ }
17154
+ function boundTextAreaField(props) {
17155
+ return (field) => ({
17156
+ component: /* @__PURE__ */ jsx153(BoundTextAreaField, { field, ...props }),
17157
+ minWidth: "200px"
17158
+ });
17159
+ }
17160
+ function boundNumberField(props) {
17161
+ return (field) => ({
17162
+ component: /* @__PURE__ */ jsx153(BoundNumberField, { field, ...props }),
17163
+ minWidth: "150px"
17164
+ });
17165
+ }
17166
+ function boundDateField(props) {
17167
+ return (field) => ({
17168
+ component: /* @__PURE__ */ jsx153(BoundDateField, { field, ...props }),
17169
+ minWidth: "150px"
17170
+ });
17171
+ }
17172
+ function boundDateRangeField(props) {
17173
+ return (field) => ({
17174
+ component: /* @__PURE__ */ jsx153(BoundDateRangeField, { field, ...props }),
17175
+ minWidth: "150px"
17176
+ });
17177
+ }
17178
+ function boundCheckboxField(props) {
17179
+ return (field) => ({
17180
+ component: /* @__PURE__ */ jsx153(BoundCheckboxField, { field, ...props }),
17181
+ minWidth: "min-content"
17182
+ });
17183
+ }
17184
+ function boundCheckboxGroupField(props) {
17185
+ return (field) => ({
17186
+ component: /* @__PURE__ */ jsx153(BoundCheckboxGroupField, { field, ...props }),
17187
+ minWidth: "200px"
17188
+ });
17189
+ }
17190
+ function boundIconCardField(props) {
17191
+ return (field) => ({
17192
+ component: /* @__PURE__ */ jsx153(BoundIconCardField, { field, ...props }),
17193
+ minWidth: "150px"
17194
+ });
17195
+ }
17196
+ function boundIconCardGroupField(props) {
17197
+ return (field) => ({
17198
+ component: /* @__PURE__ */ jsx153(BoundIconCardGroupField, { field, ...props }),
17199
+ minWidth: "100%"
17200
+ });
17201
+ }
17202
+ function boundRadioGroupField(props) {
17203
+ return (field) => ({
17204
+ component: /* @__PURE__ */ jsx153(BoundRadioGroupField, { field, ...props }),
17205
+ minWidth: "200px"
17206
+ });
17207
+ }
17208
+ function boundRichTextField(props) {
17209
+ return (field) => ({
17210
+ component: /* @__PURE__ */ jsx153(BoundRichTextField, { field, ...props }),
17211
+ minWidth: "200px"
17212
+ });
17213
+ }
17214
+ function boundSwitchField(props) {
17215
+ return (field) => ({
17216
+ component: /* @__PURE__ */ jsx153(BoundSwitchField, { field, labelStyle: "inline", ...props }),
17217
+ minWidth: "min-content"
17218
+ });
17219
+ }
17220
+ function boundToggleChipGroupField(props) {
17221
+ return (field) => ({
17222
+ component: /* @__PURE__ */ jsx153(BoundToggleChipGroupField, { field, ...props }),
17223
+ minWidth: "100%"
17224
+ });
17225
+ }
17226
+ function boundTreeSelectField(props) {
17227
+ return (field) => ({
17228
+ component: /* @__PURE__ */ jsx153(BoundTreeSelectField, { field, ...props }),
17229
+ minWidth: "200px"
17230
+ });
17231
+ }
17232
+
17233
+ // src/forms/BoundSelectAndTextField.tsx
17234
+ import { jsx as jsx154, jsxs as jsxs73 } from "@emotion/react/jsx-runtime";
17235
+ function BoundSelectAndTextField(props) {
17236
+ const { selectFieldProps, textFieldProps, compact = true } = props;
17237
+ const tid = useTestIds(props);
17238
+ return /* @__PURE__ */ jsxs73(CompoundField, { children: [
17239
+ /* @__PURE__ */ jsx154(
17240
+ BoundSelectField,
17241
+ {
17242
+ ...tid[defaultTestId(selectFieldProps.label ?? selectFieldProps.field.key)],
17243
+ ...selectFieldProps,
17244
+ sizeToContent: true,
17245
+ compact
17246
+ }
17247
+ ),
17248
+ /* @__PURE__ */ jsx154(
17249
+ BoundTextField,
17250
+ {
17251
+ ...tid[defaultTestId(textFieldProps.label ?? textFieldProps.field.key)],
17252
+ ...textFieldProps,
17253
+ compact
17254
+ }
17255
+ )
17256
+ ] });
17257
+ }
17258
+
17259
+ // src/forms/FormHeading.tsx
17260
+ import { jsx as jsx155 } from "@emotion/react/jsx-runtime";
17261
+ function FormHeading(props) {
17262
+ const { title, xss, isFirst = false, ...others } = props;
17263
+ return /* @__PURE__ */ jsx155(
17264
+ "h3",
17265
+ {
17266
+ css: {
17267
+ ...Css.baseMd.$,
17268
+ // Add space before the heading, but only if it's not first.
17269
+ ...!isFirst && Css.mt4.$,
17270
+ ...xss
17271
+ },
17272
+ ...others,
17273
+ children: title
17274
+ }
17275
+ );
17276
+ }
17277
+ FormHeading.isFormHeading = true;
17278
+
17144
17279
  // src/forms/StaticField.tsx
17145
17280
  import { useId as useId2 } from "@react-aria/utils";
17146
- import { jsx as jsx155, jsxs as jsxs74 } from "@emotion/react/jsx-runtime";
17281
+ import { jsx as jsx156, jsxs as jsxs74 } from "@emotion/react/jsx-runtime";
17147
17282
  function StaticField(props) {
17148
17283
  const { fieldProps } = usePresentationContext();
17149
17284
  const { label, labelStyle = fieldProps?.labelStyle ?? "above", value, children } = props;
17150
17285
  const tid = useTestIds(props, typeof label === "string" ? defaultTestId(label) : "staticField");
17151
17286
  const id = useId2();
17152
17287
  return /* @__PURE__ */ jsxs74("div", { css: Css.if(labelStyle === "left").df.jcsb.maxw100.$, ...tid.container, children: [
17153
- /* @__PURE__ */ jsx155("label", { css: Css.db.sm.gray700.mbPx(4).$, htmlFor: id, ...tid.label, children: label }),
17154
- /* @__PURE__ */ jsx155("div", { id, css: Css.smMd.gray900.df.aic.if(labelStyle === "left").w50.$, ...tid, children: value || children })
17288
+ /* @__PURE__ */ jsx156("label", { css: Css.db.sm.gray700.mbPx(4).$, htmlFor: id, ...tid.label, children: label }),
17289
+ /* @__PURE__ */ jsx156("div", { id, css: Css.smMd.gray900.df.aic.if(labelStyle === "left").w50.$, ...tid, children: value || children })
17155
17290
  ] });
17156
17291
  }
17157
17292
 
17158
17293
  // src/forms/SubmitButton.tsx
17159
- import { jsx as jsx156 } from "@emotion/react/jsx-runtime";
17294
+ import { jsx as jsx157 } from "@emotion/react/jsx-runtime";
17160
17295
  function SubmitButton(props) {
17161
17296
  const { form, disabled, onClick, label = "Submit", ...others } = props;
17162
17297
  if (typeof onClick === "string") {
17163
17298
  throw new Error("SubmitButton.onClick doesn't support strings yet");
17164
17299
  }
17165
17300
  const dirty = useComputed(() => form.dirty, [form]);
17166
- return /* @__PURE__ */ jsx156(
17301
+ return /* @__PURE__ */ jsx157(
17167
17302
  Button,
17168
17303
  {
17169
17304
  label,
@@ -17197,6 +17332,7 @@ export {
17197
17332
  BoundChipSelectField,
17198
17333
  BoundDateField,
17199
17334
  BoundDateRangeField,
17335
+ BoundForm,
17200
17336
  BoundIconCardField,
17201
17337
  BoundIconCardGroupField,
17202
17338
  BoundMultiLineSelectField,
@@ -17315,6 +17451,23 @@ export {
17315
17451
  applyRowFn,
17316
17452
  assignDefaultColumnIds,
17317
17453
  booleanFilter,
17454
+ boundCheckboxField,
17455
+ boundCheckboxGroupField,
17456
+ boundDateField,
17457
+ boundDateRangeField,
17458
+ boundIconCardField,
17459
+ boundIconCardGroupField,
17460
+ boundMultiSelectField,
17461
+ boundMultilineSelectField,
17462
+ boundNumberField,
17463
+ boundRadioGroupField,
17464
+ boundRichTextField,
17465
+ boundSelectField,
17466
+ boundSwitchField,
17467
+ boundTextAreaField,
17468
+ boundTextField,
17469
+ boundToggleChipGroupField,
17470
+ boundTreeSelectField,
17318
17471
  calcColumnSizes,
17319
17472
  cardStyle,
17320
17473
  checkboxFilter,