@homebound/beam 2.333.0 → 2.334.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.
@@ -197,7 +197,8 @@ function GridTable(props) {
197
197
  }
198
198
  evt.preventDefault();
199
199
  // set flags for css spacer
200
- recursiveSetDraggedOver(rows, RowState_1.DraggedOver.None);
200
+ // don't set none for the row we are entering
201
+ recursiveSetDraggedOver(rows.filter((r) => r.id !== row.id), RowState_1.DraggedOver.None);
201
202
  if (draggedRowRef.current) {
202
203
  if (draggedRowRef.current.id === row.id) {
203
204
  return;
@@ -213,7 +214,8 @@ function GridTable(props) {
213
214
  }
214
215
  evt.preventDefault();
215
216
  if (draggedRowRef.current) {
216
- if (draggedRowRef.current.id === row.id) {
217
+ if (draggedRowRef.current.id === row.id || !evt.currentTarget) {
218
+ tableState.maybeSetRowDraggedOver(row.id, RowState_1.DraggedOver.None, draggedRowRef.current);
217
219
  return;
218
220
  }
219
221
  // continuously determine above or below
@@ -12,6 +12,7 @@ const TableState_1 = require("../utils/TableState");
12
12
  const utils_1 = require("../utils/utils");
13
13
  const Css_1 = require("../../../Css");
14
14
  const utils_2 = require("../../../utils");
15
+ const use_debounce_1 = require("use-debounce");
15
16
  // We extract Row to its own mini-component primarily so we can React.memo'ize it.
16
17
  function RowImpl(props) {
17
18
  var _a, _b, _c;
@@ -32,8 +33,12 @@ function RowImpl(props) {
32
33
  const showRowHoverColor = !utils_1.reservedRowKinds.includes(row.kind) && !omitRowHover && style.rowHoverColor !== "none";
33
34
  const rowStyleCellCss = (0, utils_1.maybeApplyFunction)(row, rowStyle === null || rowStyle === void 0 ? void 0 : rowStyle.cellCss);
34
35
  const levelIndent = style.levels && ((_b = style.levels[level]) === null || _b === void 0 ? void 0 : _b.rowIndent);
36
+ const containerCss = {
37
+ ...Css_1.Css.add("transition", "padding 0.25s ease-in-out").$,
38
+ ...(rs.isDraggedOver === RowState_1.DraggedOver.Above && Css_1.Css.ptPx(25).$),
39
+ ...(rs.isDraggedOver === RowState_1.DraggedOver.Below && Css_1.Css.pbPx(25).$),
40
+ };
35
41
  const rowCss = {
36
- ...Css_1.Css.add("transition", "padding 0.5s ease-in-out").$,
37
42
  ...(!utils_1.reservedRowKinds.includes(row.kind) && style.nonHeaderRowCss),
38
43
  // Optionally include the row hover styles, by default they should be turned on.
39
44
  ...(showRowHoverColor && {
@@ -56,8 +61,6 @@ function RowImpl(props) {
56
61
  [`:hover > .${revealOnRowHoverClass} > *`]: Css_1.Css.visible.$,
57
62
  },
58
63
  ...(isLastKeptRow && Css_1.Css.addIn("&>*", style.keptLastRowCss).$),
59
- ...(rs.isDraggedOver === RowState_1.DraggedOver.Above && Css_1.Css.add("paddingTop", "35px").$),
60
- ...(rs.isDraggedOver === RowState_1.DraggedOver.Below && Css_1.Css.add("paddingBottom", "35px").$),
61
64
  };
62
65
  let currentColspan = 1;
63
66
  // Keep a running count of how many expanded columns are being shown.
@@ -67,10 +70,11 @@ function RowImpl(props) {
67
70
  let expandColumnHidden = false;
68
71
  // used to render the whole row when dragging with the handle
69
72
  const ref = (0, react_1.useRef)(null);
70
- return ((0, jsx_runtime_1.jsx)(RowTag, { css: rowCss, ...others, "data-gridrow": true, ...getCount(row.id),
71
- // these events are necessary to get the dragged-over row for the drop event
72
- // and spacer styling
73
- onDrop: (evt) => onDrop === null || onDrop === void 0 ? void 0 : onDrop(row, evt), onDragEnter: (evt) => onDragEnter === null || onDragEnter === void 0 ? void 0 : onDragEnter(row, evt), onDragOver: (evt) => onDragOver === null || onDragOver === void 0 ? void 0 : onDragOver(row, evt), ref: ref, children: isKeptGroupRow ? ((0, jsx_runtime_1.jsx)(KeptGroupRow_1.KeptGroupRow, { as: as, style: style, columnSizes: columnSizes, row: row, colSpan: columns.length })) : (columns.map((column, columnIndex) => {
73
+ // debounce drag over callback to avoid excessive re-renders
74
+ const dragOverCallback = (0, react_1.useCallback)((row, evt) => onDragOver === null || onDragOver === void 0 ? void 0 : onDragOver(row, evt), [onDragOver]);
75
+ // when the event is not called, we still need to call preventDefault
76
+ const onDragOverDebounced = (0, use_debounce_1.useDebouncedCallback)(dragOverCallback, 100);
77
+ const RowContent = () => ((0, jsx_runtime_1.jsx)(RowTag, { css: rowCss, ...others, "data-gridrow": true, ...getCount(row.id), children: isKeptGroupRow ? ((0, jsx_runtime_1.jsx)(KeptGroupRow_1.KeptGroupRow, { as: as, style: style, columnSizes: columnSizes, row: row, colSpan: columns.length })) : (columns.map((column, columnIndex) => {
74
78
  var _a, _b, _c, _d;
75
79
  // If the expandable column was hidden, then we need to look at the previous column to format the `expandHeader` and 'header' kinds correctly.
76
80
  const maybeExpandedColumn = expandColumnHidden ? columns[columnIndex - 1] : column;
@@ -126,7 +130,7 @@ function RowImpl(props) {
126
130
  onDragEnd,
127
131
  onDrop,
128
132
  onDragEnter,
129
- onDragOver,
133
+ onDragOver: onDragOverDebounced,
130
134
  });
131
135
  // Only use the `numExpandedColumns` as the `colspan` when rendering the "Expandable Header"
132
136
  currentColspan =
@@ -229,6 +233,15 @@ function RowImpl(props) {
229
233
  : (0, cell_1.defaultRenderFn)(as, currentColspan);
230
234
  return renderFn(columnIndex, cellCss, content, row, rowStyle, cellClassNames, cellOnClick, tooltip);
231
235
  })) }));
236
+ return row.draggable ? ((0, jsx_runtime_1.jsx)("div", { css: containerCss,
237
+ // these events are necessary to get the dragged-over row for the drop event
238
+ // and spacer styling
239
+ onDrop: (evt) => onDrop === null || onDrop === void 0 ? void 0 : onDrop(row, evt), onDragEnter: (evt) => onDragEnter === null || onDragEnter === void 0 ? void 0 : onDragEnter(row, evt), onDragOver: (evt) => {
240
+ // when the event isn't called due to debounce, we still need to
241
+ // call preventDefault for the drop event to fire
242
+ evt.preventDefault();
243
+ onDragOverDebounced(row, evt);
244
+ }, ref: ref, children: RowContent() })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: RowContent() }));
232
245
  }
233
246
  /**
234
247
  * Memoizes rows so that re-rendering the table doesn't re-render every single row.
@@ -184,6 +184,8 @@ class RowStates {
184
184
  return;
185
185
  }
186
186
  // this allows a single-row re-render
187
+ if (rs.isDraggedOver === draggedOver)
188
+ return;
187
189
  rs.isDraggedOver = draggedOver;
188
190
  }
189
191
  }
@@ -201,30 +201,21 @@ function dragHandleColumn(columnDef) {
201
201
  id: "beamDragHandleColumn",
202
202
  clientSideSort: false,
203
203
  align: "center",
204
- // Defining `w: 40px` to accommodate for the `16px` wide checkbox and `12px` of padding on either side.
205
204
  w: "40px",
206
205
  wrapAction: false,
207
206
  isAction: true,
208
207
  expandColumns: undefined,
209
- // Select Column should not display the select toggle for `expandableHeader` or `totals` row kinds
210
208
  expandableHeader: utils_1.emptyCell,
211
209
  totals: utils_1.emptyCell,
212
210
  // Use any of the user's per-row kind methods if they have them.
213
211
  ...columnDef,
214
212
  };
215
- // return newMethodMissingProxy(base, (key) => {
216
- // return (data: any, { row, level }: { row: GridDataRow<any>; level: number }) => ({
217
- // content: <CollapseToggle row={row} compact={level > 0} />,
218
- // });
219
- // }) as any;
220
213
  return (0, utils_2.newMethodMissingProxy)(base, (key) => {
221
214
  return (data, { row, dragData }) => {
222
215
  if (!dragData)
223
216
  return;
224
217
  const { rowRenderRef: ref, onDragStart, onDragEnd, onDrop, onDragEnter, onDragOver } = dragData;
225
218
  return {
226
- // how do we get the callbacks and the ref here?
227
- // inject them into the row in the Row component?
228
219
  content: row.draggable ? ((0, jsx_runtime_1.jsx)("div", { draggable: row.draggable, onDragStart: (evt) => {
229
220
  // show the whole row being dragged when dragging with the handle
230
221
  ref.current && evt.dataTransfer.setDragImage(ref.current, 0, 0);
@@ -179,8 +179,8 @@ exports.insertAtIndex = insertAtIndex;
179
179
  function isCursorBelowMidpoint(target, clientY) {
180
180
  const style = window.getComputedStyle(target);
181
181
  const rect = target.getBoundingClientRect();
182
- const pt = parseInt(style.getPropertyValue("padding-top")) / 2;
183
- const pb = parseInt(style.getPropertyValue("padding-bottom"));
182
+ const pt = parseFloat(style.getPropertyValue("padding-top"));
183
+ const pb = parseFloat(style.getPropertyValue("padding-bottom"));
184
184
  return clientY > rect.top + pt + (rect.height - pb) / 2;
185
185
  }
186
186
  exports.isCursorBelowMidpoint = isCursorBelowMidpoint;
@@ -115,13 +115,26 @@ function TreeSelectFieldBase(props) {
115
115
  return areAllSelected;
116
116
  }
117
117
  initialOptions.forEach(areAllChildrenSelected);
118
+ // Given a child option, determine if the parent is selected.
119
+ const isParentSelected = (option) => {
120
+ var _a;
121
+ const parents = (_a = (0, utils_1.findOption)(initialOptions, (0, Value_1.valueToKey)(getOptionValue(option)), getOptionValue)) === null || _a === void 0 ? void 0 : _a.parents;
122
+ if (!parents)
123
+ return false;
124
+ return parents.some((parent) => selectedKeys.includes((0, Value_1.valueToKey)(getOptionValue(parent))));
125
+ };
118
126
  return {
119
127
  selectedKeys,
120
128
  inputValue: selectedOptions.length === 1
121
129
  ? getOptionLabel(selectedOptions[0])
122
- : selectedOptions.length === 0
123
- ? nothingSelectedText
124
- : "",
130
+ : isReadOnly && selectedOptions.length > 0
131
+ ? selectedOptions
132
+ .filter((o) => !isParentSelected(o))
133
+ .map(getOptionLabel)
134
+ .join(", ")
135
+ : selectedOptions.length === 0
136
+ ? nothingSelectedText
137
+ : "",
125
138
  filteredOptions,
126
139
  selectedOptions,
127
140
  allOptions: initialOptions,
@@ -56,7 +56,7 @@ function ComboBoxBase(props) {
56
56
  // Do a one-time initialize of fieldState
57
57
  const [fieldState, setFieldState] = (0, react_1.useState)(() => {
58
58
  return {
59
- inputValue: getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText),
59
+ inputValue: getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText, isReadOnly),
60
60
  searchValue: undefined,
61
61
  optionsLoading: false,
62
62
  };
@@ -179,10 +179,10 @@ function ComboBoxBase(props) {
179
179
  else {
180
180
  setFieldState((prevState) => ({
181
181
  ...prevState,
182
- inputValue: getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText),
182
+ inputValue: getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText, isReadOnly),
183
183
  }));
184
184
  }
185
- }, [state.isOpen, selectedOptions, getOptionLabel, multiselect, nothingSelectedText]);
185
+ }, [state.isOpen, selectedOptions, getOptionLabel, multiselect, nothingSelectedText, isReadOnly]);
186
186
  // For the most part, the returned props contain `aria-*` and `id` attributes for accessibility purposes.
187
187
  const { buttonProps: triggerProps, inputProps, listBoxProps, labelProps, } = (0, react_aria_1.useComboBox)({
188
188
  ...comboBoxProps,
@@ -213,12 +213,14 @@ function ComboBoxBase(props) {
213
213
  return ((0, jsx_runtime_1.jsxs)("div", { css: Css_1.Css.df.fdc.w100.maxw(fieldMaxWidth).if(labelStyle === "left").maxw100.$, ref: comboBoxRef, children: [(0, jsx_runtime_1.jsx)(ComboBoxInput_1.ComboBoxInput, { ...otherProps, fullWidth: fullWidth, buttonProps: buttonProps, buttonRef: triggerRef, inputProps: inputProps, inputRef: inputRef, inputWrapRef: inputWrapRef, listBoxRef: listBoxRef, state: state, labelProps: labelProps, selectedOptions: selectedOptions, getOptionValue: getOptionValue, getOptionLabel: getOptionLabel, contrast: contrast, nothingSelectedText: nothingSelectedText, borderless: borderless, tooltip: (0, components_1.resolveTooltip)(disabled, undefined, readOnly), resetField: resetField }), state.isOpen && ((0, jsx_runtime_1.jsx)(internal_1.Popover, { triggerRef: triggerRef, popoverRef: popoverRef, positionProps: positionProps, onClose: () => state.close(), isOpen: state.isOpen, minWidth: 200, children: (0, jsx_runtime_1.jsx)(ListBox_1.ListBox, { ...listBoxProps, positionProps: positionProps, state: state, listBoxRef: listBoxRef, selectedOptions: selectedOptions, getOptionLabel: getOptionLabel, getOptionValue: (o) => (0, Value_1.valueToKey)(getOptionValue(o)), contrast: contrast, horizontalLayout: labelStyle === "left", loading: fieldState.optionsLoading, disabledOptionsWithReasons: disabledOptionsWithReasons }) }))] }));
214
214
  }
215
215
  exports.ComboBoxBase = ComboBoxBase;
216
- function getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText) {
216
+ function getInputValue(selectedOptions, getOptionLabel, multiselect, nothingSelectedText, readOnly) {
217
217
  return selectedOptions.length === 1
218
218
  ? getOptionLabel(selectedOptions[0])
219
- : multiselect && selectedOptions.length === 0
220
- ? nothingSelectedText
221
- : "";
219
+ : readOnly && selectedOptions.length > 0
220
+ ? selectedOptions.map(getOptionLabel).join(", ")
221
+ : multiselect && selectedOptions.length === 0
222
+ ? nothingSelectedText
223
+ : "";
222
224
  }
223
225
  /** Transforms/simplifies `optionsOrLoad` into just options, with unsetLabel maybe added. */
224
226
  function initializeOptions(optionsOrLoad, getOptionValue, unsetLabel) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homebound/beam",
3
- "version": "2.333.0",
3
+ "version": "2.334.0",
4
4
  "author": "Homebound",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",