@xh/hoist 71.0.0-SNAPSHOT.1735588181793 → 71.0.0-SNAPSHOT.1735657683714

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/CHANGELOG.md CHANGED
@@ -53,6 +53,11 @@
53
53
  * Improved accuracy of `IconProps` interface, with use of the `IconName` and `IconPrefix` types
54
54
  provided by FontAwesome.
55
55
  * Improved accuracy of `PersistOptions.type` enum.
56
+ * Corrected the type of `ColumnSpec.editor`.
57
+
58
+ ### 📚 Libraries
59
+
60
+ * react-grid-layout `1.4.3 → 1.5.0`
56
61
 
57
62
  ## v70.0.0 - 2024-11-15
58
63
 
@@ -1,4 +1,4 @@
1
- import { IRowNode } from '@xh/hoist/kit/ag-grid';
1
+ import { CustomCellEditorProps } from '@ag-grid-community/react';
2
2
  import { GridFilterFieldSpecConfig } from '@xh/hoist/cmp/grid/filter/GridFilterFieldSpec';
3
3
  import { HSide, PersistOptions, Some } from '@xh/hoist/core';
4
4
  import { Store, StoreRecord, View } from '@xh/hoist/data';
@@ -6,7 +6,7 @@ import { ReactElement, ReactNode } from 'react';
6
6
  import { Column } from './columns/Column';
7
7
  import { ColumnGroup } from './columns/ColumnGroup';
8
8
  import { GridModel } from './GridModel';
9
- import type { CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, ITooltipParams, RowClassParams, ValueSetterParams } from '@xh/hoist/kit/ag-grid';
9
+ import type { CellClassParams, HeaderClassParams, HeaderValueGetterParams, ICellRendererParams, IRowNode, ITooltipParams, RowClassParams, ValueSetterParams } from '@xh/hoist/kit/ag-grid';
10
10
  export interface ColumnState {
11
11
  colId: string;
12
12
  width: number;
@@ -220,15 +220,23 @@ export type ColumnEditableFn = (params: {
220
220
  gridModel: GridModel;
221
221
  }) => boolean;
222
222
  /**
223
- * Function to return one Grid cell editor. This value will be used to create a new Component
224
- * whenever editing is initiated on a cell.
223
+ * Function to return one Grid cell editor. This function will be used to create a new
224
+ * Component, whenever editing is initiated on a cell.
225
+ * The never parameter is never provided - it is included to satisfy typescript. See
226
+ * discussion in https://github.com/xh/hoist-react/pull/3351.
225
227
  * @returns the react element to use as the cell editor.
226
228
  */
227
- export type ColumnEditorFn = (params: {
229
+ export type ColumnEditorFn = (props: ColumnEditorProps, never?: any) => ReactElement;
230
+ /**
231
+ * The object passed into the first argument of {@link ColumnSpec.editor}.
232
+ * Satisfies the {@link EditorProps} of an editor component.
233
+ */
234
+ export type ColumnEditorProps = {
228
235
  record: StoreRecord;
229
236
  column: Column;
230
237
  gridModel: GridModel;
231
- }) => ReactElement;
238
+ agParams: CustomCellEditorProps;
239
+ };
232
240
  /**
233
241
  * Function to update the value of a StoreRecord field after inline editing
234
242
  */
@@ -1,9 +1,8 @@
1
1
  import { HAlign, HSide, PlainObject, Some, Thunkable } from '@xh/hoist/core';
2
2
  import { CubeFieldSpec, FieldSpec, RecordAction, RecordActionSpec, StoreRecord } from '@xh/hoist/data';
3
- import { ReactNode } from 'react';
3
+ import { FunctionComponent, ReactNode } from 'react';
4
4
  import { GridModel } from '../GridModel';
5
- import { ColumnCellClassFn, ColumnCellClassRuleFn, ColumnComparator, ColumnEditableFn, ColumnEditorFn, ColumnExcelFormatFn, ColumnExportValueFn, ColumnGetValueFn, ColumnHeaderClassFn, ColumnHeaderNameFn, ColumnRenderer, ColumnSetValueFn, ColumnSortSpec, ColumnSortValueFn, ColumnTooltipFn } from '../Types';
6
- import { FunctionComponent } from 'react';
5
+ import { ColumnCellClassFn, ColumnCellClassRuleFn, ColumnComparator, ColumnEditableFn, ColumnEditorFn, ColumnEditorProps, ColumnExcelFormatFn, ColumnExportValueFn, ColumnGetValueFn, ColumnHeaderClassFn, ColumnHeaderNameFn, ColumnRenderer, ColumnSetValueFn, ColumnSortSpec, ColumnSortValueFn, ColumnTooltipFn } from '../Types';
7
6
  import type { ColDef } from '@xh/hoist/kit/ag-grid';
8
7
  export interface ColumnSpec {
9
8
  /**
@@ -216,10 +215,10 @@ export interface ColumnSpec {
216
215
  */
217
216
  editable?: boolean | ColumnEditableFn;
218
217
  /**
219
- * Cell editor Component or a function to create one. Adding an editor will also
220
- * install a cellClassRule and tooltip to display the validation state of the cell in question.
218
+ * Cell editor Component or a function to create one. Adding an editor will also install a
219
+ * cellClassRule and tooltip to display the validation state of the cell in question.
221
220
  */
222
- editor?: FunctionComponent | ColumnEditorFn;
221
+ editor?: FunctionComponent<ColumnEditorProps> | ColumnEditorFn;
223
222
  /**
224
223
  * True if this cell editor should be rendered as a popup over the cell instead of within the
225
224
  * actual cell element. Popup editors will have their width set to match the cell by default.
@@ -330,7 +329,7 @@ export declare class Column {
330
329
  autosizeBufferPx: number;
331
330
  autoHeight: boolean;
332
331
  editable: boolean | ColumnEditableFn;
333
- editor: FunctionComponent | ColumnEditorFn;
332
+ editor: FunctionComponent<ColumnEditorProps> | ColumnEditorFn;
334
333
  editorIsPopup: boolean;
335
334
  setValueFn: ColumnSetValueFn;
336
335
  getValueFn: ColumnGetValueFn;
@@ -3,17 +3,23 @@ import { Persistable, PersistableState } from '@xh/hoist/core';
3
3
  import { DashCanvasViewModel, DashCanvasViewSpec, DashConfig, DashViewState, DashModel } from '../';
4
4
  import '@xh/hoist/desktop/register';
5
5
  export interface DashCanvasConfig extends DashConfig<DashCanvasViewSpec, DashCanvasItemState> {
6
- /** Total number of columns (x coordinates for views correspond with column numbers). */
6
+ /**
7
+ * Total number of columns (x coordinates for views correspond with column numbers).
8
+ * Default `12`.
9
+ */
7
10
  columns?: number;
8
- /** Height of each row in pixels (y coordinates for views correspond with row numbers). */
11
+ /**
12
+ * Height of each row in pixels (y coordinates for views correspond with row numbers).
13
+ * Default `50`.
14
+ */
9
15
  rowHeight?: number;
10
- /** Whether views should "compact" vertically to condense vertical space. */
16
+ /** Whether views should "compact" vertically to condense vertical space. Default `true`. */
11
17
  compact?: boolean;
12
- /** Between items [x,y] in pixels. */
18
+ /** Between items [x,y] in pixels. Default `[10, 10]`. */
13
19
  margin?: [number, number];
14
- /** Maximum number of rows permitted for this container. */
20
+ /** Maximum number of rows permitted for this container. Default `Infinity`. */
15
21
  maxRows?: number;
16
- /** Padding inside the container [x, y] in pixels. */
22
+ /** Padding inside the container [x, y] in pixels. Defaults to same as `margin`. */
17
23
  containerPadding?: [number, number];
18
24
  }
19
25
  export interface DashCanvasItemState {
@@ -47,7 +53,6 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
47
53
  layout: any[];
48
54
  ref: import("react").RefObject<HTMLElement> & import("react").RefCallback<HTMLElement>;
49
55
  isResizing: boolean;
50
- private scrollbarVisible;
51
56
  private isLoadingState;
52
57
  get rglLayout(): any[];
53
58
  constructor({ viewSpecs, viewSpecDefaults, initialState, layoutLocked, contentLocked, renameLocked, persistWith, emptyText, addViewButtonText, columns, rowHeight, compact, margin, maxRows, containerPadding, extraMenuItems }: DashCanvasConfig);
@@ -96,7 +101,6 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
96
101
  }>): void;
97
102
  private getLayoutFromPosition;
98
103
  private addViewInternal;
99
- onVisibleChange(visible: boolean): void;
100
104
  onRglLayoutChange(rglLayout: any): void;
101
105
  private setLayout;
102
106
  private loadState;
@@ -110,5 +114,4 @@ export declare class DashCanvasModel extends DashModel<DashCanvasViewSpec, DashC
110
114
  private hasSpec;
111
115
  private getViewsBySpecId;
112
116
  private getNextAvailablePosition;
113
- private fireWindowResizeEvent;
114
117
  }
@@ -12,6 +12,6 @@ export interface EditorProps<InputPropsT extends HoistInputProps> extends HoistP
12
12
  /** StoreRecord being edited. */
13
13
  record: StoreRecord;
14
14
  /** Props to pass through to the underlying HoistInput component */
15
- inputProps: InputPropsT;
15
+ inputProps?: InputPropsT;
16
16
  agParams: CustomCellEditorProps;
17
17
  }
package/cmp/grid/Types.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * Copyright © 2025 Extremely Heavy Industries Inc.
6
6
  */
7
7
 
8
- import {IRowNode} from '@xh/hoist/kit/ag-grid';
8
+ import {CustomCellEditorProps} from '@ag-grid-community/react';
9
9
  import {GridFilterFieldSpecConfig} from '@xh/hoist/cmp/grid/filter/GridFilterFieldSpec';
10
10
  import {HSide, PersistOptions, Some} from '@xh/hoist/core';
11
11
  import {Store, StoreRecord, View} from '@xh/hoist/data';
@@ -19,6 +19,7 @@ import type {
19
19
  HeaderClassParams,
20
20
  HeaderValueGetterParams,
21
21
  ICellRendererParams,
22
+ IRowNode,
22
23
  ITooltipParams,
23
24
  RowClassParams,
24
25
  ValueSetterParams
@@ -278,15 +279,24 @@ export type ColumnEditableFn = (params: {
278
279
  }) => boolean;
279
280
 
280
281
  /**
281
- * Function to return one Grid cell editor. This value will be used to create a new Component
282
- * whenever editing is initiated on a cell.
282
+ * Function to return one Grid cell editor. This function will be used to create a new
283
+ * Component, whenever editing is initiated on a cell.
284
+ * The never parameter is never provided - it is included to satisfy typescript. See
285
+ * discussion in https://github.com/xh/hoist-react/pull/3351.
283
286
  * @returns the react element to use as the cell editor.
284
287
  */
285
- export type ColumnEditorFn = (params: {
288
+ export type ColumnEditorFn = (props: ColumnEditorProps, never?: any) => ReactElement;
289
+
290
+ /**
291
+ * The object passed into the first argument of {@link ColumnSpec.editor}.
292
+ * Satisfies the {@link EditorProps} of an editor component.
293
+ */
294
+ export type ColumnEditorProps = {
286
295
  record: StoreRecord;
287
296
  column: Column;
288
297
  gridModel: GridModel;
289
- }) => ReactElement;
298
+ agParams: CustomCellEditorProps;
299
+ };
290
300
 
291
301
  /**
292
302
  * Function to update the value of a StoreRecord field after inline editing
@@ -34,9 +34,9 @@ import {
34
34
  toString
35
35
  } from 'lodash';
36
36
  import {
37
- Attributes,
38
37
  createElement,
39
38
  forwardRef,
39
+ FunctionComponent,
40
40
  isValidElement,
41
41
  ReactNode,
42
42
  useImperativeHandle,
@@ -52,6 +52,7 @@ import {
52
52
  ColumnComparator,
53
53
  ColumnEditableFn,
54
54
  ColumnEditorFn,
55
+ ColumnEditorProps,
55
56
  ColumnExcelFormatFn,
56
57
  ColumnExportValueFn,
57
58
  ColumnGetValueFn,
@@ -64,7 +65,6 @@ import {
64
65
  ColumnTooltipFn
65
66
  } from '../Types';
66
67
  import {ExcelFormat} from '../enums/ExcelFormat';
67
- import {FunctionComponent} from 'react';
68
68
  import type {
69
69
  ColDef,
70
70
  ITooltipParams,
@@ -333,10 +333,10 @@ export interface ColumnSpec {
333
333
  editable?: boolean | ColumnEditableFn;
334
334
 
335
335
  /**
336
- * Cell editor Component or a function to create one. Adding an editor will also
337
- * install a cellClassRule and tooltip to display the validation state of the cell in question.
336
+ * Cell editor Component or a function to create one. Adding an editor will also install a
337
+ * cellClassRule and tooltip to display the validation state of the cell in question.
338
338
  */
339
- editor?: FunctionComponent | ColumnEditorFn;
339
+ editor?: FunctionComponent<ColumnEditorProps> | ColumnEditorFn;
340
340
 
341
341
  /**
342
342
  * True if this cell editor should be rendered as a popup over the cell instead of within the
@@ -471,7 +471,7 @@ export class Column {
471
471
  autosizeBufferPx: number;
472
472
  autoHeight: boolean;
473
473
  editable: boolean | ColumnEditableFn;
474
- editor: FunctionComponent | ColumnEditorFn;
474
+ editor: FunctionComponent<ColumnEditorProps> | ColumnEditorFn;
475
475
  editorIsPopup: boolean;
476
476
  setValueFn: ColumnSetValueFn;
477
477
  getValueFn: ColumnGetValueFn;
@@ -986,8 +986,7 @@ export class Column {
986
986
  ref
987
987
  };
988
988
  // Can be a component or elem factory/ ad-hoc render function.
989
- if ((editor as any).isHoistComponent)
990
- return createElement(editor, props as Attributes);
989
+ if ((editor as any).isHoistComponent) return createElement(editor, props);
991
990
  if (isFunction(editor)) return editor(props);
992
991
  throw XH.exception('Column editor must be a HoistComponent or a render function');
993
992
  });
@@ -19,7 +19,6 @@ import {dashCanvasAddViewButton} from '@xh/hoist/desktop/cmp/button/DashCanvasAd
19
19
  import '@xh/hoist/desktop/register';
20
20
  import {Classes, overlay} from '@xh/hoist/kit/blueprint';
21
21
  import {TEST_ID} from '@xh/hoist/utils/js';
22
- import {useOnVisibleChange} from '@xh/hoist/utils/react';
23
22
  import classNames from 'classnames';
24
23
  import ReactGridLayout, {WidthProvider} from 'react-grid-layout';
25
24
  import {DashCanvasModel} from './DashCanvasModel';
@@ -49,13 +48,8 @@ export const [DashCanvas, dashCanvas] = hoistCmp.withFactory<DashCanvasProps>({
49
48
 
50
49
  render({className, model, testId}, ref) {
51
50
  const isDraggable = !model.layoutLocked,
52
- isResizable = !model.layoutLocked;
53
-
54
- ref = composeRefs(
55
- ref,
56
- model.ref,
57
- useOnVisibleChange(viz => model.onVisibleChange(viz))
58
- );
51
+ isResizable = !model.layoutLocked,
52
+ [padX, padY] = model.containerPadding;
59
53
 
60
54
  return refreshContextView({
61
55
  model: model.refreshContextModel,
@@ -65,7 +59,8 @@ export const [DashCanvas, dashCanvas] = hoistCmp.withFactory<DashCanvasProps>({
65
59
  isDraggable ? `${className}--draggable` : null,
66
60
  isResizable ? `${className}--resizable` : null
67
61
  ),
68
- ref,
62
+ style: {padding: `${padY}px ${padX}px`},
63
+ ref: composeRefs(ref, model.ref),
69
64
  onContextMenu: e => onContextMenu(e, model),
70
65
  items: [
71
66
  reactGridLayout({
@@ -77,7 +72,7 @@ export const [DashCanvas, dashCanvas] = hoistCmp.withFactory<DashCanvasProps>({
77
72
  compactType: model.compact ? 'vertical' : null,
78
73
  margin: model.margin,
79
74
  maxRows: model.maxRows,
80
- containerPadding: model.containerPadding,
75
+ containerPadding: [0, 0], // Workaround for https://github.com/react-grid-layout/react-grid-layout/issues/1990
81
76
  autoSize: true,
82
77
  isBounded: true,
83
78
  draggableHandle:
@@ -27,22 +27,28 @@ import {
27
27
  } from 'lodash';
28
28
 
29
29
  export interface DashCanvasConfig extends DashConfig<DashCanvasViewSpec, DashCanvasItemState> {
30
- /** Total number of columns (x coordinates for views correspond with column numbers). */
30
+ /**
31
+ * Total number of columns (x coordinates for views correspond with column numbers).
32
+ * Default `12`.
33
+ */
31
34
  columns?: number;
32
35
 
33
- /** Height of each row in pixels (y coordinates for views correspond with row numbers). */
36
+ /**
37
+ * Height of each row in pixels (y coordinates for views correspond with row numbers).
38
+ * Default `50`.
39
+ */
34
40
  rowHeight?: number;
35
41
 
36
- /** Whether views should "compact" vertically to condense vertical space. */
42
+ /** Whether views should "compact" vertically to condense vertical space. Default `true`. */
37
43
  compact?: boolean;
38
44
 
39
- /** Between items [x,y] in pixels. */
45
+ /** Between items [x,y] in pixels. Default `[10, 10]`. */
40
46
  margin?: [number, number];
41
47
 
42
- /** Maximum number of rows permitted for this container. */
48
+ /** Maximum number of rows permitted for this container. Default `Infinity`. */
43
49
  maxRows?: number;
44
50
 
45
- /** Padding inside the container [x, y] in pixels. */
51
+ /** Padding inside the container [x, y] in pixels. Defaults to same as `margin`. */
46
52
  containerPadding?: [number, number];
47
53
  }
48
54
 
@@ -97,7 +103,6 @@ export class DashCanvasModel
97
103
  @observable.ref layout: any[] = [];
98
104
  ref = createObservableRef<HTMLElement>();
99
105
  isResizing: boolean;
100
- private scrollbarVisible: boolean;
101
106
  private isLoadingState: boolean;
102
107
 
103
108
  get rglLayout() {
@@ -131,7 +136,7 @@ export class DashCanvasModel
131
136
  compact = true,
132
137
  margin = [10, 10],
133
138
  maxRows = Infinity,
134
- containerPadding = null,
139
+ containerPadding = margin,
135
140
  extraMenuItems
136
141
  }: DashCanvasConfig) {
137
142
  super();
@@ -194,19 +199,10 @@ export class DashCanvasModel
194
199
  });
195
200
  }
196
201
 
197
- this.addReaction(
198
- {
199
- track: () => this.viewState,
200
- run: () => (this.state = this.buildState())
201
- },
202
- {
203
- when: () => !!this.ref.current,
204
- run: () => {
205
- const {current: node} = this.ref;
206
- this.scrollbarVisible = node.offsetWidth > node.clientWidth;
207
- }
208
- }
209
- );
202
+ this.addReaction({
203
+ track: () => this.viewState,
204
+ run: () => (this.state = this.buildState())
205
+ });
210
206
  }
211
207
 
212
208
  /** Removes all views from the canvas */
@@ -385,12 +381,6 @@ export class DashCanvasModel
385
381
  return model;
386
382
  }
387
383
 
388
- // Trigger window resize event when component becomes visible to ensure layout adjusted to
389
- // current window size - fixes https://github.com/xh/hoist-react/issues/3215
390
- onVisibleChange(visible: boolean) {
391
- if (visible) this.fireWindowResizeEvent();
392
- }
393
-
394
384
  onRglLayoutChange(rglLayout) {
395
385
  rglLayout = rglLayout.map(it => pick(it, ['i', 'x', 'y', 'w', 'h']));
396
386
  this.setLayout(rglLayout);
@@ -404,15 +394,6 @@ export class DashCanvasModel
404
394
 
405
395
  this.layout = layout;
406
396
  if (!this.isLoadingState) this.state = this.buildState();
407
-
408
- // Check if scrollbar visibility has changed, and force resize event if so
409
- const node = this.ref.current;
410
- if (!node) return;
411
- const scrollbarVisible = node.offsetWidth > node.clientWidth;
412
- if (scrollbarVisible !== this.scrollbarVisible) {
413
- this.fireWindowResizeEvent();
414
- this.scrollbarVisible = scrollbarVisible;
415
- }
416
397
  }
417
398
 
418
399
  @action
@@ -530,8 +511,4 @@ export class DashCanvasModel
530
511
 
531
512
  return {x: defaultX, y: endY ?? rows};
532
513
  }
533
-
534
- private fireWindowResizeEvent() {
535
- window.dispatchEvent(new Event('resize'));
536
- }
537
514
  }
@@ -22,7 +22,7 @@ export interface EditorProps<InputPropsT extends HoistInputProps> extends HoistP
22
22
  record: StoreRecord;
23
23
 
24
24
  /** Props to pass through to the underlying HoistInput component */
25
- inputProps: InputPropsT;
25
+ inputProps?: InputPropsT;
26
26
 
27
27
  agParams: CustomCellEditorProps;
28
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "71.0.0-SNAPSHOT.1735588181793",
3
+ "version": "71.0.0-SNAPSHOT.1735657683714",
4
4
  "description": "Hoist add-on for building and deploying React Applications.",
5
5
  "repository": "github:xh/hoist-react",
6
6
  "homepage": "https://xh.io",
@@ -69,7 +69,7 @@
69
69
  "react-beautiful-dnd": "~13.1.0",
70
70
  "react-dates": "~21.8.0",
71
71
  "react-dropzone": "~10.2.2",
72
- "react-grid-layout": "1.4.3",
72
+ "react-grid-layout": "1.5.0",
73
73
  "react-markdown": "~9.0.1",
74
74
  "react-onsenui": "~1.13.2",
75
75
  "react-popper": "~2.3.0",