@toolbox-web/grid 1.12.0 → 1.13.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.
Files changed (75) hide show
  1. package/all.js +694 -525
  2. package/all.js.map +1 -1
  3. package/index.js +1468 -1449
  4. package/index.js.map +1 -1
  5. package/lib/core/grid.d.ts +2 -1
  6. package/lib/core/grid.d.ts.map +1 -1
  7. package/lib/core/internal/sanitize.d.ts.map +1 -1
  8. package/lib/core/internal/validate-config.d.ts.map +1 -1
  9. package/lib/core/types.d.ts +9 -1
  10. package/lib/core/types.d.ts.map +1 -1
  11. package/lib/plugins/clipboard/index.js.map +1 -1
  12. package/lib/plugins/column-virtualization/index.js.map +1 -1
  13. package/lib/plugins/context-menu/ContextMenuPlugin.d.ts.map +1 -1
  14. package/lib/plugins/context-menu/index.js +1 -1
  15. package/lib/plugins/context-menu/index.js.map +1 -1
  16. package/lib/plugins/editing/EditingPlugin.d.ts.map +1 -1
  17. package/lib/plugins/editing/editors.d.ts.map +1 -1
  18. package/lib/plugins/editing/index.d.ts +1 -1
  19. package/lib/plugins/editing/index.d.ts.map +1 -1
  20. package/lib/plugins/editing/index.js +187 -170
  21. package/lib/plugins/editing/index.js.map +1 -1
  22. package/lib/plugins/editing/types.d.ts +44 -0
  23. package/lib/plugins/editing/types.d.ts.map +1 -1
  24. package/lib/plugins/export/index.js.map +1 -1
  25. package/lib/plugins/filtering/index.js +9 -9
  26. package/lib/plugins/filtering/index.js.map +1 -1
  27. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts +8 -1
  28. package/lib/plugins/grouping-columns/GroupingColumnsPlugin.d.ts.map +1 -1
  29. package/lib/plugins/grouping-columns/index.js +59 -60
  30. package/lib/plugins/grouping-columns/index.js.map +1 -1
  31. package/lib/plugins/grouping-rows/index.js.map +1 -1
  32. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts +7 -0
  33. package/lib/plugins/master-detail/MasterDetailPlugin.d.ts.map +1 -1
  34. package/lib/plugins/master-detail/index.js +185 -145
  35. package/lib/plugins/master-detail/index.js.map +1 -1
  36. package/lib/plugins/multi-sort/index.js.map +1 -1
  37. package/lib/plugins/pinned-columns/index.js.map +1 -1
  38. package/lib/plugins/pinned-rows/index.js.map +1 -1
  39. package/lib/plugins/pivot/index.js.map +1 -1
  40. package/lib/plugins/print/index.js.map +1 -1
  41. package/lib/plugins/reorder/index.js.map +1 -1
  42. package/lib/plugins/responsive/index.js +40 -39
  43. package/lib/plugins/responsive/index.js.map +1 -1
  44. package/lib/plugins/row-reorder/index.js.map +1 -1
  45. package/lib/plugins/selection/SelectionPlugin.d.ts +51 -0
  46. package/lib/plugins/selection/SelectionPlugin.d.ts.map +1 -1
  47. package/lib/plugins/selection/index.js +325 -131
  48. package/lib/plugins/selection/index.js.map +1 -1
  49. package/lib/plugins/selection/types.d.ts +18 -0
  50. package/lib/plugins/selection/types.d.ts.map +1 -1
  51. package/lib/plugins/server-side/index.js.map +1 -1
  52. package/lib/plugins/tree/index.js.map +1 -1
  53. package/lib/plugins/undo-redo/index.js.map +1 -1
  54. package/lib/plugins/visibility/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/public.d.ts +2 -0
  57. package/public.d.ts.map +1 -1
  58. package/themes/dg-theme-bootstrap.css +192 -8
  59. package/themes/dg-theme-material.css +243 -0
  60. package/umd/grid.all.umd.js +43 -43
  61. package/umd/grid.all.umd.js.map +1 -1
  62. package/umd/grid.umd.js +19 -19
  63. package/umd/grid.umd.js.map +1 -1
  64. package/umd/plugins/context-menu.umd.js +1 -1
  65. package/umd/plugins/context-menu.umd.js.map +1 -1
  66. package/umd/plugins/editing.umd.js +1 -1
  67. package/umd/plugins/editing.umd.js.map +1 -1
  68. package/umd/plugins/filtering.umd.js +1 -1
  69. package/umd/plugins/filtering.umd.js.map +1 -1
  70. package/umd/plugins/grouping-columns.umd.js +1 -1
  71. package/umd/plugins/grouping-columns.umd.js.map +1 -1
  72. package/umd/plugins/master-detail.umd.js +1 -1
  73. package/umd/plugins/master-detail.umd.js.map +1 -1
  74. package/umd/plugins/selection.umd.js +2 -2
  75. package/umd/plugins/selection.umd.js.map +1 -1
@@ -1,4 +1,4 @@
1
- import { PluginManifest, BaseGridPlugin } from '../../core/plugin/base-plugin';
1
+ import { AfterCellRenderContext, PluginManifest, BaseGridPlugin } from '../../core/plugin/base-plugin';
2
2
  import { ColumnConfig } from '../../core/types';
3
3
  import { ColumnGroup, GroupingColumnsConfig } from './types';
4
4
  /**
@@ -106,6 +106,13 @@ export declare class GroupingColumnsPlugin extends BaseGridPlugin<GroupingColumn
106
106
  processColumns(columns: readonly ColumnConfig[]): ColumnConfig[];
107
107
  /** @internal */
108
108
  afterRender(): void;
109
+ /**
110
+ * Apply group-end class to individual cells during render and scroll.
111
+ * This is more efficient than querySelectorAll in afterRender and ensures
112
+ * cells recycled during scroll also get the class applied.
113
+ * @internal
114
+ */
115
+ afterCellRender(context: AfterCellRenderContext): void;
109
116
  /**
110
117
  * Check if column groups are active.
111
118
  * @returns Whether grouping is active
@@ -1 +1 @@
1
- {"version":3,"file":"GroupingColumnsPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/grouping-columns/GroupingColumnsPlugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,qBAAqB,CAAC;;IAC9E;;;OAGG;IACH,gBAAyB,QAAQ,EAAE,cAAc,CAc/C;IAEF,gBAAgB;IAChB,QAAQ,CAAC,IAAI,qBAAqB;IAClC,gBAAgB;IAChB,SAAkB,MAAM,SAAU;IAElC,gBAAgB;IAChB,cAAuB,aAAa,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAIrE;IAGD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAS;IAKzB,gBAAgB;IACP,MAAM,IAAI,IAAI;IAQvB;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAczD,gBAAgB;IACP,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE;IA0CzE,gBAAgB;IACP,WAAW,IAAI,IAAI;IAkF5B;;;OAGG;IACH,gBAAgB,IAAI,OAAO;IAI3B;;;OAGG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE;IAKhD;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}
1
+ {"version":3,"file":"GroupingColumnsPlugin.d.ts","sourceRoot":"","sources":["../../../../../../libs/grid/src/lib/plugins/grouping-columns/GroupingColumnsPlugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,qBAAa,qBAAsB,SAAQ,cAAc,CAAC,qBAAqB,CAAC;;IAC9E;;;OAGG;IACH,gBAAyB,QAAQ,EAAE,cAAc,CAc/C;IAEF,gBAAgB;IAChB,QAAQ,CAAC,IAAI,qBAAqB;IAClC,gBAAgB;IAChB,SAAkB,MAAM,SAAU;IAElC,gBAAgB;IAChB,cAAuB,aAAa,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAIrE;IAGD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAS;IAOzB,gBAAgB;IACP,MAAM,IAAI,IAAI;IASvB;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO;IAczD,gBAAgB;IACP,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE;IAmDzE,gBAAgB;IACP,WAAW,IAAI,IAAI;IA6C5B;;;;;OAKG;IACM,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI;IAQ/D;;;OAGG;IACH,gBAAgB,IAAI,OAAO;IAI3B;;;OAGG;IACH,SAAS,IAAI,WAAW,EAAE;IAI1B;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE;IAKhD;;OAEG;IACH,OAAO,IAAI,IAAI;CAIhB"}
@@ -1,4 +1,4 @@
1
- const c = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', p = {
1
+ const c = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/></svg>', h = {
2
2
  expand: "▶",
3
3
  collapse: "▼",
4
4
  sortAsc: "▲",
@@ -11,7 +11,7 @@ const c = '<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentCo
11
11
  filterActive: c,
12
12
  print: "🖨️"
13
13
  };
14
- class h {
14
+ class p {
15
15
  /**
16
16
  * Plugin dependencies - declare other plugins this one requires.
17
17
  *
@@ -301,7 +301,7 @@ class h {
301
301
  */
302
302
  get gridIcons() {
303
303
  const e = this.grid?.gridConfig?.icons ?? {};
304
- return { ...p, ...e };
304
+ return { ...h, ...e };
305
305
  }
306
306
  // #region Animation Helpers
307
307
  /**
@@ -379,38 +379,38 @@ class h {
379
379
  }
380
380
  function g(u) {
381
381
  if (!u.length) return [];
382
- const e = /* @__PURE__ */ new Map(), r = [], t = (o, l) => {
383
- if (!l.length) return;
384
- const s = r[r.length - 1];
385
- if (s && s.implicit && s.firstIndex + s.columns.length === o) {
386
- s.columns.push(...l);
382
+ const e = /* @__PURE__ */ new Map(), r = [], t = (o, s) => {
383
+ if (!s.length) return;
384
+ const i = r[r.length - 1];
385
+ if (i && i.implicit && i.firstIndex + i.columns.length === o) {
386
+ i.columns.push(...s);
387
387
  return;
388
388
  }
389
389
  r.push({
390
390
  id: "__implicit__" + o,
391
391
  label: void 0,
392
- columns: l,
392
+ columns: s,
393
393
  firstIndex: o,
394
394
  implicit: !0
395
395
  });
396
396
  };
397
- let i = [], n = 0;
398
- return u.forEach((o, l) => {
399
- const s = o.group;
400
- if (!s) {
401
- i.length === 0 && (n = l), i.push(o);
397
+ let l = [], n = 0;
398
+ return u.forEach((o, s) => {
399
+ const i = o.group;
400
+ if (!i) {
401
+ l.length === 0 && (n = s), l.push(o);
402
402
  return;
403
403
  }
404
- i.length && (t(n, i.slice()), i = []);
405
- const d = typeof s == "string" ? s : s.id;
404
+ l.length && (t(n, l.slice()), l = []);
405
+ const d = typeof i == "string" ? i : i.id;
406
406
  let a = e.get(d);
407
407
  a || (a = {
408
408
  id: d,
409
- label: typeof s == "string" ? void 0 : s.label,
409
+ label: typeof i == "string" ? void 0 : i.label,
410
410
  columns: [],
411
- firstIndex: l
411
+ firstIndex: s
412
412
  }, e.set(d, a), r.push(a)), a.columns.push(o);
413
- }), i.length && t(n, i), r.length === 1 && r[0].implicit && r[0].columns.length === u.length ? [] : r;
413
+ }), l.length && t(n, l), r.length === 1 && r[0].implicit && r[0].columns.length === u.length ? [] : r;
414
414
  }
415
415
  function f(u, e, r) {
416
416
  if (!e.length || !u) return;
@@ -418,14 +418,14 @@ function f(u, e, r) {
418
418
  for (const n of e)
419
419
  for (const o of n.columns)
420
420
  o.field && t.set(o.field, n.id);
421
- const i = Array.from(u.querySelectorAll(".cell[data-field]"));
422
- i.forEach((n) => {
423
- const o = n.getAttribute("data-field") || "", l = t.get(o);
424
- l && (n.classList.add("grouped"), n.getAttribute("data-group") || n.setAttribute("data-group", l));
421
+ const l = Array.from(u.querySelectorAll(".cell[data-field]"));
422
+ l.forEach((n) => {
423
+ const o = n.getAttribute("data-field") || "", s = t.get(o);
424
+ s && (n.classList.add("grouped"), n.getAttribute("data-group") || n.setAttribute("data-group", s));
425
425
  });
426
426
  for (const n of e) {
427
- const o = n.columns[n.columns.length - 1], l = i.find((s) => s.getAttribute("data-field") === o.field);
428
- l && l.classList.add("group-end");
427
+ const o = n.columns[n.columns.length - 1], s = l.find((i) => i.getAttribute("data-field") === o.field);
428
+ s && s.classList.add("group-end");
429
429
  }
430
430
  }
431
431
  function m(u, e) {
@@ -433,10 +433,10 @@ function m(u, e) {
433
433
  const r = document.createElement("div");
434
434
  r.className = "header-group-row", r.setAttribute("role", "row");
435
435
  for (const t of u) {
436
- const i = t.columns[0], n = i ? e.findIndex((d) => d.field === i.field) : -1;
436
+ const l = t.columns[0], n = l ? e.findIndex((d) => d.field === l.field) : -1;
437
437
  if (n === -1) continue;
438
- const o = String(t.id).startsWith("__implicit__"), l = o ? "" : t.label || t.id, s = document.createElement("div");
439
- s.className = "cell header-group-cell", o && s.classList.add("implicit-group"), s.setAttribute("data-group", String(t.id)), s.style.gridColumn = `${n + 1} / span ${t.columns.length}`, s.textContent = l, r.appendChild(s);
438
+ const o = String(t.id).startsWith("__implicit__"), s = o ? "" : t.label || t.id, i = document.createElement("div");
439
+ i.className = "cell header-group-cell", o && i.classList.add("implicit-group"), i.setAttribute("data-group", String(t.id)), i.style.gridColumn = `${n + 1} / span ${t.columns.length}`, i.textContent = s, r.appendChild(i);
440
440
  }
441
441
  return r;
442
442
  }
@@ -444,7 +444,7 @@ function b(u) {
444
444
  return u.some((e) => e.group != null);
445
445
  }
446
446
  const w = "@layer tbw-plugins{.header-group-row{display:grid;grid-auto-flow:column;background:var(--tbw-grouping-columns-header-bg, var(--tbw-color-header-bg));border-bottom:1px solid var(--tbw-grouping-columns-border, var(--tbw-color-border))}.header-group-cell{display:flex;align-items:center;justify-content:center;padding:var(--tbw-button-padding-sm, .25rem .5rem);font-weight:600;font-size:var(--tbw-font-size-sm, .9em);text-transform:uppercase;letter-spacing:.5px;border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-group-cell:last-child{border-right:none}.header-row .cell.grouped{border-top:none}.header-row .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.header-row .cell.group-end:last-child{border-right:none}.rows .cell.group-end{border-right:2px solid var(--tbw-grouping-columns-separator, var(--tbw-color-border-strong, var(--tbw-color-border)))}.rows .cell.group-end:last-child{border-right:none}.header-group-row.no-borders{border-bottom:none}.header-group-row.no-borders .header-group-cell{border-right:none}.header-row.no-group-borders .cell.group-end{border-right:1px solid var(--tbw-color-border)}}";
447
- class v extends h {
447
+ class v extends p {
448
448
  /**
449
449
  * Plugin manifest - declares owned properties for configuration validation.
450
450
  * @internal
@@ -477,11 +477,13 @@ class v extends h {
477
477
  // #region Internal State
478
478
  groups = [];
479
479
  isActive = !1;
480
+ /** Fields that are the last column in a group (for group-end border class). */
481
+ #e = /* @__PURE__ */ new Set();
480
482
  // #endregion
481
483
  // #region Lifecycle
482
484
  /** @internal */
483
485
  detach() {
484
- this.groups = [], this.isActive = !1;
486
+ this.groups = [], this.isActive = !1, this.#e.clear();
485
487
  }
486
488
  // #endregion
487
489
  // #region Static Detection
@@ -504,57 +506,54 @@ class v extends h {
504
506
  if (r && Array.isArray(r) && r.length > 0) {
505
507
  const n = /* @__PURE__ */ new Map();
506
508
  for (const o of r)
507
- for (const l of o.children)
508
- n.set(l, { id: o.id, label: o.header });
509
+ for (const s of o.children)
510
+ n.set(s, { id: o.id, label: o.header });
509
511
  t = e.map((o) => {
510
- const l = n.get(o.field);
511
- return l && !o.group ? { ...o, group: l } : o;
512
+ const s = n.get(o.field);
513
+ return s && !o.group ? { ...o, group: s } : o;
512
514
  });
513
515
  } else
514
516
  t = [...e];
515
- const i = g(t);
516
- return i.length === 0 ? (this.isActive = !1, this.groups = [], t) : (this.isActive = !0, this.groups = i, t);
517
+ const l = g(t);
518
+ if (l.length === 0)
519
+ return this.isActive = !1, this.groups = [], t;
520
+ this.isActive = !0, this.groups = l, this.#e.clear();
521
+ for (const n of l) {
522
+ const o = n.columns[n.columns.length - 1];
523
+ o?.field && this.#e.add(o.field);
524
+ }
525
+ return t;
517
526
  }
518
527
  /** @internal */
519
528
  afterRender() {
520
529
  if (!this.isActive) {
521
- const s = this.gridElement?.querySelector(".header")?.querySelector(".header-group-row");
522
- s && s.remove();
530
+ const i = this.gridElement?.querySelector(".header")?.querySelector(".header-group-row");
531
+ i && i.remove();
523
532
  return;
524
533
  }
525
534
  const e = this.gridElement?.querySelector(".header");
526
535
  if (!e) return;
527
536
  const r = e.querySelector(".header-group-row");
528
537
  r && r.remove();
529
- const t = this.columns, i = g(t);
530
- if (i.length === 0) return;
531
- const n = m(i, t);
538
+ const t = this.columns, l = g(t);
539
+ if (l.length === 0) return;
540
+ const n = m(l, t);
532
541
  if (n) {
533
542
  n.classList.toggle("no-borders", !this.config.showGroupBorders);
534
- const l = e.querySelector(".header-row");
535
- l ? e.insertBefore(n, l) : e.appendChild(n);
543
+ const s = e.querySelector(".header-row");
544
+ s ? e.insertBefore(n, s) : e.appendChild(n);
536
545
  }
537
546
  const o = e.querySelector(".header-row");
538
- o && (o.classList.toggle("no-group-borders", !this.config.showGroupBorders), f(o, i)), this.#e(i);
547
+ o && (o.classList.toggle("no-group-borders", !this.config.showGroupBorders), f(o, l));
539
548
  }
540
549
  /**
541
- * Apply group-end class to all data cells in the last column of each group.
542
- * This extends the strong border separator through all data rows.
550
+ * Apply group-end class to individual cells during render and scroll.
551
+ * This is more efficient than querySelectorAll in afterRender and ensures
552
+ * cells recycled during scroll also get the class applied.
553
+ * @internal
543
554
  */
544
- #e(e) {
545
- if (!this.config.showGroupBorders) return;
546
- const r = this.gridElement;
547
- if (!r) return;
548
- const t = /* @__PURE__ */ new Set();
549
- for (const n of e) {
550
- const o = n.columns[n.columns.length - 1];
551
- o?.field && t.add(o.field);
552
- }
553
- const i = r.querySelectorAll(".rows .cell[data-field]");
554
- for (const n of i) {
555
- const o = n.getAttribute("data-field");
556
- o && t.has(o) ? n.classList.add("group-end") : n.classList.remove("group-end");
557
- }
555
+ afterCellRender(e) {
556
+ !this.isActive || !this.config.showGroupBorders || e.cellElement.classList.toggle("group-end", this.#e.has(e.column.field));
558
557
  }
559
558
  // #endregion
560
559
  // #region Public API