@xh/hoist 75.0.0-SNAPSHOT.1752604774043 → 75.0.0-SNAPSHOT.1752765224740

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
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 75.0-SNAPSHOT - NOT YET RELEASED
3
+ ## 75.0-SNAPSHOT - Unreleased
4
4
 
5
5
  ### 🐞 Bug Fixes
6
6
 
@@ -9,6 +9,12 @@
9
9
  * DashCanvas: style with `position: relative;` to ensure that the empty state overlay is positioned
10
10
  within the canvas, not the next parent container up that has `position: relative;`.
11
11
 
12
+ * `useContextModel` is now reactive to a change of an (observable) resolved model when it is set.
13
+ Previously this value was cached on first render.
14
+
15
+ * Fixes to framework components that bind to grids (e.g. `ColChooserButton`, `ColAutosizeButton`,
16
+ `GridFindField`) to rebind to a new observable GridModel available via context.
17
+
12
18
  ## v74.1.2 - 2025-07-03
13
19
 
14
20
  ### 🐞 Bug Fixes
@@ -130,6 +130,7 @@ export const deviceIcon: ColumnSpec = {
130
130
  chooserGroup: 'Client App / Browser',
131
131
  headerName: Icon.desktop(),
132
132
  headerTooltip: 'Device',
133
+ exportName: 'Device',
133
134
  tooltip: true,
134
135
  resizable: false,
135
136
  align: 'center',
@@ -291,6 +292,7 @@ export const severityIcon: ColumnSpec = {
291
292
  field: severity.field,
292
293
  headerName: Icon.info(),
293
294
  headerTooltip: 'Severity',
295
+ exportName: 'Severity',
294
296
  tooltip: true,
295
297
  resizable: false,
296
298
  align: 'center',
@@ -146,7 +146,6 @@ const filterBar = hoistCmp.factory<ActivityTrackingModel>(({model}) => {
146
146
  });
147
147
 
148
148
  const aggregateView = hoistCmp.factory<ActivityTrackingModel>(({model}) => {
149
- const {gridModel} = model;
150
149
  return panel({
151
150
  collapsedTitle: 'Aggregate Activity',
152
151
  collapsedIcon: Icon.users(),
@@ -161,8 +160,8 @@ const aggregateView = hoistCmp.factory<ActivityTrackingModel>(({model}) => {
161
160
  items: [
162
161
  groupingChooser({flex: 10, maxWidth: 300}),
163
162
  filler(),
164
- colChooserButton({gridModel}),
165
- exportButton({gridModel})
163
+ colChooserButton(),
164
+ exportButton()
166
165
  ]
167
166
  }),
168
167
  items: [
@@ -36,16 +36,15 @@ export const activityDetailView = hoistCmp.factory({
36
36
  });
37
37
 
38
38
  const tbar = hoistCmp.factory<ActivityDetailModel>(({model}) => {
39
- const {gridModel} = model;
40
39
  return toolbar({
41
40
  compact: true,
42
41
  items: [
43
42
  filler(),
44
- gridCountLabel({gridModel, unit: 'entry'}),
43
+ gridCountLabel({unit: 'entry'}),
45
44
  '-',
46
- gridFindField({gridModel, key: gridModel.xhId, width: 250}),
47
- colChooserButton({gridModel}),
48
- exportButton({gridModel})
45
+ gridFindField({width: 250}),
46
+ colChooserButton(),
47
+ exportButton()
49
48
  ]
50
49
  });
51
50
  });
@@ -275,8 +275,6 @@ export declare class GridModel extends HoistModel {
275
275
  filterTask: TaskObserver;
276
276
  /** Tracks execution of autosize operations. */
277
277
  autosizeTask: TaskObserver;
278
- /** @internal - used internally by any GridFindField that is bound to this GridModel. */
279
- xhFindQuery: string;
280
278
  constructor(config: GridConfig);
281
279
  /**
282
280
  * Restore the column, sorting, and grouping configs as specified by the application at
@@ -1,4 +1,3 @@
1
- import { GridModel } from '@xh/hoist/cmp/grid';
2
1
  import { HoistModel } from '@xh/hoist/core';
3
2
  import { TextInputModel } from '@xh/hoist/desktop/cmp/input';
4
3
  /**
@@ -6,7 +5,7 @@ import { TextInputModel } from '@xh/hoist/desktop/cmp/input';
6
5
  */
7
6
  export declare class GridFindFieldImplModel extends HoistModel {
8
7
  xhImpl: boolean;
9
- gridModel: GridModel;
8
+ query: string;
10
9
  get matchMode(): string;
11
10
  get queryBuffer(): number;
12
11
  get includeFields(): string[];
@@ -20,8 +19,7 @@ export declare class GridFindFieldImplModel extends HoistModel {
20
19
  get hasFocus(): boolean;
21
20
  get hasQuery(): boolean;
22
21
  get hasResults(): boolean;
23
- get query(): string;
24
- setQuery(v: any): void;
22
+ get gridModel(): any;
25
23
  constructor();
26
24
  onLinked(): void;
27
25
  selectPrev(): void;
@@ -467,9 +467,6 @@ export class GridModel extends HoistModel {
467
467
  /** Tracks execution of autosize operations. */
468
468
  @managed autosizeTask = TaskObserver.trackAll();
469
469
 
470
- /** @internal - used internally by any GridFindField that is bound to this GridModel. */
471
- @bindable xhFindQuery: string = null;
472
-
473
470
  constructor(config: GridConfig) {
474
471
  super();
475
472
  makeObservable(this);
@@ -30,7 +30,7 @@ export const [RefreshContextView, refreshContextView] = hoistCmp.withFactory({
30
30
  parent.register(model);
31
31
  return () => parent.unregister(model);
32
32
  }
33
- });
33
+ }, [model, parent]);
34
34
 
35
35
  return children;
36
36
  }
@@ -27,9 +27,8 @@ import {each, isUndefined} from 'lodash';
27
27
  * @returns model or null if no matching model found.
28
28
  */
29
29
  export function useContextModel<T extends HoistModel>(selector: ModelSelector<T> = '*'): T {
30
- const modelLookup = useContext(ModelLookupContext),
31
- [ret] = useState(() => modelLookup?.lookupModel(selector) ?? null);
32
- return ret;
30
+ const modelLookup = useContext(ModelLookupContext);
31
+ return modelLookup?.lookupModel(selector);
33
32
  }
34
33
 
35
34
  /**
@@ -7,8 +7,8 @@
7
7
  import {GridModel} from '@xh/hoist/cmp/grid';
8
8
  import {HoistModel, XH} from '@xh/hoist/core';
9
9
  import {TextInputModel} from '@xh/hoist/desktop/cmp/input';
10
- import {action, comparer, computed, makeObservable, observable} from '@xh/hoist/mobx';
11
- import {errorIf, stripTags, throwIf, withDefault} from '@xh/hoist/utils/js';
10
+ import {action, bindable, comparer, computed, makeObservable, observable} from '@xh/hoist/mobx';
11
+ import {stripTags, withDefault} from '@xh/hoist/utils/js';
12
12
  import {createObservableRef} from '@xh/hoist/utils/react';
13
13
  import {
14
14
  escapeRegExp,
@@ -29,7 +29,8 @@ import {
29
29
  export class GridFindFieldImplModel extends HoistModel {
30
30
  override xhImpl = true;
31
31
 
32
- gridModel: GridModel;
32
+ @bindable
33
+ query: string = null;
33
34
 
34
35
  get matchMode(): string {
35
36
  return this.componentProps.matchMode ?? 'startWord';
@@ -79,35 +80,26 @@ export class GridFindFieldImplModel extends HoistModel {
79
80
  return !isNil(this.results) && !isEmpty(this.results);
80
81
  }
81
82
 
83
+ @computed
84
+ get gridModel() {
85
+ const ret = withDefault(this.componentProps.gridModel, this.lookupModel(GridModel));
86
+ if (!ret) {
87
+ this.logError("No GridModel available. Provide via a 'gridModel' prop, or context.");
88
+ } else if (!ret.selModel?.isEnabled) {
89
+ this.logError('GridFindField must be bound to GridModel with selection enabled.');
90
+ }
91
+ return ret;
92
+ }
93
+
82
94
  //------------------------------------------------------------------
83
95
  // Trampoline value to grid
84
96
  //------------------------------------------------------------------
85
- get query() {
86
- return this.gridModel.xhFindQuery;
87
- }
88
-
89
- @action
90
- setQuery(v) {
91
- this.gridModel.xhFindQuery = v;
92
- }
93
-
94
97
  constructor() {
95
98
  super();
96
99
  makeObservable(this);
97
100
  }
98
101
 
99
102
  override onLinked() {
100
- const gridModel = (this.gridModel = withDefault(
101
- this.componentProps.gridModel,
102
- this.lookupModel(GridModel)
103
- ));
104
- errorIf(
105
- !gridModel?.selModel?.isEnabled,
106
- 'GridFindField must be bound to GridModel with an enabled StoreSelectionModel.'
107
- );
108
-
109
- throwIf(!gridModel, "Must specify 'gridModel' in GridFindField.");
110
-
111
103
  this.addReaction({
112
104
  track: () => this.query,
113
105
  run: () => this.updateResults(true),
@@ -116,10 +108,10 @@ export class GridFindFieldImplModel extends HoistModel {
116
108
 
117
109
  this.addReaction({
118
110
  track: () => [
119
- gridModel.store.records,
120
- gridModel.columns,
121
- gridModel.sortBy,
122
- gridModel.groupBy
111
+ this.gridModel?.store.records,
112
+ this.gridModel?.columns,
113
+ this.gridModel?.sortBy,
114
+ this.gridModel?.groupBy
123
115
  ],
124
116
  run: () => {
125
117
  this._records = null;
@@ -184,7 +176,7 @@ export class GridFindFieldImplModel extends HoistModel {
184
176
 
185
177
  // Auto-select first matching result
186
178
  if (autoSelect && this.hasResults && !isFinite(this.selectedIdx)) {
187
- gridModel.selectAsync(this.results[0]);
179
+ gridModel?.selectAsync(this.results[0]);
188
180
  }
189
181
  }
190
182
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xh/hoist",
3
- "version": "75.0.0-SNAPSHOT.1752604774043",
3
+ "version": "75.0.0-SNAPSHOT.1752765224740",
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",