@guiexpert/preact-table 10.1.98 → 10.1.100

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.
@@ -1,5 +1,5 @@
1
1
  import { Component } from 'preact';
2
- import { FocusModelIf, GeModelChangeEvent, GeBatchEditEvent, GeDetailEvent, GeMouseEvent, GeRowDragEvent, GeScrollEvent, GeStateChangeEvent, SelectionModelIf, TableApi, TableModelIf, TableOptions } from '@guiexpert/table';
2
+ import { FocusModelIf, GeModelChangeEvent, GeBatchEditEvent, GeDetailEvent, GeEditEvent, GeUndoEvent, GeMouseEvent, GeRowDragEvent, GeScrollEvent, GeStateChangeEvent, SelectionModelIf, TableApi, TableModelIf, TableOptions } from '@guiexpert/table';
3
3
 
4
4
  export type GeMouseEventFn = (evt: GeMouseEvent) => void;
5
5
  export type GeCheckboxEventFn = (evt: any[]) => void;
@@ -12,6 +12,8 @@ export type GeStateChangeEventFn = (evt: GeStateChangeEvent) => void;
12
12
  export type GeRowDragEventFn = (evt: GeRowDragEvent) => void;
13
13
  export type GeBatchEditEventFn = (evt: GeBatchEditEvent) => void;
14
14
  export type GeDetailEventFn = (evt: GeDetailEvent) => void;
15
+ export type GeEditEventFn = (evt: GeEditEvent) => void;
16
+ export type GeUndoEventFn = (evt: GeUndoEvent) => void;
15
17
  export interface GuiexpertTableProps {
16
18
  tableModel: TableModelIf;
17
19
  tableOptions?: TableOptions;
@@ -41,6 +43,10 @@ export interface GuiexpertTableProps {
41
43
  batchEditChanged?: GeBatchEditEventFn;
42
44
  /** Master/detail: a detail row was expanded or collapsed (since 1.1.97). */
43
45
  detailExpandedChanged?: GeDetailEventFn;
46
+ /** The cell editor opened, its text changed, it committed or it was cancelled (since 1.1.99). */
47
+ editingChanged?: GeEditEventFn;
48
+ /** The undo history changed (since 1.1.99). */
49
+ undoStackChanged?: GeUndoEventFn;
44
50
  /**
45
51
  * `true` shows the loading overlay ("Loading…" with a CSS spinner) over the body, `false` hides it.
46
52
  * Changing it does **not** re-create the table. Texts: `tableOptions.overlayOptions`. @since 1.1.92
package/README.md CHANGED
@@ -37,6 +37,25 @@ This is the UI-agnostic table component for your next web app. 😊
37
37
  - Full control over the HTML structure and style
38
38
 
39
39
 
40
+ ### New in October 2026 (1.1.91 – 1.1.99) – all MIT-licensed
41
+
42
+ - Screen readers and keyboard: WAI-ARIA grid, announcements, full keyboard navigation (1.1.91)
43
+ - “Loading…” and “No rows” overlays with a CSS spinner, `loading` prop (1.1.92)
44
+ - Save and restore the state: column layout, sorting, scroll position, selection – localStorage or your server (1.1.92)
45
+ - Row numbers like in a spreadsheet: `rowNumbersVisible: true` (1.1.93)
46
+ - Total rows that follow the filter, sums of the selection: `footerAggregates` (1.1.94)
47
+ - Row grouping with subtotals: `RowGroupFactory` (1.1.94)
48
+ - Pivot tables: `PivotFactory` (1.1.94)
49
+ - Calculated columns, “Show values as” and formulas without `eval`: `valueGetter`, `showValuesAs`, `formula` (1.1.95)
50
+ - Drag rows into order – mouse, touch, keyboard: `rowDrag: true` (1.1.95)
51
+ - Fill handle and batch edit: `fillHandle`, `batchEdit` (1.1.96)
52
+ - Master/detail with nested tables or components: `masterDetail` (1.1.97)
53
+ - Right-to-left for Arabic, Hebrew, Persian: `direction: "rtl"` (1.1.98)
54
+ - A spreadsheet: A1 cell formulas, copy & paste with Excel, undo/redo, formula bar – `SpreadsheetFactory`, or `spreadsheet: true` for your table (1.1.99)
55
+
56
+ All of them with code and live demos: [gui.expert/whats-new](https://gui.expert/whats-new/) ·
57
+ training: [gui.expert/training](https://gui.expert/training/)
58
+
40
59
  ## Links
41
60
 
42
61
  - [Demos](https://gui.expert/demos)
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var b=(s,a,o)=>a in s?u(s,a,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[a]=o;var h=(s,a,o)=>b(s,typeof a!="symbol"?a+"":a,o);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("preact/jsx-runtime"),l=require("preact"),c=require("@guiexpert/table");class m extends l.Component{constructor(o){super(o);h(this,"ref",l.createRef());h(this,"tableScope");h(this,"shownByProp",!1)}componentDidMount(){const o=this.ref.current;o&&this.initTable(o,this.props)}componentDidUpdate(o){const i=this.ref.current;i&&(o.tableModel!==this.props.tableModel||o.tableOptions!==this.props.tableOptions)&&this.initTable(i,this.props),!!o.loading!=!!this.props.loading&&this.applyLoading(),this.props.licenseKey&&this.props.licenseKey!==o.licenseKey&&c.LicenseManager.getInstance().setLicenseKey(this.props.licenseKey)}componentWillUnmount(){this.destroyTable()}initTable(o,i){var g;this.destroyTable();const r=()=>this.props,p={onSelectionChanged:t=>{var e,n;return(n=(e=r()).selectionChanged)==null?void 0:n.call(e,t)},onFocusChanged:t=>{var e,n;return(n=(e=r()).focusChanged)==null?void 0:n.call(e,t)},onScroll:t=>{var e,n;return(n=(e=r()).scroll)==null?void 0:n.call(e,t)},onCheckboxChanged:t=>{var e,n;return(n=(e=r()).checkboxChanged)==null?void 0:n.call(e,t)},onContextmenu:t=>{var e,n;return(n=(e=r()).contextmenu)==null?void 0:n.call(e,t)},onModelChanged:t=>{var e,n;return(n=(e=r()).modelChanged)==null?void 0:n.call(e,t)},onMouseClicked:t=>{var e,n;return(n=(e=r()).mouseClicked)==null?void 0:n.call(e,t)},onMouseDragging:t=>{var e,n;return(n=(e=r()).mouseDragging)==null?void 0:n.call(e,t)},onMouseDraggingEnd:t=>{var e,n;return(n=(e=r()).mouseDraggingEnd)==null?void 0:n.call(e,t)},onMouseMoved:t=>{var e,n;return(n=(e=r()).mouseMoved)==null?void 0:n.call(e,t)},onStateChanged:t=>{var e,n;return(n=(e=r()).stateChanged)==null?void 0:n.call(e,t)},onRowDragStart:t=>{var e,n;return(n=(e=r()).rowDragStart)==null?void 0:n.call(e,t)},onRowDragMove:t=>{var e,n;return(n=(e=r()).rowDragMove)==null?void 0:n.call(e,t)},onRowDragEnd:t=>{var e,n;return(n=(e=r()).rowDragEnd)==null?void 0:n.call(e,t)},onBatchEditChanged:t=>{var e,n;return(n=(e=r()).batchEditChanged)==null?void 0:n.call(e,t)},onDetailExpandedChanged:t=>{var e,n;return(n=(e=r()).detailExpandedChanged)==null?void 0:n.call(e,t)}},d=new c.TableScope(o,i.tableModel,new c.SimpleDomService,i.tableOptions??new c.TableOptions,p);this.tableScope=d,d.firstInit(),this.shownByProp=!1,this.applyLoading(),(g=i.tableReady)==null||g.call(i,d.getApi()),i.licenseKey&&c.LicenseManager.getInstance().setLicenseKey(i.licenseKey)}applyLoading(){var o,i;this.props.loading?((o=this.tableScope)==null||o.showLoadingOverlay(),this.shownByProp=!0):this.shownByProp&&((i=this.tableScope)==null||i.hideOverlay(),this.shownByProp=!1)}destroyTable(){var o;(o=this.tableScope)==null||o.destroy(),this.tableScope=void 0}render(){return C.jsx("div",{ref:this.ref,className:"container-div",style:{width:"100%",height:"100%",backgroundColor:"transparent",padding:"0",margin:"0"}})}}class y{constructor(a){this.Component=a}render(a,o,i,r,p,d,g){const t={cellDiv:a,rowIndex:o,columnIndex:i,areaIdent:r,areaModel:p,cellValue:d};return l.render(l.h(this.Component,t),a),()=>{l.render(null,a)}}}class f{constructor(a){this.Component=a}render(a,o,i){const r={row:o,rowIndex:i.rowIndex,tableApi:i.tableApi,context:i};return l.render(l.h(this.Component,r),a),()=>l.render(null,a)}}exports.ComponentRendererWrapper=y;exports.DetailComponentRendererWrapper=f;exports.GuiexpertTable=m;
1
+ "use strict";var u=Object.defineProperty;var C=(s,i,o)=>i in s?u(s,i,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[i]=o;var c=(s,i,o)=>C(s,typeof i!="symbol"?i+"":i,o);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("preact/jsx-runtime"),d=require("preact"),h=require("@guiexpert/table");class m extends d.Component{constructor(o){super(o);c(this,"ref",d.createRef());c(this,"tableScope");c(this,"shownByProp",!1)}componentDidMount(){const o=this.ref.current;o&&this.initTable(o,this.props)}componentDidUpdate(o){const r=this.ref.current;r&&(o.tableModel!==this.props.tableModel||o.tableOptions!==this.props.tableOptions)&&this.initTable(r,this.props),!!o.loading!=!!this.props.loading&&this.applyLoading(),this.props.licenseKey&&this.props.licenseKey!==o.licenseKey&&h.LicenseManager.getInstance().setLicenseKey(this.props.licenseKey)}componentWillUnmount(){this.destroyTable()}initTable(o,r){var g;this.destroyTable();const a=()=>this.props,p={onSelectionChanged:t=>{var e,n;return(n=(e=a()).selectionChanged)==null?void 0:n.call(e,t)},onFocusChanged:t=>{var e,n;return(n=(e=a()).focusChanged)==null?void 0:n.call(e,t)},onScroll:t=>{var e,n;return(n=(e=a()).scroll)==null?void 0:n.call(e,t)},onCheckboxChanged:t=>{var e,n;return(n=(e=a()).checkboxChanged)==null?void 0:n.call(e,t)},onContextmenu:t=>{var e,n;return(n=(e=a()).contextmenu)==null?void 0:n.call(e,t)},onModelChanged:t=>{var e,n;return(n=(e=a()).modelChanged)==null?void 0:n.call(e,t)},onMouseClicked:t=>{var e,n;return(n=(e=a()).mouseClicked)==null?void 0:n.call(e,t)},onMouseDragging:t=>{var e,n;return(n=(e=a()).mouseDragging)==null?void 0:n.call(e,t)},onMouseDraggingEnd:t=>{var e,n;return(n=(e=a()).mouseDraggingEnd)==null?void 0:n.call(e,t)},onMouseMoved:t=>{var e,n;return(n=(e=a()).mouseMoved)==null?void 0:n.call(e,t)},onStateChanged:t=>{var e,n;return(n=(e=a()).stateChanged)==null?void 0:n.call(e,t)},onRowDragStart:t=>{var e,n;return(n=(e=a()).rowDragStart)==null?void 0:n.call(e,t)},onRowDragMove:t=>{var e,n;return(n=(e=a()).rowDragMove)==null?void 0:n.call(e,t)},onRowDragEnd:t=>{var e,n;return(n=(e=a()).rowDragEnd)==null?void 0:n.call(e,t)},onBatchEditChanged:t=>{var e,n;return(n=(e=a()).batchEditChanged)==null?void 0:n.call(e,t)},onDetailExpandedChanged:t=>{var e,n;return(n=(e=a()).detailExpandedChanged)==null?void 0:n.call(e,t)},onEditingChanged:t=>{var e,n;return(n=(e=a()).editingChanged)==null?void 0:n.call(e,t)},onUndoStackChanged:t=>{var e,n;return(n=(e=a()).undoStackChanged)==null?void 0:n.call(e,t)}},l=new h.TableScope(o,r.tableModel,new h.SimpleDomService,r.tableOptions??new h.TableOptions,p);this.tableScope=l,l.firstInit(),this.shownByProp=!1,this.applyLoading(),(g=r.tableReady)==null||g.call(r,l.getApi()),r.licenseKey&&h.LicenseManager.getInstance().setLicenseKey(r.licenseKey)}applyLoading(){var o,r;this.props.loading?((o=this.tableScope)==null||o.showLoadingOverlay(),this.shownByProp=!0):this.shownByProp&&((r=this.tableScope)==null||r.hideOverlay(),this.shownByProp=!1)}destroyTable(){var o;(o=this.tableScope)==null||o.destroy(),this.tableScope=void 0}render(){return b.jsx("div",{ref:this.ref,className:"container-div",style:{width:"100%",height:"100%",backgroundColor:"transparent",padding:"0",margin:"0"}})}}class y{constructor(i){this.Component=i}render(i,o,r,a,p,l,g){const t={cellDiv:i,rowIndex:o,columnIndex:r,areaIdent:a,areaModel:p,cellValue:l};return d.render(d.h(this.Component,t),i),()=>{d.render(null,i)}}}class S{constructor(i){this.Component=i}render(i,o,r){const a={row:o,rowIndex:r.rowIndex,tableApi:r.tableApi,context:r};return d.render(d.h(this.Component,a),i),()=>d.render(null,i)}}exports.ComponentRendererWrapper=y;exports.DetailComponentRendererWrapper=S;exports.GuiexpertTable=m;
package/index.js CHANGED
@@ -1,24 +1,24 @@
1
- var b = Object.defineProperty;
2
- var C = (r, s, o) => s in r ? b(r, s, { enumerable: !0, configurable: !0, writable: !0, value: o }) : r[s] = o;
3
- var d = (r, s, o) => C(r, typeof s != "symbol" ? s + "" : s, o);
1
+ var m = Object.defineProperty;
2
+ var b = (r, a, o) => a in r ? m(r, a, { enumerable: !0, configurable: !0, writable: !0, value: o }) : r[a] = o;
3
+ var l = (r, a, o) => b(r, typeof a != "symbol" ? a + "" : a, o);
4
4
  import { jsx as u } from "preact/jsx-runtime";
5
- import { Component as y, createRef as f, render as h, h as m } from "preact";
5
+ import { Component as y, createRef as f, render as h, h as C } from "preact";
6
6
  import { LicenseManager as g, TableScope as w, SimpleDomService as S, TableOptions as M } from "@guiexpert/table";
7
7
  class K extends y {
8
8
  constructor(o) {
9
9
  super(o);
10
- d(this, "ref", f());
11
- d(this, "tableScope");
10
+ l(this, "ref", f());
11
+ l(this, "tableScope");
12
12
  /** the overlay was shown by the loading prop: loading={false} hides only that one */
13
- d(this, "shownByProp", !1);
13
+ l(this, "shownByProp", !1);
14
14
  }
15
15
  componentDidMount() {
16
16
  const o = this.ref.current;
17
17
  o && this.initTable(o, this.props);
18
18
  }
19
19
  componentDidUpdate(o) {
20
- const a = this.ref.current;
21
- a && (o.tableModel !== this.props.tableModel || o.tableOptions !== this.props.tableOptions) && this.initTable(a, this.props), !!o.loading != !!this.props.loading && this.applyLoading(), this.props.licenseKey && this.props.licenseKey !== o.licenseKey && g.getInstance().setLicenseKey(this.props.licenseKey);
20
+ const s = this.ref.current;
21
+ s && (o.tableModel !== this.props.tableModel || o.tableOptions !== this.props.tableOptions) && this.initTable(s, this.props), !!o.loading != !!this.props.loading && this.applyLoading(), this.props.licenseKey && this.props.licenseKey !== o.licenseKey && g.getInstance().setLicenseKey(this.props.licenseKey);
22
22
  }
23
23
  componentWillUnmount() {
24
24
  this.destroyTable();
@@ -27,7 +27,7 @@ class K extends y {
27
27
  * Creates the table in `ele` (a table created before is destroyed first) and calls `tableReady`.
28
28
  * The event callbacks are always taken from the current props.
29
29
  */
30
- initTable(o, a) {
30
+ initTable(o, s) {
31
31
  var p;
32
32
  this.destroyTable();
33
33
  const i = () => this.props, c = {
@@ -94,20 +94,28 @@ class K extends y {
94
94
  onDetailExpandedChanged: (t) => {
95
95
  var e, n;
96
96
  return (n = (e = i()).detailExpandedChanged) == null ? void 0 : n.call(e, t);
97
+ },
98
+ onEditingChanged: (t) => {
99
+ var e, n;
100
+ return (n = (e = i()).editingChanged) == null ? void 0 : n.call(e, t);
101
+ },
102
+ onUndoStackChanged: (t) => {
103
+ var e, n;
104
+ return (n = (e = i()).undoStackChanged) == null ? void 0 : n.call(e, t);
97
105
  }
98
- }, l = new w(
106
+ }, d = new w(
99
107
  o,
100
- a.tableModel,
108
+ s.tableModel,
101
109
  new S(),
102
- a.tableOptions ?? new M(),
110
+ s.tableOptions ?? new M(),
103
111
  c
104
112
  );
105
- this.tableScope = l, l.firstInit(), this.shownByProp = !1, this.applyLoading(), (p = a.tableReady) == null || p.call(a, l.getApi()), a.licenseKey && g.getInstance().setLicenseKey(a.licenseKey);
113
+ this.tableScope = d, d.firstInit(), this.shownByProp = !1, this.applyLoading(), (p = s.tableReady) == null || p.call(s, d.getApi()), s.licenseKey && g.getInstance().setLicenseKey(s.licenseKey);
106
114
  }
107
115
  /** Shows or hides the loading overlay according to the `loading` prop. */
108
116
  applyLoading() {
109
- var o, a;
110
- this.props.loading ? ((o = this.tableScope) == null || o.showLoadingOverlay(), this.shownByProp = !0) : this.shownByProp && ((a = this.tableScope) == null || a.hideOverlay(), this.shownByProp = !1);
117
+ var o, s;
118
+ this.props.loading ? ((o = this.tableScope) == null || o.showLoadingOverlay(), this.shownByProp = !0) : this.shownByProp && ((s = this.tableScope) == null || s.hideOverlay(), this.shownByProp = !1);
111
119
  }
112
120
  /** Releases the table (listeners, resize observer, cell renderers). */
113
121
  destroyTable() {
@@ -131,21 +139,21 @@ class K extends y {
131
139
  );
132
140
  }
133
141
  }
134
- class L {
135
- constructor(s) {
136
- this.Component = s;
142
+ class k {
143
+ constructor(a) {
144
+ this.Component = a;
137
145
  }
138
- render(s, o, a, i, c, l, p) {
146
+ render(a, o, s, i, c, d, p) {
139
147
  const t = {
140
- cellDiv: s,
148
+ cellDiv: a,
141
149
  rowIndex: o,
142
- columnIndex: a,
150
+ columnIndex: s,
143
151
  areaIdent: i,
144
152
  areaModel: c,
145
- cellValue: l
153
+ cellValue: d
146
154
  };
147
- return h(m(this.Component, t), s), () => {
148
- h(null, s);
155
+ return h(C(this.Component, t), a), () => {
156
+ h(null, a);
149
157
  };
150
158
  }
151
159
  // private mount(
@@ -168,17 +176,17 @@ class L {
168
176
  // return cleanupFn;
169
177
  // }
170
178
  }
171
- class R {
172
- constructor(s) {
173
- this.Component = s;
179
+ class L {
180
+ constructor(a) {
181
+ this.Component = a;
174
182
  }
175
- render(s, o, a) {
176
- const i = { row: o, rowIndex: a.rowIndex, tableApi: a.tableApi, context: a };
177
- return h(m(this.Component, i), s), () => h(null, s);
183
+ render(a, o, s) {
184
+ const i = { row: o, rowIndex: s.rowIndex, tableApi: s.tableApi, context: s };
185
+ return h(C(this.Component, i), a), () => h(null, a);
178
186
  }
179
187
  }
180
188
  export {
181
- L as ComponentRendererWrapper,
182
- R as DetailComponentRendererWrapper,
189
+ k as ComponentRendererWrapper,
190
+ L as DetailComponentRendererWrapper,
183
191
  K as GuiexpertTable
184
192
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guiexpert/preact-table",
3
- "version": "10.1.98",
3
+ "version": "10.1.100",
4
4
  "license": "MIT",
5
5
  "author": "Dr. Marc Kronberg <info@gui.expert> (https://gui.expert)",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "tslib": "^2.3.0",
34
- "@guiexpert/table": "^1.1.98"
34
+ "@guiexpert/table": "^1.1.100"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "preact": "^10.0.0"