@orkestrel/table 0.0.8 → 0.0.9

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.
@@ -0,0 +1,902 @@
1
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
2
+ import type { EmitterHooks } from '@orkestrel/emitter';
3
+ import type { EmitterInterface } from '@orkestrel/emitter';
4
+ import type { JSONRecord } from '@orkestrel/contract';
5
+
6
+ /**
7
+ * Keeps the rows whose cell falls between `minimum` and `maximum`, both included, compared the
8
+ * way the column compares.
9
+ *
10
+ * @remarks
11
+ * A `text` column holding ISO strings therefore takes a pair of ISO strings and reads as a date
12
+ * range.
13
+ */
14
+ declare interface BetweenFilter {
15
+ readonly column: string;
16
+ readonly operator: 'between';
17
+ readonly minimum: string | number;
18
+ readonly maximum: string | number;
19
+ }
20
+
21
+ /**
22
+ * Represents a column drawn from a declared list, compared by the order that list declares. It
23
+ * requires `choices`.
24
+ *
25
+ * @remarks
26
+ * A cell holding a value the list does not offer is refused at admission.
27
+ */
28
+ declare interface ChoiceColumn extends ColumnBase {
29
+ readonly cell: 'choice';
30
+ readonly choices: readonly ColumnChoice[];
31
+ }
32
+
33
+ /**
34
+ * Describes what every column carries, whatever its cells hold — the name a row's cell uses, the
35
+ * text a reader sees, whether a host draws the column, and the metadata a host attaches to it.
36
+ *
37
+ * @remarks
38
+ * `key` names the column, and it is the name a row uses for that column's cell. `label` is the
39
+ * heading a reader sees and `help` explains the column.
40
+ *
41
+ * `hidden` declares the column out of the presentation. It is still sorted, still filtered, and
42
+ * still serialized, because hiding is what a host draws rather than what the table holds.
43
+ *
44
+ * There is no `sortable` and no `filterable`. Every declared column sorts and filters; whether a
45
+ * heading offers either is the host's decision.
46
+ *
47
+ * `meta` is a bounded JSON carrier for whatever the schema declines to model. The table never
48
+ * reads it, no comparison sees it, and it round-trips verbatim. This package defines no key in
49
+ * it, so every key belongs to the host: an alignment, a format, a pixel width.
50
+ */
51
+ declare interface ColumnBase {
52
+ readonly key: string;
53
+ readonly label?: string;
54
+ readonly help?: string;
55
+ readonly hidden?: boolean;
56
+ readonly meta?: JSONRecord;
57
+ }
58
+
59
+ /**
60
+ * Represents one value a `choice` column offers — `value` is stored, `label` is read, and `help`
61
+ * explains.
62
+ *
63
+ * @remarks
64
+ * The order a column declares its choices in is the order that column sorts by, which is what
65
+ * lets a status column sort draft before live before archived rather than alphabetically.
66
+ */
67
+ declare interface ColumnChoice {
68
+ readonly value: string;
69
+ readonly label: string;
70
+ readonly help?: string;
71
+ }
72
+
73
+ /** Keeps the rows whose cell holds this `text` somewhere inside it. */
74
+ declare interface ContainsFilter {
75
+ readonly column: string;
76
+ readonly operator: 'contains';
77
+ readonly text: string;
78
+ }
79
+
80
+ /** Creates a native table binding with one retained row owner.
81
+ * @param element - The native table to bind.
82
+ * @param document - The borrowed core document.
83
+ * @param options - Renderers, scoped controls, and listeners.
84
+ * @returns The native binding.
85
+ */
86
+ export declare function createTableBinding(element: HTMLTableElement, document: TableInterface, options?: TableBindingOptions): TableBindingInterface;
87
+
88
+ /** Keeps the rows whose cell holds exactly this `value`. */
89
+ declare interface EqualsFilter {
90
+ readonly column: string;
91
+ readonly operator: 'equals';
92
+ readonly value: TableCell;
93
+ }
94
+
95
+ /**
96
+ * Manages the rows somebody has opened up.
97
+ *
98
+ * @remarks
99
+ * Expansion holds keys exactly as selection does, and what an opened row shows beside it is the
100
+ * host's to draw.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * table.expansion.toggle('7')
105
+ * table.expansion.keys.has('7') // true
106
+ * ```
107
+ */
108
+ declare interface ExpansionManagerInterface {
109
+ /** Holds the keys of the rows opened right now. */
110
+ readonly keys: ReadonlySet<TableKey>;
111
+ /** Opens every row the table holds, one row, or several. */
112
+ expand(): void;
113
+ /**
114
+ * Opens one row.
115
+ *
116
+ * @param key - The row's key.
117
+ * @returns True if the key named a row the table holds; false otherwise.
118
+ */
119
+ expand(key: TableKey): boolean;
120
+ /**
121
+ * Opens several rows.
122
+ *
123
+ * @param keys - The rows' keys.
124
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
125
+ * checked before any row opens.
126
+ */
127
+ expand(keys: readonly TableKey[]): boolean;
128
+ /**
129
+ * Closes every row, one row, or several. A known key that was not open still answers `true`.
130
+ */
131
+ clear(): void;
132
+ /**
133
+ * Closes one row.
134
+ *
135
+ * @param key - The row's key.
136
+ * @returns True if the key named a row the table holds, whether or not it was
137
+ * open; false otherwise.
138
+ */
139
+ clear(key: TableKey): boolean;
140
+ /**
141
+ * Closes several rows.
142
+ *
143
+ * @param keys - The rows' keys.
144
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
145
+ * checked before any row closes.
146
+ */
147
+ clear(keys: readonly TableKey[]): boolean;
148
+ /**
149
+ * Opens one row, or closes it when it is already open; over a list, turns each row around on
150
+ * its own.
151
+ *
152
+ * @param key - The row's key.
153
+ * @returns True if the key named a row the table holds; false otherwise.
154
+ */
155
+ toggle(key: TableKey): boolean;
156
+ /**
157
+ * Turns several rows around, each on its own.
158
+ *
159
+ * @param keys - The rows' keys.
160
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
161
+ * checked before any row turns.
162
+ */
163
+ toggle(keys: readonly TableKey[]): boolean;
164
+ }
165
+
166
+ /**
167
+ * Manages which rows a table keeps.
168
+ *
169
+ * @remarks
170
+ * The table holds at most one filter per column and keeps the rows every filter accepts.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * table.filter.set({ column: 'name', operator: 'contains', text: 'ad' })
175
+ * table.count // how many rows are left
176
+ * ```
177
+ */
178
+ declare interface FilterManagerInterface {
179
+ /**
180
+ * Finds one column's filter; `undefined` when nothing filters that column.
181
+ *
182
+ * @param column - The column's key.
183
+ * @returns The filter, or `undefined` when nothing filters that column.
184
+ */
185
+ filter(column: string): TableFilter | undefined;
186
+ /**
187
+ * Reads every filter the table keeps rows by, in the order they were set.
188
+ *
189
+ * @returns The filters the table keeps rows by.
190
+ */
191
+ filters(): readonly TableFilter[];
192
+ /**
193
+ * Filters one column or several. A filter for a column already filtered replaces it; every
194
+ * other one joins the end. An undeclared column raises `COLUMN`, and a filter the column does
195
+ * not admit raises `CELL`.
196
+ *
197
+ * @param filters - The filters to set. A filter for a column already filtered replaces that
198
+ * column's filter; every other one joins the end of the list.
199
+ * @throws A {@link TableError} coded `COLUMN` when a filter names a column the schema does not
200
+ * declare, and `CELL` when an operand is one the column cannot hold. Every filter is checked
201
+ * before any is set.
202
+ */
203
+ set(filters: readonly TableFilter[]): void;
204
+ /**
205
+ * Filters one column.
206
+ *
207
+ * @param filter - The filter to set.
208
+ * @throws A {@link TableError} coded `COLUMN` when the filter names a column the schema does
209
+ * not declare, and `CELL` when an operand is one the column cannot hold.
210
+ */
211
+ set(filter: TableFilter): void;
212
+ /**
213
+ * Stops filtering everything, one column, or several. An undeclared column returns `false` and
214
+ * stops nothing.
215
+ */
216
+ remove(): void;
217
+ /**
218
+ * Stops filtering one column.
219
+ *
220
+ * @param column - The column's key.
221
+ * @returns True if the schema declares that column; false otherwise.
222
+ */
223
+ remove(column: string): boolean;
224
+ /**
225
+ * Stops filtering several columns.
226
+ *
227
+ * @param columns - The columns' keys.
228
+ * @returns True if the schema declares every one of them; false otherwise. Every key is
229
+ * checked before any filter goes.
230
+ */
231
+ remove(columns: readonly string[]): boolean;
232
+ }
233
+
234
+ /** Represents a column of yes-or-no answers, compared false before true. */
235
+ declare interface FlagColumn extends ColumnBase {
236
+ readonly cell: 'flag';
237
+ }
238
+
239
+ /** Checks whether a caught value is a native table binding error.
240
+ * @param value - The caught value.
241
+ * @returns Whether the value is a binding error.
242
+ */
243
+ export declare function isTableBindingError(value: unknown): value is TableBindingError;
244
+
245
+ /** Represents a column of numbers, compared by magnitude. */
246
+ declare interface NumberColumn extends ColumnBase {
247
+ readonly cell: 'number';
248
+ }
249
+
250
+ /**
251
+ * Manages which stretch of the filtered rows the view shows.
252
+ *
253
+ * @remarks
254
+ * `page` is the state, counted from one. `offset` and `count` are worked out from it and from the
255
+ * rows the filter admits, so nothing here can drift out of step with what the table holds. A page
256
+ * beyond the last one clamps to the last one.
257
+ *
258
+ * `offset` counts the rows skipped, from zero, which is what a database query asks for.
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * table.pagination.resize(10)
263
+ * table.pagination.move(3)
264
+ * table.pagination.offset // 20
265
+ * ```
266
+ */
267
+ declare interface PaginationManagerInterface {
268
+ /** Holds the page the view shows, counted from one, and `1` when the table is not paged. */
269
+ readonly page: number;
270
+ /** Holds the number of rows one page shows, or `undefined` when the table is not paged. */
271
+ readonly limit: number | undefined;
272
+ /** Holds the number of rows the view skips before the page it shows, counted from zero. */
273
+ readonly offset: number;
274
+ /** Counts the pages the rows admitted by the filter fill, and `1` when the table is not paged. */
275
+ readonly count: number;
276
+ /**
277
+ * Shows another page, counted from one and clamped to the pages that exist.
278
+ *
279
+ * @param page - The page to show, counted from one and clamped to the pages that exist. `NaN`
280
+ * shows the first page.
281
+ */
282
+ move(page: number): void;
283
+ /**
284
+ * Sets how many rows a page holds, keeping the first row the view was showing. Leave the
285
+ * argument out to stop paging.
286
+ *
287
+ * @remarks
288
+ * The page moves to wherever that first row now falls.
289
+ *
290
+ * @param limit - How many rows a page holds. Leave it out to stop paging, and the view shows
291
+ * every row the filter admits.
292
+ */
293
+ resize(limit?: number): void;
294
+ }
295
+
296
+ /** Reads declared header metadata and explicit row keys into a validated core projection.
297
+ * @param element - A native table with data-table-key naming its identity column.
298
+ * @returns The schema and rows, validated together before any mutation.
299
+ * @throws A binding error when metadata, identities, or cells are malformed.
300
+ * @example
301
+ * ```ts
302
+ * import { createTable } from '@orkestrel/table'
303
+ * import { readTable } from '@orkestrel/table/browser'
304
+ * const element = document.createElement('table')
305
+ * element.setAttribute('data-table-key', 'id')
306
+ * element.innerHTML = '<thead><tr><th data-table-column="id" data-table-cell="text">Reference</th></tr></thead><tbody></tbody>'
307
+ * const projection = readTable(element)
308
+ * const table = createTable(projection.schema, { rows: projection.rows })
309
+ * ```
310
+ */
311
+ export declare function readTable(element: HTMLTableElement): TableProjection;
312
+
313
+ /** Reads explicit keys and declared direct cells against a core schema.
314
+ * @param schema - The declared columns and identity column.
315
+ * @param elements - Data rows belonging to one table, including retained detached rows.
316
+ * @returns Validated rows in the supplied order.
317
+ * @throws A binding error for duplicate keys, undeclared cells, or malformed values.
318
+ */
319
+ export declare function readTableRows(schema: TableSchema, elements: readonly HTMLTableRowElement[]): readonly TableRow[];
320
+
321
+ /** Reads and validates explicit native header metadata.
322
+ * @param element - The table declaring its identity column and cell kinds.
323
+ * @returns The core schema described by the native headers.
324
+ */
325
+ export declare function readTableSchema(element: HTMLTableElement): TableSchema;
326
+
327
+ /**
328
+ * Manages the rows a table holds, in the order it holds them.
329
+ *
330
+ * @remarks
331
+ * This order is the table's own, and it is what the view shows when no sort term separates two
332
+ * rows. Sorting reads it and never rewrites it.
333
+ *
334
+ * @example
335
+ * ```ts
336
+ * table.rows.add({ id: '7', name: 'Ada', age: 36 })
337
+ * table.rows.update({ id: '7', age: 37 })
338
+ * ```
339
+ */
340
+ declare interface RowManagerInterface {
341
+ /**
342
+ * Finds one row by key; `undefined` when the table holds no such key.
343
+ *
344
+ * @param key - The row's key.
345
+ * @returns The row, or `undefined` when the table holds no such key.
346
+ */
347
+ row(key: TableKey): TableRow | undefined;
348
+ /**
349
+ * Reads every row the table holds, in its own order — unfiltered, unsorted, and unpaged.
350
+ *
351
+ * @returns The rows, in the order the table holds them.
352
+ */
353
+ rows(): readonly TableRow[];
354
+ /**
355
+ * Takes in one row or several, appending them in the order given. Every row is checked before
356
+ * any is admitted.
357
+ *
358
+ * @param rows - The rows to admit.
359
+ * @throws A {@link TableError} coded `KEY` when a row's key is missing, unusable, already
360
+ * taken, or repeated inside the batch, and `CELL` when a cell is one its column cannot hold.
361
+ * Every row is checked before any is admitted, so one refusal admits none of them.
362
+ */
363
+ add(rows: readonly TableRow[]): void;
364
+ /**
365
+ * Takes in one row, appending it.
366
+ *
367
+ * @param row - The row to admit.
368
+ * @throws A {@link TableError} coded `KEY` when the row's key is missing, unusable, or already
369
+ * taken, and `CELL` when a cell is one its column cannot hold.
370
+ */
371
+ add(row: TableRow): void;
372
+ /**
373
+ * Writes over one row or several, each found by the key it carries. The cells given replace;
374
+ * the cells left out stay.
375
+ *
376
+ * @param rows - The rows to write, each carrying the key of the row it writes over.
377
+ * @returns True if every key named a row the table holds; false otherwise.
378
+ * @throws A {@link TableError} coded `CELL` when a cell is one its column cannot hold. Every
379
+ * row is checked before any is written, so one refusal writes none of them.
380
+ */
381
+ update(rows: readonly TableRow[]): boolean;
382
+ /**
383
+ * Writes over one row, found by the key it carries.
384
+ *
385
+ * @remarks
386
+ * The cells given replace the cells held; the cells left out stay as they are. A row's key
387
+ * therefore cannot move, because a different key names a different row.
388
+ *
389
+ * @param row - The cells to write, carrying the key of the row they belong to.
390
+ * @returns True if the key named a row the table holds; false otherwise.
391
+ * @throws A {@link TableError} coded `CELL` when a cell is one its column cannot hold.
392
+ */
393
+ update(row: TableRow): boolean;
394
+ /**
395
+ * Replaces complete rows under existing keys, removing omitted cells without moving identities.
396
+ * @param rows - Whole rows to replace; every key must already exist.
397
+ * @returns Whether every key exists. A missing key leaves the batch unchanged.
398
+ * @throws A table error when any row is invalid, before any row is written.
399
+ */
400
+ replace(rows: readonly TableRow[]): boolean;
401
+ /**
402
+ * Replaces one complete row while retaining its position, selection, and expansion.
403
+ * @param row - The whole replacement, including its existing identity.
404
+ * @returns Whether the key exists.
405
+ */
406
+ replace(row: TableRow): boolean;
407
+ /**
408
+ * Moves one row to another place in the table's own order, counted from zero and clamped to the
409
+ * rows that exist.
410
+ *
411
+ * @param key - The row's key.
412
+ * @param index - Where to put it, counted from zero and clamped to the rows that exist. `NaN`
413
+ * puts the row first.
414
+ * @returns True if the key named a row the table holds; false otherwise.
415
+ */
416
+ move(key: TableKey, index: number): boolean;
417
+ /**
418
+ * Takes out every row, one row, or several. Selection and expansion drop the keys of the rows
419
+ * that went.
420
+ */
421
+ remove(): void;
422
+ /**
423
+ * Takes out one row.
424
+ *
425
+ * @param key - The row's key.
426
+ * @returns True if the key named a row the table holds; false otherwise.
427
+ */
428
+ remove(key: TableKey): boolean;
429
+ /**
430
+ * Takes out several rows.
431
+ *
432
+ * @param keys - The rows' keys.
433
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
434
+ * checked before any row goes, so one unknown key leaves the whole call undone.
435
+ */
436
+ remove(keys: readonly TableKey[]): boolean;
437
+ }
438
+
439
+ /**
440
+ * Manages the rows somebody has picked.
441
+ *
442
+ * @remarks
443
+ * Selection holds keys, never rows or positions, so a pick survives a sort, a filter, and a page
444
+ * turn. A row that leaves the table takes its key out of the selection with it.
445
+ *
446
+ * @example
447
+ * ```ts
448
+ * table.selection.toggle('7')
449
+ * table.selection.keys.has('7') // true
450
+ * ```
451
+ */
452
+ declare interface SelectionManagerInterface {
453
+ /** Holds the keys of the rows picked right now. */
454
+ readonly keys: ReadonlySet<TableKey>;
455
+ /**
456
+ * Picks every row the table holds, one row, or several. Every row, not every visible one.
457
+ *
458
+ * @remarks
459
+ * A host picking one page hands that page's keys over instead.
460
+ */
461
+ select(): void;
462
+ /**
463
+ * Picks one row.
464
+ *
465
+ * @param key - The row's key.
466
+ * @returns True if the key named a row the table holds; false otherwise.
467
+ */
468
+ select(key: TableKey): boolean;
469
+ /**
470
+ * Picks several rows.
471
+ *
472
+ * @param keys - The rows' keys.
473
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
474
+ * checked before any row is picked.
475
+ */
476
+ select(keys: readonly TableKey[]): boolean;
477
+ /**
478
+ * Drops every pick, one pick, or several. A known key that was not picked still answers `true`.
479
+ */
480
+ clear(): void;
481
+ /**
482
+ * Drops one pick.
483
+ *
484
+ * @param key - The row's key.
485
+ * @returns True if the key named a row the table holds, whether or not it was
486
+ * picked; false otherwise.
487
+ */
488
+ clear(key: TableKey): boolean;
489
+ /**
490
+ * Drops several picks.
491
+ *
492
+ * @param keys - The rows' keys.
493
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
494
+ * checked before any pick is dropped.
495
+ */
496
+ clear(keys: readonly TableKey[]): boolean;
497
+ /**
498
+ * Picks one row, or drops it when it is already picked; over a list, turns each row around on
499
+ * its own.
500
+ *
501
+ * @param key - The row's key.
502
+ * @returns True if the key named a row the table holds; false otherwise.
503
+ */
504
+ toggle(key: TableKey): boolean;
505
+ /**
506
+ * Turns several rows around, each on its own.
507
+ *
508
+ * @param keys - The rows' keys.
509
+ * @returns True if every key named a row the table holds; false otherwise. Every key is
510
+ * checked before any row turns.
511
+ */
512
+ toggle(keys: readonly TableKey[]): boolean;
513
+ }
514
+
515
+ /**
516
+ * Manages the order a table reads its rows in.
517
+ *
518
+ * @remarks
519
+ * The table holds one term per column and applies them in the order they were set. Which
520
+ * direction a heading offers next is the host's decision, so there is no cycling verb here: read
521
+ * the column's term, decide, then set or remove it.
522
+ *
523
+ * @example
524
+ * ```ts
525
+ * table.sort.set({ column: 'age', direction: 'descending' })
526
+ * table.sort.orders() // [{ column: 'age', direction: 'descending' }]
527
+ * ```
528
+ */
529
+ declare interface SortManagerInterface {
530
+ /**
531
+ * Finds one column's term; `undefined` when nothing sorts that column.
532
+ *
533
+ * @param column - The column's key.
534
+ * @returns The term, or `undefined` when nothing sorts that column.
535
+ */
536
+ order(column: string): TableOrder | undefined;
537
+ /**
538
+ * Reads every term the table sorts by, first to last, in the order they decide.
539
+ *
540
+ * @returns The terms the table sorts by.
541
+ */
542
+ orders(): readonly TableOrder[];
543
+ /**
544
+ * Sorts by one column or several. A term for a column already sorted replaces its direction in
545
+ * place; every other term joins the end. An undeclared column raises `COLUMN`.
546
+ *
547
+ * @param orders - The terms to set. A term for a column already sorted replaces that column's
548
+ * direction in place; every other term joins the end of the list.
549
+ * @throws A {@link TableError} coded `COLUMN` when a term names a column the schema does not
550
+ * declare. Every term is checked before any is set.
551
+ */
552
+ set(orders: readonly TableOrder[]): void;
553
+ /**
554
+ * Sorts by one column.
555
+ *
556
+ * @param order - The term to set.
557
+ * @throws A {@link TableError} coded `COLUMN` when the term names a column the schema does not
558
+ * declare.
559
+ */
560
+ set(order: TableOrder): void;
561
+ /**
562
+ * Stops sorting by everything, by one column, or by several. An undeclared column returns
563
+ * `false` and stops nothing.
564
+ */
565
+ remove(): void;
566
+ /**
567
+ * Stops sorting by one column.
568
+ *
569
+ * @param column - The column's key.
570
+ * @returns True if the schema declares that column; false otherwise.
571
+ */
572
+ remove(column: string): boolean;
573
+ /**
574
+ * Stops sorting by several columns.
575
+ *
576
+ * @param columns - The columns' keys.
577
+ * @returns True if the schema declares every one of them; false otherwise. Every key is
578
+ * checked before any term goes.
579
+ */
580
+ remove(columns: readonly string[]): boolean;
581
+ }
582
+
583
+ /** Retains keyed native rows while projecting every core table manager. */
584
+ export declare class TableBinding implements TableBindingInterface {
585
+ #private;
586
+ /** Creates a native binding over a borrowed document.
587
+ * @param element - The table whose body the binding owns.
588
+ * @param document - The core document retained by the caller.
589
+ * @param options - Row ownership, detail renderer, controls, and listeners.
590
+ */
591
+ constructor(element: HTMLTableElement, document: TableInterface, options?: TableBindingOptions);
592
+ get element(): HTMLTableElement;
593
+ get document(): TableInterface;
594
+ get destroyed(): boolean;
595
+ get emitter(): EmitterInterface<TableBindingEventMap>;
596
+ /** Reconciles native input and retries rendering against the current document. */
597
+ refresh(): void;
598
+ /** Releases native resources and restores authored state while retaining the core document. */
599
+ destroy(): void;
600
+ }
601
+
602
+ /** Represents a native table binding failure with a machine-readable code. */
603
+ export declare class TableBindingError extends Error {
604
+ readonly code: TableBindingErrorCode;
605
+ /** Creates a binding failure.
606
+ * @param code - The failed boundary.
607
+ * @param message - The explanation.
608
+ */
609
+ constructor(code: TableBindingErrorCode, message: string);
610
+ }
611
+
612
+ /** Names a native binding failure at its structure, rendering, or lifecycle boundary. */
613
+ export declare type TableBindingErrorCode = 'STRUCTURE';
614
+
615
+ /** Announces cancelable sorting, completed rendering, and failed DOM operations. */
616
+ export declare type TableBindingEventMap = {
617
+ readonly sort: readonly [event: CustomEvent<readonly TableOrder[]>];
618
+ readonly render: readonly [];
619
+ readonly error: readonly [error: unknown];
620
+ };
621
+
622
+ /** Binds native table elements to a borrowed core document. */
623
+ export declare interface TableBindingInterface {
624
+ readonly element: HTMLTableElement;
625
+ readonly document: TableInterface;
626
+ readonly destroyed: boolean;
627
+ readonly emitter: EmitterInterface<TableBindingEventMap>;
628
+ /** Reconciles and renders the document, retrying a failed renderer. */
629
+ refresh(): void;
630
+ /** Releases listeners and restores owned attributes without destroying the document. */
631
+ destroy(): void;
632
+ }
633
+
634
+ /** Configures row ownership, detail presentation, scoped controls, and event listeners.
635
+ * @remarks
636
+ * Supply row for model-owned values and an empty body. Omit it to enhance authored rows
637
+ * matching the supplied document. Each callback patches only the supplied row contents.
638
+ * Detail receives a generated row containing a spanning cell. Scope contains the table and
639
+ * its external page checkbox. The error option handles listener throws; on.error observes
640
+ * failed native reads and renders. Neither callback owns row placement or core teardown.
641
+ */
642
+ export declare interface TableBindingOptions {
643
+ readonly row?: TableRenderHandler;
644
+ readonly detail?: TableRenderHandler;
645
+ readonly scope?: HTMLElement;
646
+ readonly on?: EmitterHooks<TableBindingEventMap>;
647
+ readonly error?: EmitterErrorHandler;
648
+ }
649
+
650
+ /**
651
+ * Represents every value a cell can hold — a `string`, a `number`, or a `boolean`.
652
+ *
653
+ * @remarks
654
+ * The variant follows the column: `text` and `choice` hold a `string`, `number` holds a `number`,
655
+ * and `flag` holds a `boolean`. A cell nobody has filled has no key in its row, so absence is
656
+ * `undefined` and never `null` or an empty string.
657
+ */
658
+ declare type TableCell = string | number | boolean;
659
+
660
+ /**
661
+ * Represents any column a schema can declare — the union discriminated on `cell`.
662
+ *
663
+ * @remarks
664
+ * Narrowing on `cell` reaches each variant's own members.
665
+ *
666
+ * @example
667
+ * ```ts
668
+ * function choices(column: TableColumn): readonly ColumnChoice[] {
669
+ * return column.cell === 'choice' ? column.choices : []
670
+ * }
671
+ * ```
672
+ */
673
+ declare type TableColumn = TextColumn | NumberColumn | FlagColumn | ChoiceColumn;
674
+
675
+ /**
676
+ * Names which way a column sorts. A column nobody has sorted carries no term at all.
677
+ *
678
+ * @remarks
679
+ * No member of this union stands for unsorted; that state is the missing {@link TableOrder}.
680
+ */
681
+ declare type TableDirection = 'ascending' | 'descending';
682
+
683
+ /**
684
+ * Lists everything a table announces, mapping each event to the payload its listeners receive.
685
+ *
686
+ * @remarks
687
+ * Every event fires after the state it reports is committed, and only when something actually
688
+ * moved: a write that changes nothing announces nothing.
689
+ *
690
+ * `write` and `remove` carry one key and fire once per row, in the order the table wrote or
691
+ * removed them. A listener that wants the row reads it back.
692
+ *
693
+ * `sort` and `filter` carry the whole axis as it now stands, and `select` and `expand` carry the
694
+ * whole key set. Each payload is owned by the listener, so nothing it holds moves underneath it.
695
+ *
696
+ * `paginate` carries the page the table now shows, and fires whenever the paged window moves,
697
+ * including a clamp and a change of page size.
698
+ *
699
+ * `clear` is a signal, and it is the whole announcement of that reset: a clear emits no `remove`,
700
+ * no `select`, and no `paginate` beside it.
701
+ */
702
+ declare type TableEventMap = {
703
+ readonly write: readonly [key: TableKey];
704
+ readonly remove: readonly [key: TableKey];
705
+ readonly sort: readonly [orders: readonly TableOrder[]];
706
+ readonly filter: readonly [filters: readonly TableFilter[]];
707
+ readonly select: readonly [keys: ReadonlySet<TableKey>];
708
+ readonly expand: readonly [keys: ReadonlySet<TableKey>];
709
+ readonly paginate: readonly [page: number];
710
+ readonly clear: readonly [];
711
+ };
712
+
713
+ /**
714
+ * Represents any filter a table can hold — the union discriminated on `operator`.
715
+ *
716
+ * @remarks
717
+ * Each operator carries only the operands it uses, so a `between` missing a bound cannot be
718
+ * written down.
719
+ *
720
+ * A table holds at most one filter per column and keeps every row all of them accept. There is no
721
+ * either-or composition in this version.
722
+ *
723
+ * @example
724
+ * ```ts
725
+ * const filter: TableFilter = { column: 'age', operator: 'between', minimum: 30, maximum: 40 }
726
+ * ```
727
+ */
728
+ declare type TableFilter = ContainsFilter | BetweenFilter | EqualsFilter;
729
+
730
+ /**
731
+ * Represents a table: what it declares, the rows it holds, and the lens it reads them through.
732
+ *
733
+ * @remarks
734
+ * The table owns values, not pixels. It renders nothing, reads no document, and names no host
735
+ * type, so one table serves a browser, a terminal, a report, and an export equally.
736
+ *
737
+ * One manager holds each axis that moves: `rows`, `sort`, `filter`, `selection`, `expansion`, and
738
+ * `pagination`. Nothing else is stored. `view` and `count` are worked out when they are read, so no
739
+ * second copy of the answer can go stale.
740
+ *
741
+ * A write validates all of itself before any of it lands, and announces itself once it has.
742
+ *
743
+ * @example
744
+ * ```ts
745
+ * table.filter.set({ column: 'name', operator: 'contains', text: 'ad' })
746
+ * table.sort.set({ column: 'age', direction: 'descending' })
747
+ * table.view // the rows to draw now: filtered, sorted, paged
748
+ * ```
749
+ */
750
+ declare interface TableInterface {
751
+ /** Holds the table's event emitter. */
752
+ readonly emitter: EmitterInterface<TableEventMap>;
753
+ /** Holds what this table declares. */
754
+ readonly schema: TableSchema;
755
+ /** Manages the rows the table holds. */
756
+ readonly rows: RowManagerInterface;
757
+ /** Manages the order the table reads them in. */
758
+ readonly sort: SortManagerInterface;
759
+ /** Manages which of them the table keeps. */
760
+ readonly filter: FilterManagerInterface;
761
+ /** Manages the ones somebody has picked. */
762
+ readonly selection: SelectionManagerInterface;
763
+ /** Manages the ones somebody has opened up. */
764
+ readonly expansion: ExpansionManagerInterface;
765
+ /** Manages which stretch of them the view shows. */
766
+ readonly pagination: PaginationManagerInterface;
767
+ /**
768
+ * Returns the rows to draw right now: filtered, then sorted, then paged.
769
+ *
770
+ * @remarks
771
+ * It is worked out on every read and never stored, so it is right the instant anything moves.
772
+ */
773
+ readonly view: readonly TableRow[];
774
+ /** Counts the rows the filter admits, before the page narrows them. */
775
+ readonly count: number;
776
+ /** Reports whether the table has been torn down. */
777
+ readonly destroyed: boolean;
778
+ /**
779
+ * Puts the table back the way it opened, holding nothing. Rows, sort, filter, selection,
780
+ * expansion, and the page all reset.
781
+ *
782
+ * @remarks
783
+ * The table emits `clear` and nothing else, so a reset of ten thousand rows is one
784
+ * announcement.
785
+ */
786
+ clear(): void;
787
+ /**
788
+ * Tears the table down. Idempotent; afterwards every write raises `DESTROYED` and every getter
789
+ * still answers.
790
+ *
791
+ * @remarks
792
+ * The write throws a {@link TableError} carrying that code, and what a getter answers is what
793
+ * the table last held, so a host can read its way out of teardown without catching anything.
794
+ */
795
+ destroy(): void;
796
+ }
797
+
798
+ /**
799
+ * Represents a row's identity — a `string`, carried in the cell the schema's `key` names.
800
+ *
801
+ * @remarks
802
+ * The identity must be non-empty. A column's own identifier is a plain `string`; this names a row.
803
+ * Selection and expansion hold these keys and nothing else, so a row keeps its selection through a
804
+ * re-sort.
805
+ *
806
+ * @example
807
+ * ```ts
808
+ * const key: TableKey = '7'
809
+ * ```
810
+ */
811
+ declare type TableKey = string;
812
+
813
+ /**
814
+ * Represents one column's place in the sort — the `column` and its `direction`. The list is read
815
+ * left to right.
816
+ *
817
+ * @remarks
818
+ * The first term decides, and each later term breaks the tie the terms before it left. Rows no
819
+ * term separates keep the order the table holds them in.
820
+ *
821
+ * @example
822
+ * ```ts
823
+ * const order: TableOrder = { column: 'age', direction: 'descending' }
824
+ * ```
825
+ */
826
+ declare interface TableOrder {
827
+ readonly column: string;
828
+ readonly direction: TableDirection;
829
+ }
830
+
831
+ /** Holds a validated native table projection for constructing a core document. */
832
+ export declare interface TableProjection {
833
+ readonly schema: TableSchema;
834
+ readonly rows: readonly TableRow[];
835
+ }
836
+
837
+ /** Patches the contents of a retained row without moving or replacing that row.
838
+ * @param element - The binding-owned row; a detail row already contains its spanning cell.
839
+ * @param row - The core value to present.
840
+ */
841
+ export declare type TableRenderHandler = (element: HTMLTableRowElement, row: TableRow) => void;
842
+
843
+ /**
844
+ * Represents one row, keyed by column. A column nobody has filled has no key here.
845
+ *
846
+ * @remarks
847
+ * A row carries no key the schema does not declare, and the table clones and freezes it at
848
+ * admission, so nothing a caller holds afterwards can move a stored row.
849
+ *
850
+ * @example
851
+ * ```ts
852
+ * const row: TableRow = { id: '7', name: 'Ada', age: 36, active: true }
853
+ * ```
854
+ */
855
+ declare type TableRow = Readonly<Record<string, TableCell>>;
856
+
857
+ /**
858
+ * Holds everything a table declares about itself — how the table is described, which column
859
+ * carries row identity, and the columns it declares, in the order it declares them.
860
+ *
861
+ * @remarks
862
+ * The schema is data. It carries no function, so all of it crosses a wire and nothing is dropped
863
+ * on the way.
864
+ *
865
+ * `columns` is the schema's column list, and the order it declares is the order a host presents.
866
+ * `key` names the column whose cells carry row identity; it is required, it must name a declared
867
+ * column, and the table refuses a row whose cell there is missing, empty, or not a string. There
868
+ * is no default column, no positional fallback, and no key generation: an index is a position,
869
+ * and a position is not an identity.
870
+ *
871
+ * `name`, `label`, and `help` describe the table itself.
872
+ *
873
+ * @example
874
+ * ```ts
875
+ * const schema: TableSchema = {
876
+ * label: 'People',
877
+ * key: 'id',
878
+ * columns: [
879
+ * { cell: 'text', key: 'id', label: 'Reference' },
880
+ * { cell: 'text', key: 'name', label: 'Name' },
881
+ * { cell: 'number', key: 'age', label: 'Age' },
882
+ * ],
883
+ * }
884
+ * ```
885
+ */
886
+ declare interface TableSchema {
887
+ readonly name?: string;
888
+ readonly label?: string;
889
+ readonly help?: string;
890
+ readonly key: string;
891
+ readonly columns: readonly TableColumn[];
892
+ }
893
+
894
+ /**
895
+ * Represents a column of text, compared lexically. Carries a date, a time, and a timestamp as ISO
896
+ * strings.
897
+ */
898
+ declare interface TextColumn extends ColumnBase {
899
+ readonly cell: 'text';
900
+ }
901
+
902
+ export { }