@bryntum/grid-react-thin 7.3.1 → 7.3.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.
Files changed (43) hide show
  1. package/README.md +4 -4
  2. package/lib/BryntumAIFilterField.d.ts +1 -1
  3. package/lib/BryntumAIFilterField.js +1 -1
  4. package/lib/BryntumAIFilterField.js.map +1 -1
  5. package/lib/BryntumChecklistFilterCombo.d.ts +1 -1
  6. package/lib/BryntumChecklistFilterCombo.js +1 -1
  7. package/lib/BryntumChecklistFilterCombo.js.map +1 -1
  8. package/lib/BryntumGrid.js +1 -0
  9. package/lib/BryntumGrid.js.map +1 -1
  10. package/lib/BryntumGridBase.js +1 -0
  11. package/lib/BryntumGridBase.js.map +1 -1
  12. package/lib/BryntumGridChartDesigner.d.ts +1 -1
  13. package/lib/BryntumGridChartDesigner.js +1 -1
  14. package/lib/BryntumGridChartDesigner.js.map +1 -1
  15. package/lib/BryntumGridFieldFilterPicker.d.ts +1 -1
  16. package/lib/BryntumGridFieldFilterPicker.js +1 -1
  17. package/lib/BryntumGridFieldFilterPicker.js.map +1 -1
  18. package/lib/BryntumGridFieldFilterPickerGroup.d.ts +1 -1
  19. package/lib/BryntumGridFieldFilterPickerGroup.js +1 -1
  20. package/lib/BryntumGridFieldFilterPickerGroup.js.map +1 -1
  21. package/lib/BryntumGroupBar.d.ts +2 -2
  22. package/lib/BryntumGroupBar.js +1 -1
  23. package/lib/BryntumGroupBar.js.map +1 -1
  24. package/lib/BryntumTreeCombo.d.ts +1 -1
  25. package/lib/BryntumTreeCombo.js +1 -1
  26. package/lib/BryntumTreeCombo.js.map +1 -1
  27. package/lib/BryntumTreeGrid.js +1 -0
  28. package/lib/BryntumTreeGrid.js.map +1 -1
  29. package/lib/WrapperHelper.js +27 -8
  30. package/lib/WrapperHelper.js.map +1 -1
  31. package/license.pdf +0 -0
  32. package/package.json +1 -1
  33. package/src/BryntumAIFilterField.tsx +12 -5
  34. package/src/BryntumChecklistFilterCombo.tsx +12 -5
  35. package/src/BryntumGrid.tsx +8 -1
  36. package/src/BryntumGridBase.tsx +8 -1
  37. package/src/BryntumGridChartDesigner.tsx +12 -5
  38. package/src/BryntumGridFieldFilterPicker.tsx +13 -6
  39. package/src/BryntumGridFieldFilterPickerGroup.tsx +13 -6
  40. package/src/BryntumGroupBar.tsx +15 -6
  41. package/src/BryntumTreeCombo.tsx +12 -5
  42. package/src/BryntumTreeGrid.tsx +8 -1
  43. package/src/WrapperHelper.tsx +55 -17
@@ -43,6 +43,8 @@ export type BryntumTreeGridProps = {
43
43
  /**
44
44
  * Element (or the id of an element) to append this widget's element to. Can be configured, or set once at
45
45
  * runtime. To access the element of a rendered widget, see [element](https://bryntum.com/products/grid/docs/api/Core/widget/Widget#property-element).
46
+ * <div class="note">When creating nested trees of widgets, this should only be used on the outermost widget.
47
+ * [More...](https://bryntum.com/products/grid/docs/api/Grid/view/TreeGrid#config-appendTo)
46
48
  */
47
49
  appendTo? : HTMLElement|string
48
50
  /**
@@ -354,10 +356,14 @@ export type BryntumTreeGridProps = {
354
356
  inputFieldAlign? : 'start'|'end'
355
357
  /**
356
358
  * Element (or element id) to insert this widget before. If provided, [appendTo](https://bryntum.com/products/grid/docs/api/Core/widget/Widget#config-appendTo) config is ignored.
359
+ * <div class="note">When creating nested trees of widgets, this should only be used on the outermost widget.
360
+ * [More...](https://bryntum.com/products/grid/docs/api/Grid/view/TreeGrid#config-insertBefore)
357
361
  */
358
362
  insertBefore? : HTMLElement|string
359
363
  /**
360
364
  * Element (or element id) to append this widget element to, as a first child. If provided, [appendTo](https://bryntum.com/products/grid/docs/api/Core/widget/Widget#config-appendTo) config is ignored.
365
+ * <div class="note">When creating nested trees of widgets, this should only be used on the outermost widget.
366
+ * [More...](https://bryntum.com/products/grid/docs/api/Grid/view/TreeGrid#config-insertFirst)
361
367
  */
362
368
  insertFirst? : HTMLElement|string
363
369
  /**
@@ -370,7 +376,7 @@ export type BryntumTreeGridProps = {
370
376
  */
371
377
  labelPosition? : 'before'|'above'|'align-before'|'auto'|null
372
378
  /**
373
- * Sets `labelWidth´ for all children of this Container, that does not define their own `labelWidth`.
379
+ * Sets `labelWidth` for all children of this Container, that do not define their own `labelWidth`.
374
380
  * [More...](https://bryntum.com/products/grid/docs/api/Grid/view/TreeGrid#config-labelWidth)
375
381
  */
376
382
  labelWidth? : number|null
@@ -2295,6 +2301,7 @@ export class BryntumTreeGrid extends React.Component<BryntumTreeGridProps> {
2295
2301
  ];
2296
2302
 
2297
2303
  static propertyNames = [
2304
+ 'centered',
2298
2305
  'originalStore',
2299
2306
  'parent',
2300
2307
  'selectedCell',
@@ -50,6 +50,7 @@ type ReactComponentState = {
50
50
  type HTMLElementWithData = HTMLElement & {
51
51
  elementData?: any
52
52
  lastPortalId?: string | null
53
+ jsxContainer?: HTMLElement | null
53
54
  didSetTextContent?: boolean
54
55
  };
55
56
 
@@ -515,9 +516,11 @@ function processCellContent(this: { reactComponent: any; isExporting: boolean; $
515
516
  else {
516
517
  // Create new portal container
517
518
  const portalContainer = DomHelper.append(renderElement, {
518
- tag : 'div',
519
- className : portalContainerClass,
520
- dataset : { portalId } // for reference in tests
519
+ tag : 'div',
520
+ className : portalContainerClass,
521
+ dataset : { portalId }, // for reference in tests
522
+ // We don't want portal container to be reused in the DomConfig flip for this cell
523
+ retainElement : true
521
524
  });
522
525
  renderElement.portalContainer = portalContainer;
523
526
 
@@ -542,9 +545,27 @@ function processCellContent(this: { reactComponent: any; isExporting: boolean; $
542
545
  cellElementData.hasPortal = true;
543
546
  portal.generation = record.generation;
544
547
  }
545
- else if (!rendererHtml && cellElementData.hasPortal) {
546
- cellElement.portalContainer.remove();
547
- cellElementData.hasPortal = false;
548
+ else if (cellElementData.hasPortal) {
549
+ // The previous JSX cell content can be replaced by DomConfig object so in that case,
550
+ // we want to delete the previously created portal for JSX. See:
551
+ // https://github.com/bryntum/support/issues/7862
552
+ const
553
+ container = renderElement.portalContainer || renderElement.querySelector(`.${portalContainerClass}`),
554
+ ownedPortalId = container?.dataset.portalId,
555
+ portal = ownedPortalId && state.portals.get(ownedPortalId);
556
+
557
+ if (portal && portal.containerInfo === container) {
558
+ deletePortal(component, ownedPortalId);
559
+ flushSync(() => updateGeneration(component, true));
560
+ }
561
+ else {
562
+ // No live portal owns this container. Since retainElement is true,
563
+ // we have to remove it manually
564
+ container?.remove();
565
+ }
566
+
567
+ renderElement.portalContainer = null;
568
+ cellElementData.hasPortal = false;
548
569
  }
549
570
  }
550
571
 
@@ -1173,7 +1194,7 @@ function processEventContent(this: any, {
1173
1194
  */
1174
1195
  function processResourceHeader(
1175
1196
  { jsx, targetElement }:
1176
- { jsx: ReactElement; targetElement: HTMLElement }): void {
1197
+ { jsx: ReactElement; targetElement: HTMLElementWithData }): void {
1177
1198
 
1178
1199
  if (!jsx) {
1179
1200
  return;
@@ -1186,19 +1207,36 @@ function processResourceHeader(
1186
1207
  { portals } = state,
1187
1208
  portalId = `resource-header-${targetElement.dataset.resourceId}`;
1188
1209
 
1189
- // Delete portal if we already have one
1190
- if (portals.has(portalId)) {
1191
- portals.delete(portalId);
1192
-
1193
- // Update the generation (force React re-rendering) in this tick
1194
- updateGeneration(reactComponent, true);
1210
+ // Render the JSX into a retained container instead of straight into the header cell. DomSync owns the
1211
+ // header cell and, on every re-sync (e.g. when resizing the resource columns), it releases any DOM children
1212
+ // it did not create itself - adding the `b-released` class which hides the React-rendered content. A
1213
+ // `b-jsx-container` flagged with `retainElement` is left untouched by DomSync. The container is given
1214
+ // `display: contents` so it stays transparent to the header cell's flex layout.
1215
+ // The container is cached on the cell rather than queried from the DOM each pass.
1216
+ let jsxContainer = targetElement.jsxContainer;
1217
+
1218
+ if (!jsxContainer) {
1219
+ // Clear any plain content DomSync may have placed in the cell before hosting the portal
1220
+ targetElement.textContent = '';
1221
+ targetElement.jsxContainer = jsxContainer = DomHelper.createElement({
1222
+ className : 'b-jsx-container',
1223
+ parent : targetElement,
1224
+ retainElement : true,
1225
+ style : { display : 'contents' }
1226
+ }) as HTMLElement;
1227
+ }
1228
+ // When a header cell is reused for a different resource, drop the now stale portal
1229
+ else if (targetElement.lastPortalId && targetElement.lastPortalId !== portalId) {
1230
+ portals.delete(targetElement.lastPortalId);
1195
1231
  }
1196
1232
 
1197
- portals.set(portalId, ReactDOM.createPortal(jsx, targetElement));
1198
-
1199
- // Trigger the React portals re-rendering in the next animation frame
1200
- updateGeneration(reactComponent);
1233
+ // (Re)create the portal so resource record changes are reflected. Setting the same
1234
+ // id replaces any existing portal, so no explicit delete is needed beforehand.
1235
+ portals.set(portalId, ReactDOM.createPortal(jsx, jsxContainer));
1236
+ targetElement.lastPortalId = portalId;
1201
1237
 
1238
+ // Force React to re-render the portals in this tick
1239
+ updateGeneration(reactComponent, true);
1202
1240
  }
1203
1241
 
1204
1242
  /**