tsgrid-ui 1.0.1 → 2.1.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/CHANGELOG.md CHANGED
@@ -2,6 +2,78 @@
2
2
 
3
3
  All notable changes to **TsGrid UI** will be documented in this file.
4
4
 
5
+ ## v2.1.0 — 2026-05-13
6
+
7
+ ### Refactor
8
+
9
+ Decomposed `TsUtils` into 5 stateless sub-modules — **no breaking changes**, no public API surface change. The class still exists with the same shape; method bodies are now one-line delegators that route to plain functions in sibling modules.
10
+
11
+ - `src/tsutils-type-guards.ts` — 9 type-guard functions (`isInt`, `isFloat`, `isMoney`, `isHex`, `isAlphaNumeric`, `isEmail`, `isIpAddress`, `isPlainObject`, `isBin`). `isFloat`/`isMoney` accept a `Pick<TsUISettings, ...>` slice for locale-aware testing.
12
+ - `src/tsutils-color.ts` — 4 color math functions (`parseColor`, `hsv2rgb`, `rgb2hsv`, `colorContrast`) + `TsColorRgb` type. Dual-form dispatch (object-arg vs positional) preserved using `typeof` detection — more robust than `arguments.length` under the delegator pattern.
13
+ - `src/tsutils-data.ts` — 10 data helpers (`clone`, `extend`, `naturalCompare`, `normMenu`, `getNested`, `encodeParams`, `prepareParams`, `parseRoute`, `debounce`, `wait`) + `TsCloneOptions`, `TsNormMenuOptions` types. `prepareParams` accepts `defaultDataType` parameter.
14
+ - `src/tsutils-string.ts` — 10 string/HTML helpers (`stripSpaces`, `stripTags`, `encodeTags`, `decodeTags`, `escapeId`, `unescapeId`, `base64encode`, `base64decode`, `sha256`, `execTemplate`).
15
+ - `src/tsutils-marker.ts` — `marker` + private DOM regex helpers (`_clearMarkers`, `_replace`).
16
+
17
+ `TsUtils` singleton shape and all ~788 call sites: **UNCHANGED**. SEMVER MINOR. BC verdict: NONE.
18
+
19
+ ### Tests
20
+
21
+ Added 27 unit tests (84 → 111): 15 color cluster (`parseColor`, `hsv2rgb`, `rgb2hsv`, `colorContrast`) + 2 `isBin` ratchet + 2 object-form regression locks (`hsv2rgb`/`rgb2hsv`) + 6 data ratchet (`getNested`, `normMenu`) + 2 string ratchet (`decodeTags`, `execTemplate`).
22
+
23
+ ### Bundle
24
+
25
+ Delta vs v2.0.1 baseline: `dist/tsgrid-ui.js` +0.15% (944,879 → 943,454 bytes), `dist/tsgrid-ui.es6.js` +0.15% (943,022 → 941,597 bytes). Within ±2% gate. PASSED.
26
+
27
+ ---
28
+
29
+ ## v2.0.1 — 2026-05-13
30
+
31
+ ### Fixed
32
+
33
+ - **`MIGRATION_v2.md` now included in the published npm tarball.** v2.0.0 omitted this file from `package.json` `files`, so `CHANGELOG.md` and `README.md` links pointing to `MIGRATION_v2.md` (codemod, bundle measurement, release checklist) broke on npmjs.com. No source code changes — package metadata only.
34
+
35
+ ## v2.0.0 — 2026-05-09
36
+
37
+ ### Breaking changes
38
+
39
+ **BC-1 — Event handler signatures changed (`CustomEvent` → `TsEventPayload`)**
40
+
41
+ All `on*` event handler properties across `TsGrid`, `TsForm`, and `TsField` now declare
42
+ `(event: TsEventPayload) => void` instead of `(event: CustomEvent) => void`.
43
+
44
+ This is a type-level correction: the runtime has always dispatched `TsEventPayload` objects,
45
+ never DOM `CustomEvent` instances. Consumers who explicitly annotated handlers with
46
+ `CustomEvent` will see a TypeScript compile error. Untyped or `any`-typed handlers are
47
+ unaffected. Mechanical migration via codemod — see [MIGRATION_v2.md § Codemod](MIGRATION_v2.md#codemod).
48
+
49
+ **BC-2 — Internal restructure; deep imports are unsupported**
50
+
51
+ `src/tsgrid.ts` has been decomposed from ~10,006 LOC into 8 sibling modules:
52
+ `grid-columns`, `grid-state`, `grid-data`, `grid-selection`, `grid-edit`, `grid-search`,
53
+ `grid-interaction`, `grid-render`. The public class `TsGrid` is now ~2,392 LOC (thin
54
+ orchestrator of one-liner delegators).
55
+
56
+ The public API surface is **UNCHANGED**: all method signatures, names, and behaviors are
57
+ preserved (verified by 84 Vitest + 38 Playwright tests). Consumers who import from the
58
+ public barrel (`import { TsGrid } from 'tsgrid-ui'`) require **no changes**. Subclasses
59
+ or code that inspects `TsGrid.prototype` directly may observe method bodies as one-line
60
+ delegators — this is expected behavior. Deep imports from internal paths
61
+ (`tsgrid-ui/src/*`) are not supported and may break.
62
+
63
+ ### Bundle size disclosure
64
+
65
+ v2.0 is a structural refactor with no bundle reduction goal. Bundle size delta vs v1.0.1
66
+ baseline: **-0.19%** (actual: 941,597 bytes vs baseline: 943,401 bytes). No reduction is
67
+ claimed. Bundle improvements are deferred to v2.2 (multi-entry subpath exports +
68
+ tree-shaking). See [MIGRATION_v2.md § Bundle size measurement](MIGRATION_v2.md#bundle-size-measurement).
69
+
70
+ ### Migration
71
+
72
+ See [MIGRATION_v2.md](MIGRATION_v2.md) for the codemod, full migration guide, and
73
+ release checklist.
74
+
75
+ ---
76
+
5
77
  ## [1.0.1] — Consumer DX fixes
6
78
 
7
79
  Patch release driven by integrating tsgrid-ui v1.0.0 in a real Angular 21 standalone project. Three changes, no breaking, no API removals.
@@ -0,0 +1,178 @@
1
+ # Migration Guide: v1.x to v2.0
2
+
3
+ <!-- baseline: 943401 bytes -->
4
+
5
+ ## Bundle size measurement
6
+
7
+ | Metric | Value |
8
+ |--------|-------|
9
+ | Baseline (v1.0.1, pre-v2.0) | 943,401 bytes |
10
+ | Post-v2.0 actual | 941,597 bytes |
11
+ | Delta | -1,804 bytes (-0.19%) |
12
+ | Status | PASS (within ±2% gate) |
13
+ | Build date | 2026-05-09 |
14
+
15
+ v2.0 is a structural refactor with no bundle reduction goal. The -0.19% delta is
16
+ within the ±2% measurement gate and does not constitute a meaningful change. Bundle
17
+ improvements are explicitly deferred to v2.2 (multi-entry subpath exports + tree-shaking).
18
+
19
+ ---
20
+
21
+ ## Overview
22
+
23
+ `tsgrid-ui` v2.0 is a **code-organisation and type-system release**. No runtime behavior
24
+ changes between v1.0.1 and v2.0.0. All public API method signatures remain identical.
25
+
26
+ Two breaking changes are documented below (BC-1 and BC-2). Both were intentional and
27
+ are codemod-friendly.
28
+
29
+ ---
30
+
31
+ ## Breaking Change BC-1: Event handler types
32
+
33
+ ### What changed
34
+
35
+ All `on*` event handler properties on `TsGrid`, `TsForm`, and `TsField` now declare
36
+ `TsEventPayload` as the handler parameter type instead of `CustomEvent`.
37
+
38
+ **v1.x (old type):**
39
+ ```ts
40
+ onSelect: ((event: CustomEvent) => void) | null
41
+ ```
42
+
43
+ **v2.0 (corrected type):**
44
+ ```ts
45
+ onSelect: ((event: TsEventPayload) => void) | null
46
+ ```
47
+
48
+ ### Why this is a correction, not a new feature
49
+
50
+ The runtime event system in `TsGrid`/`TsForm` has always passed a `TsEventPayload`
51
+ object to handlers — never a DOM `CustomEvent`. The v1.x type declarations were
52
+ inaccurate. This change aligns the declared types with what was always happening at
53
+ runtime.
54
+
55
+ ### Who is affected
56
+
57
+ Only consumers who **explicitly annotated** their handler parameter as `CustomEvent`:
58
+
59
+ ```ts
60
+ // This breaks on v2.0 — parameter type mismatch
61
+ grid.onSelect = (event: CustomEvent) => {
62
+ console.log(event.detail)
63
+ }
64
+ ```
65
+
66
+ Consumers who used **no annotation** or **inferred types** are unaffected:
67
+
68
+ ```ts
69
+ // These continue to work — TypeScript infers TsEventPayload
70
+ grid.onSelect = (event) => { console.log(event.detail) }
71
+ grid.onSelect = (event: TsEventPayload) => { console.log(event.detail) }
72
+ ```
73
+
74
+ ### Codemod
75
+
76
+ Apply the following regex to your source files to migrate in bulk:
77
+
78
+ **Find:**
79
+ ```
80
+ \(event:\s*CustomEvent\)\s*=>
81
+ ```
82
+
83
+ **Replace:**
84
+ ```
85
+ (event: TsEventPayload) =>
86
+ ```
87
+
88
+ **Caveats:**
89
+ 1. You must add `import type { TsEventPayload } from 'tsgrid-ui'` to each migrated file.
90
+ 2. The regex may produce false positives on unrelated DOM `CustomEvent` handler sites
91
+ (e.g., handlers attached via `element.addEventListener('custom', ...)`). Review
92
+ replacements manually before committing.
93
+ 3. `event.detail` is now typed as `TsEventData` (with `[key: string]: unknown`). If you
94
+ accessed properties like `event.detail.someField`, TypeScript strict mode requires
95
+ bracket notation: `event.detail['someField']`. Cast as needed.
96
+
97
+ ### Before / after example
98
+
99
+ The updated `test/consumer-smoke.ts` is the canonical reference. Below is a condensed
100
+ example:
101
+
102
+ **Before (v1.x):**
103
+ ```ts
104
+ import { TsGrid } from 'tsgrid-ui'
105
+
106
+ const grid = new TsGrid({ name: 'my-grid', columns: [], records: [] })
107
+
108
+ // Explicit CustomEvent annotation — BREAKS on v2.0
109
+ grid.onSelect = (event: CustomEvent) => {
110
+ console.log(event.detail)
111
+ }
112
+ ```
113
+
114
+ **After (v2.0):**
115
+ ```ts
116
+ import { TsGrid } from 'tsgrid-ui'
117
+ import type { TsEventPayload } from 'tsgrid-ui'
118
+
119
+ const grid = new TsGrid({ name: 'my-grid', columns: [], records: [] })
120
+
121
+ // Option A: explicit TsEventPayload annotation
122
+ grid.onSelect = (event: TsEventPayload) => {
123
+ console.log(event.detail)
124
+ }
125
+
126
+ // Option B: remove the annotation — TypeScript infers correctly
127
+ grid.onSelect = (event) => {
128
+ console.log(event.detail)
129
+ }
130
+ ```
131
+
132
+ `TsEventPayload` has been importable from `tsgrid-ui` since **v1.0.1**. Consumers may
133
+ pre-migrate before upgrading to v2.0.
134
+
135
+ ---
136
+
137
+ ## Breaking Change BC-2: Deep imports are unsupported
138
+
139
+ v2.0 decomposes `src/tsgrid.ts` into sibling modules (`src/grid-*.ts`). Any import from
140
+ an internal path is **not supported** and carries no stability guarantee:
141
+
142
+ ```ts
143
+ // UNSUPPORTED — may break in any minor or patch release
144
+ import { someHelper } from 'tsgrid-ui/src/tsgrid'
145
+ import { someHelper } from 'tsgrid-ui/src/grid-columns'
146
+ ```
147
+
148
+ Always import from the public barrel:
149
+
150
+ ```ts
151
+ // SUPPORTED — stable public API
152
+ import { TsGrid, TsEventPayload } from 'tsgrid-ui'
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Bundle size disclosure
158
+
159
+ v2.0 decomposes the codebase for maintainability. **Bundle size is unchanged by design.**
160
+ Bundle improvements are deferred to v2.2 (multi-entry subpath exports + tree-shaking).
161
+
162
+ Do not expect or claim bundle size reduction from upgrading to v2.0.
163
+
164
+ ---
165
+
166
+ ## Release checklist
167
+
168
+ > Reference — execute manually after PR review and approval. The SDD apply phase does NOT
169
+ > run any of these.
170
+
171
+ ```bash
172
+ # After PR merged to master:
173
+ git checkout master && git pull
174
+ git tag -a v2.0.0 -m "v2.0.0 — TsGrid decomposition + event signature fix"
175
+ git push origin v2.0.0
176
+ pnpm publish --access public --tag latest
177
+ gh release create v2.0.0 --title "v2.0.0 — TsGrid v2 decomposition" --notes-from-tag
178
+ ```
@@ -1,4 +1,4 @@
1
- /* tsgrid-ui 1.0.x (nightly) (5/9/2026, 12:21:22 AM) (c) 2014 vitmalina@gmail.com, (c) 2026 DaverSoGT — MIT */
1
+ /* tsgrid-ui 1.0.x (nightly) (5/13/2026, 3:29:07 PM) (c) 2014 vitmalina@gmail.com, (c) 2026 DaverSoGT — MIT */
2
2
  /**
3
3
  * TODO:
4
4
  * - remove default styling, only keep tsg-* styles
@@ -9,7 +9,7 @@
9
9
  */
10
10
  @font-face {
11
11
  font-family: "tsgrid-font";
12
- src: url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff");
12
+ src: url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff");
13
13
  font-weight: normal;
14
14
  font-style: normal;
15
15
  }
@@ -227,6 +227,55 @@ declare class Query {
227
227
  click(): Query;
228
228
  }
229
229
 
230
+ /**
231
+ * Part of TsUi 2.0 library — color cluster sub-module
232
+ * - Extracted from src/tsutils.ts by v2.1 SDD refactor (Phase 2)
233
+ * - No dependencies on TsBase, TsUtils, or any other sub-module (L1 DAG leaf)
234
+ * - All exports are plain functions — no default export
235
+ *
236
+ * 4-space indent (project convention for sub-modules).
237
+ */
238
+ /** RGB(A) color as returned by parseColor() */
239
+ interface TsColorRgb {
240
+ r: number;
241
+ g: number;
242
+ b: number;
243
+ a: number;
244
+ }
245
+
246
+ /**
247
+ * TsUtils v2.1 — Data / Object helpers sub-module (Phase 3+4 of v2.1 SDD)
248
+ *
249
+ * Contains: TsCloneOptions, clone, extend,
250
+ * naturalCompare, normMenu, getNested, encodeParams,
251
+ * prepareParams, parseRoute, debounce, wait
252
+ *
253
+ * Rules:
254
+ * - No default export
255
+ * - No import from tsbase.ts (INV-4)
256
+ * - No this.-dispatch inside function bodies (INV-8)
257
+ * - 4-space indent
258
+ */
259
+ /** Options for TsUtils.clone() */
260
+ interface TsCloneOptions {
261
+ functions?: boolean;
262
+ elements?: boolean;
263
+ events?: boolean;
264
+ exclude?: string[] | ((key: string, ctx: {
265
+ obj: unknown;
266
+ parent: string;
267
+ }) => boolean);
268
+ parent?: string;
269
+ }
270
+ /** Options for TsUtils.normMenu() */
271
+ interface TsNormMenuOptions {
272
+ itemMap?: {
273
+ id: string;
274
+ text: string;
275
+ };
276
+ [key: string]: unknown;
277
+ }
278
+
230
279
  /**
231
280
  * Part of TsUi 2.0 library
232
281
  * - Dependencies: mQuery, TsUtils, TsBase, TsLocale
@@ -310,13 +359,7 @@ interface TsTimeResult {
310
359
  minutes: number;
311
360
  seconds: number;
312
361
  }
313
- /** RGB(A) color as returned by TsUtils.parseColor() */
314
- interface TsColorRgb {
315
- r: number;
316
- g: number;
317
- b: number;
318
- a: number;
319
- }
362
+
320
363
  /** A normalized menu item */
321
364
  interface TsMenuItem {
322
365
  id: string | number | null;
@@ -327,25 +370,6 @@ interface TsMenuItem {
327
370
  attrs?: string;
328
371
  [key: string]: unknown;
329
372
  }
330
- /** Options for TsUtils.normMenu() */
331
- interface TsNormMenuOptions {
332
- itemMap?: {
333
- id: string;
334
- text: string;
335
- };
336
- [key: string]: unknown;
337
- }
338
- /** Options for TsUtils.clone() */
339
- interface TsCloneOptions {
340
- functions?: boolean;
341
- elements?: boolean;
342
- events?: boolean;
343
- exclude?: string[] | ((key: string, ctx: {
344
- obj: unknown;
345
- parent: string;
346
- }) => boolean);
347
- parent?: string;
348
- }
349
373
  /** Promise-chain handle returned by TsUtils.message() / .confirm() / .prompt() */
350
374
  interface TsMessageProm {
351
375
  self: TsBase;
@@ -536,7 +560,7 @@ declare class Utils {
536
560
  getStrWidth(str: string, styles?: string, raw?: boolean): any;
537
561
  getStrHeight(str: string, styles?: string, raw?: boolean): any;
538
562
  execTemplate(str: any, replace_obj: any): any;
539
- marker(el: any, items: any, options?: any): any;
563
+ marker(el: any, items: any, options?: any): unknown;
540
564
  lang(phrase: string, params?: Record<string, string | number> | boolean): string;
541
565
  locale(locale: string | string[] | Record<string, unknown>, keepPhrases?: boolean, noMerge?: boolean): Promise<{
542
566
  file: string;
@@ -1723,57 +1747,57 @@ declare class TsGrid extends TsBase {
1723
1747
  operators: Record<string, any[]>;
1724
1748
  defaultOperator: Record<string, string>;
1725
1749
  operatorsMap: Record<string, string>;
1726
- onAdd: ((event: CustomEvent) => void) | null;
1727
- onEdit: ((event: CustomEvent) => void) | null;
1728
- onRequest: ((event: CustomEvent) => void) | null;
1729
- onLoad: ((event: CustomEvent) => void) | null;
1730
- onDelete: ((event: CustomEvent) => void) | null;
1731
- onSave: ((event: CustomEvent) => void) | null;
1732
- onSelect: ((event: CustomEvent) => void) | null;
1733
- onClick: ((event: CustomEvent) => void) | null;
1734
- onDblClick: ((event: CustomEvent) => void) | null;
1735
- onContextMenu: ((event: CustomEvent) => void) | null;
1736
- onContextMenuClick: ((event: CustomEvent) => void) | null;
1737
- onColumnClick: ((event: CustomEvent) => void) | null;
1738
- onColumnDblClick: ((event: CustomEvent) => void) | null;
1739
- onColumnContextMenu: ((event: CustomEvent) => void) | null;
1740
- onColumnResize: ((event: CustomEvent) => void) | null;
1741
- onColumnAutoResize: ((event: CustomEvent) => void) | null;
1742
- onSort: ((event: CustomEvent) => void) | null;
1743
- onSearch: ((event: CustomEvent) => void) | null;
1744
- onSearchOpen: ((event: CustomEvent) => void) | null;
1745
- onSearchClose: ((event: CustomEvent) => void) | null;
1746
- onChange: ((event: CustomEvent) => void) | null;
1747
- onRestore: ((event: CustomEvent) => void) | null;
1748
- onExpand: ((event: CustomEvent) => void) | null;
1749
- onCollapse: ((event: CustomEvent) => void) | null;
1750
- onError: ((event: CustomEvent) => void) | null;
1751
- onKeydown: ((event: CustomEvent) => void) | null;
1752
- onToolbar: ((event: CustomEvent) => void) | null;
1753
- onColumnOnOff: ((event: CustomEvent) => void) | null;
1754
- onCopy: ((event: CustomEvent) => void) | null;
1755
- onPaste: ((event: CustomEvent) => void) | null;
1756
- onSelectionExtend: ((event: CustomEvent) => void) | null;
1757
- onEditField: ((event: CustomEvent) => void) | null;
1758
- onRender: ((event: CustomEvent) => void) | null;
1759
- onRefresh: ((event: CustomEvent) => void) | null;
1760
- onReload: ((event: CustomEvent) => void) | null;
1761
- onResize: ((event: CustomEvent) => void) | null;
1762
- onDestroy: ((event: CustomEvent) => void) | null;
1763
- onStateSave: ((event: CustomEvent) => void) | null;
1764
- onStateRestore: ((event: CustomEvent) => void) | null;
1765
- onFocus: ((event: CustomEvent) => void) | null;
1766
- onBlur: ((event: CustomEvent) => void) | null;
1767
- onReorderRow: ((event: CustomEvent) => void) | null;
1768
- onSearchSave: ((event: CustomEvent) => void) | null;
1769
- onSearchRemove: ((event: CustomEvent) => void) | null;
1770
- onSearchSelect: ((event: CustomEvent) => void) | null;
1771
- onColumnSelect: ((event: CustomEvent) => void) | null;
1772
- onColumnDragStart: ((event: CustomEvent) => void) | null;
1773
- onColumnDragEnd: ((event: CustomEvent) => void) | null;
1774
- onResizerDblClick: ((event: CustomEvent) => void) | null;
1775
- onMouseEnter: ((event: CustomEvent) => void) | null;
1776
- onMouseLeave: ((event: CustomEvent) => void) | null;
1750
+ onAdd: ((event: TsEventPayload) => void) | null;
1751
+ onEdit: ((event: TsEventPayload) => void) | null;
1752
+ onRequest: ((event: TsEventPayload) => void) | null;
1753
+ onLoad: ((event: TsEventPayload) => void) | null;
1754
+ onDelete: ((event: TsEventPayload) => void) | null;
1755
+ onSave: ((event: TsEventPayload) => void) | null;
1756
+ onSelect: ((event: TsEventPayload) => void) | null;
1757
+ onClick: ((event: TsEventPayload) => void) | null;
1758
+ onDblClick: ((event: TsEventPayload) => void) | null;
1759
+ onContextMenu: ((event: TsEventPayload) => void) | null;
1760
+ onContextMenuClick: ((event: TsEventPayload) => void) | null;
1761
+ onColumnClick: ((event: TsEventPayload) => void) | null;
1762
+ onColumnDblClick: ((event: TsEventPayload) => void) | null;
1763
+ onColumnContextMenu: ((event: TsEventPayload) => void) | null;
1764
+ onColumnResize: ((event: TsEventPayload) => void) | null;
1765
+ onColumnAutoResize: ((event: TsEventPayload) => void) | null;
1766
+ onSort: ((event: TsEventPayload) => void) | null;
1767
+ onSearch: ((event: TsEventPayload) => void) | null;
1768
+ onSearchOpen: ((event: TsEventPayload) => void) | null;
1769
+ onSearchClose: ((event: TsEventPayload) => void) | null;
1770
+ onChange: ((event: TsEventPayload) => void) | null;
1771
+ onRestore: ((event: TsEventPayload) => void) | null;
1772
+ onExpand: ((event: TsEventPayload) => void) | null;
1773
+ onCollapse: ((event: TsEventPayload) => void) | null;
1774
+ onError: ((event: TsEventPayload) => void) | null;
1775
+ onKeydown: ((event: TsEventPayload) => void) | null;
1776
+ onToolbar: ((event: TsEventPayload) => void) | null;
1777
+ onColumnOnOff: ((event: TsEventPayload) => void) | null;
1778
+ onCopy: ((event: TsEventPayload) => void) | null;
1779
+ onPaste: ((event: TsEventPayload) => void) | null;
1780
+ onSelectionExtend: ((event: TsEventPayload) => void) | null;
1781
+ onEditField: ((event: TsEventPayload) => void) | null;
1782
+ onRender: ((event: TsEventPayload) => void) | null;
1783
+ onRefresh: ((event: TsEventPayload) => void) | null;
1784
+ onReload: ((event: TsEventPayload) => void) | null;
1785
+ onResize: ((event: TsEventPayload) => void) | null;
1786
+ onDestroy: ((event: TsEventPayload) => void) | null;
1787
+ onStateSave: ((event: TsEventPayload) => void) | null;
1788
+ onStateRestore: ((event: TsEventPayload) => void) | null;
1789
+ onFocus: ((event: TsEventPayload) => void) | null;
1790
+ onBlur: ((event: TsEventPayload) => void) | null;
1791
+ onReorderRow: ((event: TsEventPayload) => void) | null;
1792
+ onSearchSave: ((event: TsEventPayload) => void) | null;
1793
+ onSearchRemove: ((event: TsEventPayload) => void) | null;
1794
+ onSearchSelect: ((event: TsEventPayload) => void) | null;
1795
+ onColumnSelect: ((event: TsEventPayload) => void) | null;
1796
+ onColumnDragStart: ((event: TsEventPayload) => void) | null;
1797
+ onColumnDragEnd: ((event: TsEventPayload) => void) | null;
1798
+ onResizerDblClick: ((event: TsEventPayload) => void) | null;
1799
+ onMouseEnter: ((event: TsEventPayload) => void) | null;
1800
+ onMouseLeave: ((event: TsEventPayload) => void) | null;
1777
1801
  constructor(options: Record<string, any>);
1778
1802
  add(record: TsGridRecord | TsGridRecord[], first?: boolean): number;
1779
1803
  find(obj?: Record<string, any>, returnIndex?: boolean, displayedOnly?: boolean): (string | number)[];
@@ -1801,13 +1825,13 @@ declare class TsGrid extends TsBase {
1801
1825
  hideColumn(...fields: string[]): number;
1802
1826
  /** Add one or more search fields. If `search` is omitted, `before` is treated as the search(es) to append. */
1803
1827
  addSearch(before: any, search?: any): number;
1804
- removeSearch(...fields: string[]): number;
1828
+ removeSearch(...fields: string[]): any;
1805
1829
  getSearch(): string[];
1806
1830
  getSearch(field: string, returnIndex: true): number | null;
1807
1831
  getSearch(field: string, returnIndex?: false): TsGridSearch | null;
1808
- toggleSearch(...fields: string[]): number;
1809
- showSearch(...fields: string[]): number;
1810
- hideSearch(...fields: string[]): number;
1832
+ toggleSearch(...fields: string[]): any;
1833
+ showSearch(...fields: string[]): any;
1834
+ hideSearch(...fields: string[]): any;
1811
1835
  getSearchData(field: string): Record<string, any> | null;
1812
1836
  localSort(silent?: boolean, noResetRefresh?: boolean): number | undefined;
1813
1837
  localSearch(silent?: boolean): number | undefined;
@@ -1821,7 +1845,7 @@ declare class TsGrid extends TsBase {
1821
1845
  addRange(rangesInput: TsGridRange | TsGridRange[] | string | Record<string, any>): number;
1822
1846
  removeRange(...names: string[]): number;
1823
1847
  refreshRanges(): number | undefined;
1824
- select(...selectArgs: any[]): number | undefined;
1848
+ select(...selectArgs: any[]): any;
1825
1849
  unselect(...unselectArgs: any[]): number;
1826
1850
  compareSelection(newSel: any[]): {
1827
1851
  select: any[];
@@ -1852,17 +1876,17 @@ declare class TsGrid extends TsBase {
1852
1876
  * compat with the v2.0 API and for callers that genuinely handle both modes.
1853
1877
  */
1854
1878
  getSelection(returnIndex?: boolean): RecId[] | number[] | TsGridCellSelection[];
1855
- search(field?: any, value?: any): void;
1856
- searchOpen(options?: any): void;
1879
+ search(field?: any, value?: any): any;
1880
+ searchOpen(options?: any): any;
1857
1881
  searchClose(): void;
1858
- searchFieldTooltip(ind: any, sd_ind: any, el: any): void;
1859
- searchSuggest(imediate?: boolean, forceHide?: boolean, anchor?: HTMLElement | Element): void;
1882
+ searchFieldTooltip(ind: any, sd_ind: any, el: any): any;
1883
+ searchSuggest(imediate?: boolean, forceHide?: boolean, anchor?: HTMLElement | Element): any;
1860
1884
  searchSave(): void;
1861
1885
  cache(type: any): any;
1862
- cacheSave(type: any, value: any): boolean;
1886
+ cacheSave(type: any, value: any): any;
1863
1887
  searchReset(noReload?: boolean): void;
1864
1888
  searchShowFields(forceHide?: boolean): void;
1865
- searchInitInput(field: string, _value?: any): void;
1889
+ searchInitInput(field: string, _value?: any): any;
1866
1890
  clear(noRefresh?: boolean): void;
1867
1891
  reset(noRefresh?: boolean): void;
1868
1892
  skip(offset: any, callBack?: any): void;
@@ -1874,14 +1898,14 @@ declare class TsGrid extends TsBase {
1874
1898
  getChanges(recordsBase?: TsGridRecord[]): Record<string, any>[];
1875
1899
  mergeChanges(): void;
1876
1900
  save(callBack?: (data: any) => void): void;
1877
- editField(recid: string | number, column: number, value: any, event?: any): void;
1878
- editChange(input?: any, index?: any, column?: any, event?: any): void;
1879
- editDone(index?: any, column?: any, event?: any): void;
1901
+ editField(recid: string | number, column: number, value: any, event?: any): any;
1902
+ editChange(input?: any, index?: any, column?: any, event?: any): any;
1903
+ editDone(index?: any, column?: any, event?: any): any;
1880
1904
  'delete'(force?: boolean): void;
1881
1905
  click(recid: string | number | {
1882
1906
  recid: string | number;
1883
1907
  column?: number;
1884
- } | any, event?: MouseEvent | any): void;
1908
+ } | any, event?: MouseEvent | any): any;
1885
1909
  columnClick(field: string, event?: MouseEvent | any): void;
1886
1910
  columnDblClick(field: any, event: any): void;
1887
1911
  columnContextMenu(field: any, event: any): void;
@@ -1895,7 +1919,7 @@ declare class TsGrid extends TsBase {
1895
1919
  dblClick(recid: string | number | {
1896
1920
  recid: string | number;
1897
1921
  column?: number;
1898
- } | any, event?: MouseEvent | any): void;
1922
+ } | any, event?: MouseEvent | any): any;
1899
1923
  showContextMenu(event: MouseEvent | any, options: {
1900
1924
  recid?: string | number;
1901
1925
  index?: number;
@@ -1942,9 +1966,9 @@ declare class TsGrid extends TsBase {
1942
1966
  resizeBoxes(): void;
1943
1967
  resizeRecords(): void;
1944
1968
  getSearchesHTML(): string;
1945
- getOperators(type: any, opers: any): string;
1946
- initOperator(ind: any): void;
1947
- initSearchLists(changedField?: any): void;
1969
+ getOperators(type: any, opers: any): any;
1970
+ initOperator(ind: any): any;
1971
+ initSearchLists(changedField?: any): any;
1948
1972
  initSearches(): void;
1949
1973
  getColumnsHTML(): string[];
1950
1974
  getColumnCellHTML(i: any): string;
@@ -2071,21 +2095,21 @@ declare class TsForm extends TsBase {
2071
2095
  errorsShown?: boolean;
2072
2096
  observeResize?: ResizeObserver;
2073
2097
  };
2074
- onRequest: ((event: CustomEvent) => void) | null;
2075
- onLoad: ((event: CustomEvent) => void) | null;
2076
- onValidate: ((event: CustomEvent) => void) | null;
2077
- onSubmit: ((event: CustomEvent) => void) | null;
2078
- onProgress: ((event: CustomEvent) => void) | null;
2079
- onSave: ((event: CustomEvent) => void) | null;
2080
- onChange: ((event: CustomEvent) => void) | null;
2081
- onInput: ((event: CustomEvent) => void) | null;
2082
- onRender: ((event: CustomEvent) => void) | null;
2083
- onRefresh: ((event: CustomEvent) => void) | null;
2084
- onResize: ((event: CustomEvent) => void) | null;
2085
- onDestroy: ((event: CustomEvent) => void) | null;
2086
- onAction: ((event: CustomEvent) => void) | null;
2087
- onToolbar: ((event: CustomEvent) => void) | null;
2088
- onError: ((event: CustomEvent) => void) | null;
2098
+ onRequest: ((event: TsEventPayload) => void) | null;
2099
+ onLoad: ((event: TsEventPayload) => void) | null;
2100
+ onValidate: ((event: TsEventPayload) => void) | null;
2101
+ onSubmit: ((event: TsEventPayload) => void) | null;
2102
+ onProgress: ((event: TsEventPayload) => void) | null;
2103
+ onSave: ((event: TsEventPayload) => void) | null;
2104
+ onChange: ((event: TsEventPayload) => void) | null;
2105
+ onInput: ((event: TsEventPayload) => void) | null;
2106
+ onRender: ((event: TsEventPayload) => void) | null;
2107
+ onRefresh: ((event: TsEventPayload) => void) | null;
2108
+ onResize: ((event: TsEventPayload) => void) | null;
2109
+ onDestroy: ((event: TsEventPayload) => void) | null;
2110
+ onAction: ((event: TsEventPayload) => void) | null;
2111
+ onToolbar: ((event: TsEventPayload) => void) | null;
2112
+ onError: ((event: TsEventPayload) => void) | null;
2089
2113
  msgRefresh: string;
2090
2114
  msgSaving: string;
2091
2115
  msgServerError: string;