cenitu-table 0.3.0 → 0.4.0-beta.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.
- package/README.md +53 -0
- package/README.tr.md +53 -0
- package/dist/cenitu-table.cjs +1 -1
- package/dist/cenitu-table.js +1 -1
- package/dist/index-BIH30fQ2.js +6571 -0
- package/dist/index-Bidvqh7P.cjs +197 -0
- package/dist/react.cjs +1 -1
- package/dist/react.js +67 -51
- package/dist/types/grid/cellTypes.d.ts +7 -0
- package/dist/types/grid/columnMenu.d.ts +7 -0
- package/dist/types/grid/grid.d.ts +95 -1
- package/dist/types/grid/messages.d.ts +10 -0
- package/dist/types/grid/serverMode.d.ts +66 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/react/index.d.ts +8 -1
- package/package.json +1 -1
- package/dist/index-BHarWDHD.cjs +0 -184
- package/dist/index-BpjIy-X9.js +0 -6264
package/dist/react.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("react/jsx-runtime"),s=require("react"),h=require("./index-Bidvqh7P.cjs"),w=["fixedRowsTop","fixedColumnsStart","readOnly","columns","colHeaders","mergeCells","columnSorting","filters","fillHandle","locale","language","contextMenu","search","query","totalCount","loading","loadError"],H=s.forwardRef(function(e,C){const f=s.useRef(null),u=s.useRef(null),r=s.useRef(e);r.current=e,s.useLayoutEffect(()=>{const{className:a,style:y,onChange:m,onSelection:x,onSort:E,onFilter:D,onQueryChange:j,onRowClick:v,onRowDoubleClick:q,onColumnLayoutChange:L,..._}=r.current,c=new h.CenituGrid(f.current,_);return c.addHook("afterChange",(o,n)=>{var t,l;return(l=(t=r.current).onChange)==null?void 0:l.call(t,o,n)}),c.addHook("afterSelection",(o,n,t,l)=>{var R,S;return(S=(R=r.current).onSelection)==null?void 0:S.call(R,o,n,t,l)}),c.addHook("afterColumnSort",(o,n)=>{var t,l;return(l=(t=r.current).onSort)==null?void 0:l.call(t,o,n)}),c.addHook("afterFilter",o=>{var n,t;return(t=(n=r.current).onFilter)==null?void 0:t.call(n,o)}),c.addHook("afterQueryChange",(o,n)=>{var t,l;return(l=(t=r.current).onQueryChange)==null?void 0:l.call(t,o,n)}),c.addHook("afterRowClick",o=>{var n,t;return(t=(n=r.current).onRowClick)==null?void 0:t.call(n,o)}),c.addHook("afterRowDoubleClick",o=>{var n,t;return(t=(n=r.current).onRowDoubleClick)==null?void 0:t.call(n,o)}),c.addHook("afterColumnLayout",o=>{var n,t;return(t=(n=r.current).onColumnLayoutChange)==null?void 0:t.call(n,o)}),u.current=c,()=>{c.destroy(),u.current=null}},[]),s.useImperativeHandle(C,()=>u.current,[]);const g=s.useRef(!1);s.useEffect(()=>{if(!g.current)return;const a=u.current;!a||!e.data||(e.dataMode==="server"?a.setPageRows(e.data,e.totalCount):T(a,e.data)||a.loadData(e.data))},[e.data]);const d=w.map(a=>e[a]);return s.useEffect(()=>{var y;if(!g.current)return;const a={};w.forEach(m=>e[m]!==void 0&&(a[m]=e[m])),(y=u.current)==null||y.updateSettings(a)},d),s.useEffect(()=>{g.current=!0},[]),b.jsx("div",{ref:f,className:e.className,style:e.style})});function T(i,e){if(!h.isObjectData(e))return k(i.getSourceData(),e);if(i.getSourceObjects()===e)return!0;const C=Array.from({length:i.countCols()},(f,u)=>i.colToProp(u));return k(i.getBoundRows(),h.ObjectBinding.create(e,C).toRows())}function k(i,e){const C=Math.max(i.length,e.length);for(let f=0;f<C;f++){const u=i[f]??[],r=e[f]??[],g=Math.max(u.length,r.length);for(let d=0;d<g;d++)if((u[d]??null)!==(r[d]??null))return!1}return!0}exports.CenituGrid=h.CenituGrid;exports.CenituTable=H;
|
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { C as
|
|
4
|
-
const
|
|
1
|
+
import { jsx as H } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as x, useRef as g, useLayoutEffect as b, useImperativeHandle as D, useEffect as y } from "react";
|
|
3
|
+
import { C as E, i as T, O as v } from "./index-BIH30fQ2.js";
|
|
4
|
+
const k = [
|
|
5
5
|
"fixedRowsTop",
|
|
6
6
|
"fixedColumnsStart",
|
|
7
7
|
"readOnly",
|
|
@@ -14,58 +14,74 @@ const _ = [
|
|
|
14
14
|
"locale",
|
|
15
15
|
"language",
|
|
16
16
|
"contextMenu",
|
|
17
|
-
"search"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
"search",
|
|
18
|
+
"query",
|
|
19
|
+
"totalCount",
|
|
20
|
+
"loading",
|
|
21
|
+
"loadError"
|
|
22
|
+
], P = x(function(e, d) {
|
|
23
|
+
const i = g(null), a = g(null), r = g(e);
|
|
24
|
+
r.current = e, b(() => {
|
|
25
|
+
const { className: u, style: h, onChange: m, onSelection: O, onSort: j, onFilter: M, onQueryChange: N, onRowClick: F, onRowDoubleClick: I, onColumnLayoutChange: Q, ..._ } = r.current, l = new E(i.current, _);
|
|
26
|
+
return l.addHook("afterChange", (o, n) => {
|
|
27
|
+
var t, c;
|
|
28
|
+
return (c = (t = r.current).onChange) == null ? void 0 : c.call(t, o, n);
|
|
29
|
+
}), l.addHook("afterSelection", (o, n, t, c) => {
|
|
30
|
+
var w, S;
|
|
31
|
+
return (S = (w = r.current).onSelection) == null ? void 0 : S.call(w, o, n, t, c);
|
|
32
|
+
}), l.addHook("afterColumnSort", (o, n) => {
|
|
33
|
+
var t, c;
|
|
34
|
+
return (c = (t = r.current).onSort) == null ? void 0 : c.call(t, o, n);
|
|
35
|
+
}), l.addHook("afterFilter", (o) => {
|
|
36
|
+
var n, t;
|
|
37
|
+
return (t = (n = r.current).onFilter) == null ? void 0 : t.call(n, o);
|
|
38
|
+
}), l.addHook("afterQueryChange", (o, n) => {
|
|
39
|
+
var t, c;
|
|
40
|
+
return (c = (t = r.current).onQueryChange) == null ? void 0 : c.call(t, o, n);
|
|
41
|
+
}), l.addHook("afterRowClick", (o) => {
|
|
42
|
+
var n, t;
|
|
43
|
+
return (t = (n = r.current).onRowClick) == null ? void 0 : t.call(n, o);
|
|
44
|
+
}), l.addHook("afterRowDoubleClick", (o) => {
|
|
45
|
+
var n, t;
|
|
46
|
+
return (t = (n = r.current).onRowDoubleClick) == null ? void 0 : t.call(n, o);
|
|
47
|
+
}), l.addHook("afterColumnLayout", (o) => {
|
|
48
|
+
var n, t;
|
|
49
|
+
return (t = (n = r.current).onColumnLayoutChange) == null ? void 0 : t.call(n, o);
|
|
50
|
+
}), a.current = l, () => {
|
|
51
|
+
l.destroy(), a.current = null;
|
|
36
52
|
};
|
|
37
|
-
}, []),
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
if (!
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
}, [
|
|
44
|
-
const
|
|
45
|
-
return
|
|
46
|
-
var
|
|
47
|
-
if (!
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
}, []), /* @__PURE__ */
|
|
53
|
+
}, []), D(d, () => a.current, []);
|
|
54
|
+
const C = g(!1);
|
|
55
|
+
y(() => {
|
|
56
|
+
if (!C.current) return;
|
|
57
|
+
const u = a.current;
|
|
58
|
+
!u || !e.data || (e.dataMode === "server" ? u.setPageRows(e.data, e.totalCount) : L(u, e.data) || u.loadData(e.data));
|
|
59
|
+
}, [e.data]);
|
|
60
|
+
const f = k.map((u) => e[u]);
|
|
61
|
+
return y(() => {
|
|
62
|
+
var h;
|
|
63
|
+
if (!C.current) return;
|
|
64
|
+
const u = {};
|
|
65
|
+
k.forEach((m) => e[m] !== void 0 && (u[m] = e[m])), (h = a.current) == null || h.updateSettings(u);
|
|
66
|
+
}, f), y(() => {
|
|
67
|
+
C.current = !0;
|
|
68
|
+
}, []), /* @__PURE__ */ H("div", { ref: i, className: e.className, style: e.style });
|
|
53
69
|
});
|
|
54
|
-
function
|
|
55
|
-
if (!
|
|
56
|
-
if (
|
|
57
|
-
const d = Array.from({ length:
|
|
58
|
-
return
|
|
70
|
+
function L(s, e) {
|
|
71
|
+
if (!T(e)) return R(s.getSourceData(), e);
|
|
72
|
+
if (s.getSourceObjects() === e) return !0;
|
|
73
|
+
const d = Array.from({ length: s.countCols() }, (i, a) => s.colToProp(a));
|
|
74
|
+
return R(s.getBoundRows(), v.create(e, d).toRows());
|
|
59
75
|
}
|
|
60
|
-
function
|
|
61
|
-
const d = Math.max(
|
|
62
|
-
for (let
|
|
63
|
-
const
|
|
64
|
-
for (let
|
|
76
|
+
function R(s, e) {
|
|
77
|
+
const d = Math.max(s.length, e.length);
|
|
78
|
+
for (let i = 0; i < d; i++) {
|
|
79
|
+
const a = s[i] ?? [], r = e[i] ?? [], C = Math.max(a.length, r.length);
|
|
80
|
+
for (let f = 0; f < C; f++) if ((a[f] ?? null) !== (r[f] ?? null)) return !1;
|
|
65
81
|
}
|
|
66
82
|
return !0;
|
|
67
83
|
}
|
|
68
84
|
export {
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
E as CenituGrid,
|
|
86
|
+
P as CenituTable
|
|
71
87
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ConditionOp } from './filters.js';
|
|
2
|
+
import type { ServerFilterDef } from './serverMode.js';
|
|
2
3
|
import { type CellValue, type RawCell } from '../formula/values.js';
|
|
3
4
|
export type CellType = 'text' | 'numeric' | 'date' | 'checkbox' | 'dropdown';
|
|
4
5
|
export interface NumericFormat {
|
|
@@ -43,6 +44,12 @@ export interface CellRenderContext {
|
|
|
43
44
|
}
|
|
44
45
|
/** Settings that can be given per column (`columns`) or per cell (`cells`). */
|
|
45
46
|
export interface CellMeta {
|
|
47
|
+
/** Stable column id used in server queries and change events; default `data`. */
|
|
48
|
+
id?: string;
|
|
49
|
+
/** Server mode: the server can sort this column. */
|
|
50
|
+
sortable?: boolean;
|
|
51
|
+
/** Server mode: what the server can filter this column by. */
|
|
52
|
+
serverFilter?: ServerFilterDef;
|
|
46
53
|
/** Object mode: property path bound to this column, e.g. "qty" or "customer.name". */
|
|
47
54
|
data?: string;
|
|
48
55
|
type?: CellType;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ColumnFilter, SortOrder } from './filters.js';
|
|
2
2
|
import type { Messages } from './messages.js';
|
|
3
|
+
import { type ServerFilter, type ServerFilterDef } from './serverMode.js';
|
|
3
4
|
export interface ColumnMenuOptions {
|
|
4
5
|
anchor: HTMLElement;
|
|
5
6
|
messages: Messages;
|
|
@@ -14,6 +15,12 @@ export interface ColumnMenuOptions {
|
|
|
14
15
|
filterable: boolean;
|
|
15
16
|
onSort(order: SortOrder | null, add?: boolean): void;
|
|
16
17
|
onFilter(filter: ColumnFilter | null): void;
|
|
18
|
+
/** Server mode: replaces the local filter controls. */
|
|
19
|
+
server?: {
|
|
20
|
+
def: ServerFilterDef;
|
|
21
|
+
value: ServerFilter | undefined;
|
|
22
|
+
onFilter(filter: ServerFilter | null): void;
|
|
23
|
+
};
|
|
17
24
|
onClose(): void;
|
|
18
25
|
}
|
|
19
26
|
/** Excel-like column dropdown: sort buttons, a condition filter and a value checklist. */
|
|
@@ -11,6 +11,7 @@ import { type ColumnFilter, type SortOrder } from './filters.js';
|
|
|
11
11
|
import { type MergeArea } from './merges.js';
|
|
12
12
|
import { type Messages } from './messages.js';
|
|
13
13
|
import { type SearchOptions } from './search.js';
|
|
14
|
+
import { type QueryChangeReason, type ServerFilter, type ServerQuery } from './serverMode.js';
|
|
14
15
|
export interface GridOptions {
|
|
15
16
|
/** Rows as arrays, or as objects bound to columns through `columns[i].data` (edits are written back). */
|
|
16
17
|
data?: RawCell[][] | DataRow[];
|
|
@@ -66,6 +67,52 @@ export interface GridOptions {
|
|
|
66
67
|
search?: boolean;
|
|
67
68
|
/** Shows a bar above the grid with the active cell's address and content; editable. */
|
|
68
69
|
formulaBar?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* 'server': the application fetches pages; the grid never sorts or filters itself and reports
|
|
72
|
+
* what it needs through the `afterQueryChange` hook. Formulas are off unless `formulas` is set,
|
|
73
|
+
* and rows cannot be added locally. Default 'client'.
|
|
74
|
+
*/
|
|
75
|
+
dataMode?: 'client' | 'server';
|
|
76
|
+
/** Server mode: object property (or function) identifying a row across pages. */
|
|
77
|
+
rowKey?: string | ((row: DataRow | RawCell[]) => unknown);
|
|
78
|
+
/** Server mode: page, sort and filters. Set again to change them from outside. */
|
|
79
|
+
query?: Partial<ServerQuery>;
|
|
80
|
+
/** Server mode: records matching the query, for the page bar. */
|
|
81
|
+
totalCount?: number;
|
|
82
|
+
/** Server mode: old rows stay visible, dimmed, until new ones arrive. */
|
|
83
|
+
loading?: boolean;
|
|
84
|
+
/** Server mode: true shows the default message, a string shows that message. */
|
|
85
|
+
loadError?: boolean | string;
|
|
86
|
+
/** Server mode: page sizes offered (default 25, 50, 100). */
|
|
87
|
+
pageSizes?: number[];
|
|
88
|
+
/** Server mode: page bar below the grid. Default true. */
|
|
89
|
+
pager?: boolean;
|
|
90
|
+
/** Server mode: fills the page bar's slot for application buttons. */
|
|
91
|
+
pagerActions?: (slot: HTMLElement) => void;
|
|
92
|
+
/** Server mode: replaces the content of the empty, loading and error messages. */
|
|
93
|
+
renderStatus?: (el: HTMLElement, state: 'empty' | 'loading' | 'error') => void;
|
|
94
|
+
/** Column widths, order and visibility to start with, from `getColumnLayout`. */
|
|
95
|
+
columnLayout?: ColumnLayout;
|
|
96
|
+
}
|
|
97
|
+
/** Saved column arrangement. Only columns with an id (`columns[i].id` or `data`) are included. */
|
|
98
|
+
export interface ColumnLayout {
|
|
99
|
+
columns: {
|
|
100
|
+
id: string;
|
|
101
|
+
width: number;
|
|
102
|
+
hidden: boolean;
|
|
103
|
+
}[];
|
|
104
|
+
}
|
|
105
|
+
export interface RowEvent {
|
|
106
|
+
/** Visual row. */
|
|
107
|
+
row: number;
|
|
108
|
+
physicalRow: number;
|
|
109
|
+
col: number;
|
|
110
|
+
columnId?: string;
|
|
111
|
+
/** Needs the `rowKey` option. */
|
|
112
|
+
rowKey?: unknown;
|
|
113
|
+
/** The source object (object mode) or raw row. */
|
|
114
|
+
rowData: DataRow | RawCell[] | undefined;
|
|
115
|
+
originalEvent: MouseEvent;
|
|
69
116
|
}
|
|
70
117
|
export interface SortKey {
|
|
71
118
|
col: number;
|
|
@@ -78,6 +125,10 @@ export interface CellChange {
|
|
|
78
125
|
col: number;
|
|
79
126
|
/** Bound property in object mode. */
|
|
80
127
|
prop?: string;
|
|
128
|
+
/** Column id, when the column has one. */
|
|
129
|
+
columnId?: string;
|
|
130
|
+
/** Server mode: `rowKey` value of the row; indexes change between pages, this does not. */
|
|
131
|
+
rowKey?: unknown;
|
|
81
132
|
oldValue: RawCell;
|
|
82
133
|
newValue: RawCell;
|
|
83
134
|
}
|
|
@@ -91,6 +142,15 @@ interface HookMap {
|
|
|
91
142
|
afterAlter: (action: AlterAction, index: number, amount: number) => void;
|
|
92
143
|
afterColumnSort: (col: number, order: SortOrder | null) => void;
|
|
93
144
|
afterSort: (keys: SortKey[]) => void;
|
|
145
|
+
afterRowClick: (e: RowEvent) => void;
|
|
146
|
+
/** Return false to keep the cell editor closed, e.g. when double click opens the record. */
|
|
147
|
+
afterRowDoubleClick: (e: RowEvent) => boolean | void;
|
|
148
|
+
/** Columns were resized, moved, hidden or shown; save the layout here. */
|
|
149
|
+
afterColumnLayout: (layout: ColumnLayout) => void;
|
|
150
|
+
/** Server mode: fetch the rows for `query`. */
|
|
151
|
+
afterQueryChange: (query: ServerQuery, reason: QueryChangeReason) => void;
|
|
152
|
+
/** Server mode: a paste did not fit the loaded rows; `lost` rows were not pasted. */
|
|
153
|
+
afterPasteClipped: (lost: number) => void;
|
|
94
154
|
afterFilter: (filters: Map<number, ColumnFilter>) => void;
|
|
95
155
|
afterAutofill: (source: CellRange, target: CellRange) => void;
|
|
96
156
|
afterValidate: (row: number, col: number, error: string | undefined) => void;
|
|
@@ -163,9 +223,27 @@ export declare class CenituGrid {
|
|
|
163
223
|
/** Matches shown highlighted while the search box is open (physical cell keys). */
|
|
164
224
|
private searchHits;
|
|
165
225
|
private bar?;
|
|
226
|
+
private server?;
|
|
166
227
|
private frame;
|
|
167
228
|
private cleanup;
|
|
168
229
|
constructor(container: HTMLElement, options?: GridOptions);
|
|
230
|
+
/** Current query (server mode). */
|
|
231
|
+
getQuery(): ServerQuery | undefined;
|
|
232
|
+
/** Changes the query and asks for new rows. Anything but a page change returns to page 1. */
|
|
233
|
+
setQuery(change: Partial<ServerQuery>, reason?: QueryChangeReason): void;
|
|
234
|
+
/**
|
|
235
|
+
* Shows a fetched page. Unlike `loadData`, sort marks, filters, column layout and scroll stay,
|
|
236
|
+
* and the selection follows its row by `rowKey` when the row is still there. Undo history ends
|
|
237
|
+
* here: it refers to rows that are gone.
|
|
238
|
+
*/
|
|
239
|
+
setPageRows(rows: RawCell[][] | DataRow[], totalCount?: number): void;
|
|
240
|
+
private rowKeyAt;
|
|
241
|
+
/** Stable id of a column: `columns[i].id`, then its bound property. */
|
|
242
|
+
getColumnId(col: number): string | undefined;
|
|
243
|
+
private colOfId;
|
|
244
|
+
private buildServerMode;
|
|
245
|
+
/** Page bar, busy state and the empty/loading/error message. */
|
|
246
|
+
private renderServerState;
|
|
169
247
|
/** Number of visible rows. */
|
|
170
248
|
countRows(): number;
|
|
171
249
|
countSourceRows(): number;
|
|
@@ -216,7 +294,7 @@ export declare class CenituGrid {
|
|
|
216
294
|
getCellMeta(row: number, col: number): CellMeta;
|
|
217
295
|
setCellMeta(row: number, col: number, meta: CellMeta): void;
|
|
218
296
|
/** Updates a subset of options at runtime. */
|
|
219
|
-
updateSettings(s: Pick<GridOptions, 'fixedRowsTop' | 'fixedColumnsStart' | 'readOnly' | 'columns' | 'colHeaders' | 'mergeCells' | 'columnSorting' | 'filters' | 'fillHandle' | 'locale' | 'language' | 'contextMenu' | 'conditionalFormats' | 'search'>): void;
|
|
297
|
+
updateSettings(s: Pick<GridOptions, 'fixedRowsTop' | 'fixedColumnsStart' | 'readOnly' | 'columns' | 'colHeaders' | 'mergeCells' | 'columnSorting' | 'filters' | 'fillHandle' | 'locale' | 'language' | 'contextMenu' | 'conditionalFormats' | 'search' | 'query' | 'totalCount' | 'loading' | 'loadError'>): void;
|
|
220
298
|
selectCell(row: number, col: number, row2?: number, col2?: number): void;
|
|
221
299
|
private announce;
|
|
222
300
|
/** Selection as [[row, col, row2, col2]] (visual). */
|
|
@@ -234,6 +312,16 @@ export declare class CenituGrid {
|
|
|
234
312
|
toggleCellStyle(flag: 'bold' | 'italic' | 'underline' | 'strike'): void;
|
|
235
313
|
setRowHeight(row: number, height: number): void;
|
|
236
314
|
getRowHeight(row: number): number;
|
|
315
|
+
/** Current widths, order and visibility; store it and give it back with `setColumnLayout`. */
|
|
316
|
+
getColumnLayout(): ColumnLayout;
|
|
317
|
+
/**
|
|
318
|
+
* Restores a saved layout. Ids that no longer exist are skipped and new columns stay after the
|
|
319
|
+
* saved ones, so a layout survives application updates. Clears undo history when columns moved:
|
|
320
|
+
* its entries refer to the old order.
|
|
321
|
+
*/
|
|
322
|
+
setColumnLayout(layout: ColumnLayout): void;
|
|
323
|
+
private applyColumnLayout;
|
|
324
|
+
private layoutChanged;
|
|
237
325
|
hideColumns(cols: number[]): void;
|
|
238
326
|
/** Shows the given hidden columns, or all of them. */
|
|
239
327
|
showColumns(cols?: number[]): void;
|
|
@@ -258,6 +346,8 @@ export declare class CenituGrid {
|
|
|
258
346
|
/** The primary sort key, or null. */
|
|
259
347
|
getSortState(): SortKey | null;
|
|
260
348
|
getSortKeys(): SortKey[];
|
|
349
|
+
/** Server mode: sets or clears the filter of a column; asks for rows from page 1. */
|
|
350
|
+
setServerFilter(columnId: string, filter: ServerFilter | null): void;
|
|
261
351
|
setFilter(col: number, filter: ColumnFilter | null): void;
|
|
262
352
|
clearFilters(): void;
|
|
263
353
|
getFilters(): Map<number, ColumnFilter>;
|
|
@@ -294,6 +384,7 @@ export declare class CenituGrid {
|
|
|
294
384
|
* is a no-op, out of range, or would split a merged cell.
|
|
295
385
|
*/
|
|
296
386
|
moveColumns(start: number, count: number, target: number): boolean;
|
|
387
|
+
private relocateColumns;
|
|
297
388
|
canMoveColumns(start: number, count: number, target: number): boolean;
|
|
298
389
|
undo(): void;
|
|
299
390
|
redo(): void;
|
|
@@ -418,6 +509,8 @@ export declare class CenituGrid {
|
|
|
418
509
|
private onMouseDown;
|
|
419
510
|
private onContextMenu;
|
|
420
511
|
private onDoubleClick;
|
|
512
|
+
/** The row a click landed on; null for headers, checkboxes and drags that ended on another cell. */
|
|
513
|
+
private rowEventAt;
|
|
421
514
|
private onDrag;
|
|
422
515
|
private onMouseUp;
|
|
423
516
|
private dropLine?;
|
|
@@ -428,6 +521,7 @@ export declare class CenituGrid {
|
|
|
428
521
|
private fillToDataEnd;
|
|
429
522
|
private startResize;
|
|
430
523
|
private startRowResize;
|
|
524
|
+
private openServerMenu;
|
|
431
525
|
private openMenu;
|
|
432
526
|
private toggleCheckboxes;
|
|
433
527
|
private moveActive;
|
|
@@ -60,6 +60,16 @@ export interface Messages {
|
|
|
60
60
|
previous: string;
|
|
61
61
|
close: string;
|
|
62
62
|
formulaBar: string;
|
|
63
|
+
/** {from}, {to} and {total} are record numbers. */
|
|
64
|
+
pagerRange: string;
|
|
65
|
+
pageSize: string;
|
|
66
|
+
noRows: string;
|
|
67
|
+
loading: string;
|
|
68
|
+
loadError: string;
|
|
69
|
+
dateFrom: string;
|
|
70
|
+
dateTo: string;
|
|
71
|
+
yes: string;
|
|
72
|
+
no: string;
|
|
63
73
|
}
|
|
64
74
|
export declare const enUS: Messages;
|
|
65
75
|
export declare const trTR: Messages;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Messages } from './messages.js';
|
|
2
|
+
/** What a column can be filtered by on the server. */
|
|
3
|
+
export type ServerFilterDef = {
|
|
4
|
+
kind: 'text';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'list';
|
|
7
|
+
options: {
|
|
8
|
+
value: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
}[];
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'date';
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'boolean';
|
|
15
|
+
};
|
|
16
|
+
/** A filter value in the query; date bounds are as the date inputs give them (YYYY-MM-DD). */
|
|
17
|
+
export type ServerFilter = {
|
|
18
|
+
kind: 'text';
|
|
19
|
+
value: string;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'list';
|
|
22
|
+
values: string[];
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'date';
|
|
25
|
+
from?: string;
|
|
26
|
+
to?: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'boolean';
|
|
29
|
+
value: boolean;
|
|
30
|
+
};
|
|
31
|
+
export interface ServerSort {
|
|
32
|
+
field: string;
|
|
33
|
+
desc: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Describes the rows the application should fetch. Fields are column ids, never indexes. */
|
|
36
|
+
export interface ServerQuery {
|
|
37
|
+
page: number;
|
|
38
|
+
pageSize: number;
|
|
39
|
+
sort: ServerSort[];
|
|
40
|
+
filters: Record<string, ServerFilter>;
|
|
41
|
+
search?: string;
|
|
42
|
+
}
|
|
43
|
+
export type QueryChangeReason = 'page' | 'pageSize' | 'sort' | 'filter' | 'search';
|
|
44
|
+
export declare const DEFAULT_PAGE_SIZES: number[];
|
|
45
|
+
export declare function initialQuery(q: Partial<ServerQuery> | undefined, pageSizes: number[]): ServerQuery;
|
|
46
|
+
export declare const pageCount: (total: number, pageSize: number) => number;
|
|
47
|
+
/** The controls for one filter; `read` gives the entered filter, or null when it is empty. */
|
|
48
|
+
export declare function serverFilterSection(doc: Document, m: Messages, def: ServerFilterDef, value: ServerFilter | undefined): {
|
|
49
|
+
el: HTMLElement;
|
|
50
|
+
read(): ServerFilter | null;
|
|
51
|
+
};
|
|
52
|
+
/** Page bar: custom actions, record range, page size, previous and next. */
|
|
53
|
+
export declare class Pager {
|
|
54
|
+
private readonly m;
|
|
55
|
+
readonly el: HTMLDivElement;
|
|
56
|
+
/** Slot for application buttons. */
|
|
57
|
+
readonly actions: HTMLDivElement;
|
|
58
|
+
private readonly range;
|
|
59
|
+
private readonly size;
|
|
60
|
+
private readonly position;
|
|
61
|
+
private readonly prev;
|
|
62
|
+
private readonly next;
|
|
63
|
+
constructor(doc: Document, m: Messages, pageSizes: number[], onPage: (delta: number) => void, onSize: (size: number) => void);
|
|
64
|
+
/** `total` undefined keeps the last figures, so the bar does not flicker while a page loads. */
|
|
65
|
+
update(q: ServerQuery, total: number | undefined): void;
|
|
66
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { CenituGrid, type GridOptions, type CellChange, type ChangeSource, type AlterAction, type SortKey, type HookName, } from './grid/grid.js';
|
|
1
|
+
export { CenituGrid, type GridOptions, type CellChange, type ChangeSource, type AlterAction, type SortKey, type ColumnLayout, type RowEvent, type HookName, } from './grid/grid.js';
|
|
2
2
|
export type { CellMeta, CellStyle, ConditionalFormat, NumericFormat, CellRenderContext, CellType as GridCellType } from './grid/cellTypes.js';
|
|
3
3
|
export type { ColumnFilter, ConditionOp, SortOrder } from './grid/filters.js';
|
|
4
4
|
export type { MergeArea } from './grid/merges.js';
|
|
5
5
|
export type { SearchOptions } from './grid/search.js';
|
|
6
|
+
export type { ServerQuery, ServerFilter, ServerFilterDef, ServerSort, QueryChangeReason } from './grid/serverMode.js';
|
|
6
7
|
export type { MenuEntry, MenuItem } from './grid/contextMenu.js';
|
|
7
8
|
export type { DataRow } from './grid/binding.js';
|
|
8
9
|
export { enUS, trTR, type Messages } from './grid/messages.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
2
|
import type { ColumnFilter, SortOrder } from '../grid/filters.js';
|
|
3
|
-
import { CenituGrid, type CellChange, type ChangeSource, type GridOptions } from '../grid/grid.js';
|
|
3
|
+
import { CenituGrid, type CellChange, type ChangeSource, type ColumnLayout, type GridOptions, type RowEvent } from '../grid/grid.js';
|
|
4
|
+
import type { QueryChangeReason, ServerQuery } from '../grid/serverMode.js';
|
|
4
5
|
export interface CenituTableProps extends GridOptions {
|
|
5
6
|
className?: string;
|
|
6
7
|
style?: CSSProperties;
|
|
@@ -8,6 +9,12 @@ export interface CenituTableProps extends GridOptions {
|
|
|
8
9
|
onSelection?(row: number, col: number, row2: number, col2: number): void;
|
|
9
10
|
onSort?(col: number, order: SortOrder | null): void;
|
|
10
11
|
onFilter?(filters: Map<number, ColumnFilter>): void;
|
|
12
|
+
onRowClick?(event: RowEvent): void;
|
|
13
|
+
/** Return false to keep the cell editor closed. */
|
|
14
|
+
onRowDoubleClick?(event: RowEvent): boolean | void;
|
|
15
|
+
onColumnLayoutChange?(layout: ColumnLayout): void;
|
|
16
|
+
/** Server mode: fetch the rows for `query`. */
|
|
17
|
+
onQueryChange?(query: ServerQuery, reason: QueryChangeReason): void;
|
|
11
18
|
}
|
|
12
19
|
/**
|
|
13
20
|
* React component around CenituGrid. The ref exposes the grid instance for imperative calls.
|