@homebound/beam 2.117.0 → 2.117.3

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.
@@ -224,6 +224,7 @@ function GridTable(props) {
224
224
  tooManyClientSideRows = true;
225
225
  filteredRows = filteredRows.slice(0, filterMaxRows);
226
226
  }
227
+ rowState.visibleRows.replace(filteredRows.map(([row]) => { var _a; return (_a = row === null || row === void 0 ? void 0 : row.id) !== null && _a !== void 0 ? _a : ""; }));
227
228
  // Push back to the caller a way to ask us where a row is.
228
229
  const { rowLookup } = props;
229
230
  if (rowLookup) {
@@ -1,3 +1,4 @@
1
+ import { ObservableSet } from "mobx";
1
2
  import React, { MutableRefObject } from "react";
2
3
  import { GridDataRow } from "./GridTable";
3
4
  export declare type SelectedState = "checked" | "unchecked" | "partial";
@@ -21,6 +22,7 @@ export declare class RowState {
21
22
  private persistCollapse;
22
23
  private readonly collapsedRows;
23
24
  private readonly selectedRows;
25
+ visibleRows: ObservableSet<string>;
24
26
  activeRowId: string | undefined;
25
27
  /**
26
28
  * Creates the `RowState` for a given `GridTable`.
@@ -30,6 +30,8 @@ class RowState {
30
30
  this.rows = rows;
31
31
  this.persistCollapse = persistCollapse;
32
32
  this.selectedRows = new mobx_1.ObservableMap();
33
+ // Set of just row ids. Keeps track of which rows are visible. Used to filter out non-visible rows from `selectedIds`
34
+ this.visibleRows = new mobx_1.ObservableSet();
33
35
  this.collapsedRows = new mobx_1.ObservableSet(persistCollapse ? readLocalCollapseState(persistCollapse) : []);
34
36
  this.activeRowId = activeRowId;
35
37
  // Make ourselves an observable so that mobx will do caching of .collapseIds so
@@ -38,7 +40,9 @@ class RowState {
38
40
  }
39
41
  get selectedIds() {
40
42
  // Return only ids that are fully checked, i.e. not partial
41
- const ids = [...this.selectedRows.entries()].filter(([, v]) => v === "checked").map(([k]) => k);
43
+ const ids = [...this.selectedRows.entries()]
44
+ .filter(([id, v]) => this.visibleRows.has(id) && v === "checked")
45
+ .map(([k]) => k);
42
46
  // Hide our header marker
43
47
  const headerIndex = ids.indexOf("header");
44
48
  if (headerIndex > -1) {
@@ -1,4 +1,4 @@
1
- import { FieldState } from "@homebound/form-state/dist/formState";
1
+ import { FieldState } from "@homebound/form-state";
2
2
  import { Value } from "../inputs";
3
3
  import { ChipSelectFieldProps } from "../inputs/ChipSelectField";
4
4
  import { HasIdAndName, Optional } from "../types";
@@ -1,4 +1,4 @@
1
- import { FieldState } from "@homebound/form-state/dist/formState";
1
+ import { FieldState } from "@homebound/form-state";
2
2
  import { MultiSelectFieldProps, Value } from "../inputs";
3
3
  import { HasIdAndName, Optional } from "../types";
4
4
  export declare type BoundMultiSelectFieldProps<O, V extends Value> = Omit<MultiSelectFieldProps<O, V>, "values" | "onSelect" | "label"> & {
@@ -1,4 +1,4 @@
1
- import { FieldState } from "@homebound/form-state/dist/formState";
1
+ import { FieldState } from "@homebound/form-state";
2
2
  import { SelectFieldProps, Value } from "../inputs";
3
3
  import { HasIdAndName, Optional } from "../types";
4
4
  export declare type BoundSelectFieldProps<T, V extends Value> = Omit<SelectFieldProps<T, V>, "value" | "onSelect" | "label"> & {
@@ -56,9 +56,9 @@ function FormStateApp() {
56
56
  { value: "a:4", label: "Iguana" },
57
57
  { value: "a:5", label: "Turtle" },
58
58
  ];
59
- return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.$ }, { children: [(0, jsx_runtime_1.jsxs)("header", Object.assign({ css: Css_1.Css.wPx(700).$ }, { children: [(0, jsx_runtime_1.jsxs)(FormLines_1.FormLines, Object.assign({ labelSuffix: { required: "*", optional: "(Opt)" } }, { children: [(0, jsx_runtime_1.jsx)("b", { children: "Author" }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.firstName }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.middleInitial }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.lastName }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundDateField, { field: formState.birthday }, void 0), (0, jsx_runtime_1.jsxs)(forms_1.FieldGroup, { children: [(0, jsx_runtime_1.jsx)(forms_1.StaticField, { label: "Revenue", value: "$500" }, void 0), (0, jsx_runtime_1.jsx)(forms_1.StaticLinkField, { label: "Website", href: "https://google.com" }, void 0)] }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundNumberField, { field: formState.heightInInches }, void 0), (0, jsx_runtime_1.jsx)(forms_1.FormDivider, {}, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundSelectField, { field: formState.favoriteSport, options: sports }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundMultiSelectField, { field: formState.favoriteShapes, options: shapes }, void 0), (0, jsx_runtime_1.jsx)(BoundCheckboxGroupField_1.BoundCheckboxGroupField, { field: formState.favoriteColors, options: colors }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundToggleChipGroupField, { field: formState.animals, options: animals }, void 0), (0, jsx_runtime_1.jsx)(forms_1.FormDivider, {}, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundSwitchField, { field: formState.isAvailable }, void 0)] }), void 0), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("strong", { children: ["Books", (0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "plus", onClick: () => formState.books.add({ id: String(formState.books.value.length) }) }, void 0)] }, void 0), (0, jsx_runtime_1.jsx)(components_1.GridTable, { columns: columns, rows: rows, observeRows: true }, void 0)] }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.childGap1.$ }, { children: [(0, jsx_runtime_1.jsx)(components_1.Button, { onClick: () => formState.reset(), label: "Cancel" }, void 0), (0, jsx_runtime_1.jsx)(components_1.Button, { onClick: () => {
59
+ return ((0, jsx_runtime_1.jsx)(mobx_react_1.Observer, { children: () => ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.$ }, { children: [(0, jsx_runtime_1.jsxs)("header", Object.assign({ css: Css_1.Css.wPx(700).$ }, { children: [(0, jsx_runtime_1.jsxs)(FormLines_1.FormLines, Object.assign({ labelSuffix: { required: "*", optional: "(Opt)" } }, { children: [(0, jsx_runtime_1.jsx)("b", { children: "Author" }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.firstName }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.middleInitial }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundTextField, { field: formState.lastName }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundDateField, { field: formState.birthday }, void 0), (0, jsx_runtime_1.jsxs)(forms_1.FieldGroup, { children: [(0, jsx_runtime_1.jsx)(forms_1.StaticField, { label: "Revenue", value: "$500" }, void 0), (0, jsx_runtime_1.jsx)(forms_1.StaticLinkField, { label: "Website", href: "https://google.com" }, void 0)] }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundNumberField, { field: formState.heightInInches }, void 0), (0, jsx_runtime_1.jsx)(forms_1.FormDivider, {}, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundSelectField, { field: formState.favoriteSport, options: sports }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundMultiSelectField, { field: formState.favoriteShapes, options: shapes }, void 0), (0, jsx_runtime_1.jsx)(BoundCheckboxGroupField_1.BoundCheckboxGroupField, { field: formState.favoriteColors, options: colors }, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundToggleChipGroupField, { field: formState.animals, options: animals }, void 0), (0, jsx_runtime_1.jsx)(forms_1.FormDivider, {}, void 0), (0, jsx_runtime_1.jsx)(forms_1.BoundSwitchField, { field: formState.isAvailable }, void 0)] }), void 0), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("strong", { children: ["Books", (0, jsx_runtime_1.jsx)(components_1.IconButton, { icon: "plus", onClick: () => formState.books.add({ id: String(formState.books.value.length) }) }, void 0)] }, void 0), (0, jsx_runtime_1.jsx)(components_1.GridTable, { columns: columns, rows: rows, observeRows: true }, void 0)] }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.childGap1.$ }, { children: [(0, jsx_runtime_1.jsx)(components_1.Button, { onClick: () => formState.revertChanges(), label: "Cancel" }, void 0), (0, jsx_runtime_1.jsx)(components_1.Button, { onClick: () => {
60
60
  if (formState.canSave()) {
61
- formState.save();
61
+ formState.commitChanges();
62
62
  }
63
63
  }, label: "Save" }, void 0)] }), void 0)] }), void 0), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(components_1.Button, { label: "Read Only", onClick: () => setReadOnly(!readOnly) }, void 0) }, void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.mt1.$ }, { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Form Values:" }, void 0), (0, jsx_runtime_1.jsx)("pre", { children: JSON.stringify(formState.value, null, 2) }, void 0)] }), void 0)] }, void 0)] }), void 0)) }, void 0));
64
64
  }
@@ -89,7 +89,7 @@ function MiscAuthorDetails({ formState, onBack }) {
89
89
  var _a, _b;
90
90
  return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", Object.assign({ css: Css_1.Css.mb1.$ }, { children: "Author Details" }), void 0), (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.mb2.$ }, { children: (0, jsx_runtime_1.jsx)(BoundDateField_1.BoundDateField, { field: formState.birthday, helperText: "Required" }, void 0) }), void 0), (0, jsx_runtime_1.jsx)("div", Object.assign({ css: Css_1.Css.mb2.$ }, { children: (0, jsx_runtime_1.jsx)(BoundNumberField_1.BoundNumberField, { field: formState.heightInInches }, void 0) }), void 0), (0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.df.jcsb.bt.bGray300.py1.mt2.$ }, { children: [(0, jsx_runtime_1.jsx)(components_1.Button, { variant: "tertiary", label: "Back", onClick: onBack }, void 0), (0, jsx_runtime_1.jsx)(components_1.Button, { disabled: !formState.valid, onClick: () => {
91
91
  if (formState.canSave()) {
92
- formState.save();
92
+ formState.commitChanges();
93
93
  setShowFormData(true);
94
94
  }
95
95
  }, label: "Save" }, void 0)] }), void 0), showFormData && ((0, jsx_runtime_1.jsxs)("div", Object.assign({ css: Css_1.Css.mt5.$ }, { children: [(0, jsx_runtime_1.jsx)("h2", { children: "Form saved!" }, void 0), (0, jsx_runtime_1.jsxs)("ul", { children: [(0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "First Name" }, void 0), " ", formState.value.firstName] }, void 0), (0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Last Name" }, void 0), " ", formState.value.lastName] }, void 0), (0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Books" }, void 0), " ", (_a = formState.value.books) === null || _a === void 0 ? void 0 : _a.map((b) => b.title).join(", ")] }, void 0), (0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Birthday" }, void 0), " ", (_b = formState.value.birthday) === null || _b === void 0 ? void 0 : _b.toDateString()] }, void 0), (0, jsx_runtime_1.jsxs)("li", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Height" }, void 0), " ", formState.value.heightInInches] }, void 0)] }, void 0)] }), void 0))] }, void 0));
@@ -6,7 +6,7 @@ const react_1 = require("react");
6
6
  /** Evaluates a computed function `fn` to a regular value and triggers a re-render whenever it changes. */
7
7
  function useComputed(fn, deps) {
8
8
  // We always return the useRef value, and use this just to trigger re-renders
9
- const [, setValue] = (0, react_1.useState)(0);
9
+ const [, setTick] = (0, react_1.useState)(0);
10
10
  const ref = (0, react_1.useRef)({
11
11
  runner: undefined,
12
12
  value: undefined,
@@ -17,25 +17,25 @@ function useComputed(fn, deps) {
17
17
  // with `useEffect`, which would only get calc'd after the 1st render has
18
18
  // already been done.
19
19
  (0, react_1.useMemo)(() => {
20
- let tick = 0;
21
20
  const { current } = ref;
22
21
  // If deps has changed, unhook the previous observer
23
22
  if (current.runner) {
24
23
  current.runner();
25
24
  }
25
+ // If deps has changed, we're already re-running, so don't trigger a 2nd one
26
+ current.hasRan = false;
26
27
  current.runner = (0, mobx_1.autorun)(() => {
27
28
  // Always eval fn() (even on 1st render) to register our observable.
28
29
  const newValue = fn();
29
- const oldValue = current.value;
30
+ const { value: oldValue, hasRan: oldHasRun } = current;
30
31
  current.value = newValue;
31
32
  current.hasRan = true;
32
33
  // Only trigger a re-render if this is not the 1st autorun. Note
33
34
  // that if deps has changed, we're inherently in a re-render so also
34
35
  // don't need to trigger an additional re-render.
35
- if (tick > 0 && newValue !== oldValue) {
36
- setValue(tick);
36
+ if (oldHasRun && newValue !== oldValue) {
37
+ setTick((tick) => tick + 1);
37
38
  }
38
- tick++;
39
39
  });
40
40
  // eslint-disable-next-line react-hooks/exhaustive-deps
41
41
  }, deps);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.117.0",
3
+ "version": "2.117.3",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -33,7 +33,7 @@
33
33
  "format": "prettier --loglevel warn --write \"**/*.{ts,tsx,css,md}\""
34
34
  },
35
35
  "dependencies": {
36
- "@homebound/form-state": "2.5.0",
36
+ "@homebound/form-state": "2.13.0",
37
37
  "@internationalized/number": "^3.0.3",
38
38
  "@react-aria/utils": "^3.9.0",
39
39
  "@react-hook/resize-observer": "^1.2.2",