@timlassiter11/yatl 0.2.2 → 0.3.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.
@@ -1,2 +1,2 @@
1
- .data-table{--dt-header-sorter-width: 1ch;--dt-header-resizer-width: 10px;--dt-header-drop-color: rgba(255, 255, 255, .1);position:relative;white-space:nowrap;overflow:auto;width:100%;table-layout:fixed!important}.dt-headers{position:sticky;top:0;z-index:1}.dt-headers th{overflow:hidden;box-sizing:border-box}.dt-headers .dt-header-content{position:relative}.dt-sortable .dt-header-content{cursor:pointer}.dt-header-title-wrapper{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;overflow:hidden}.dt-sort-icon{position:relative;width:var(--dt-header-sorter-width);align-self:stretch;padding:0 12px;overflow:hidden;flex-shrink:0}.dt-sort-icon:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dt-sortable.dt-descending .dt-sort-icon:after{content:"\2193"}.dt-sortable.dt-ascending .dt-sort-icon:after{content:"\2191"}.dt-resizer{position:absolute;top:0;right:calc((var(--dt-header-resizer-width) / 2) * -1);height:100%;width:var(--dt-header-resizer-width);cursor:ew-resize;z-index:2}.dt-resizer:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1px;height:60%;background-color:currentColor}.dt-headers>tr>th.dt-drag-over,.dt-headers>tr>th:has(.dt-drag-over){background-color:var(--dt-header-drop-color)}.data-table>tbody>tr>td,.dt-header-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.dt-empty{text-align:center;pointer-events:none}.dt-scroller{height:100%;overflow:auto}*:has(.data-table:has(.dt-virtual-scroll)){height:100%;min-height:0}
1
+ .data-table{--dt-header-sorter-width: 1ch;--dt-header-resizer-width: 10px;--dt-header-drop-color: rgba(255, 255, 255, .1);position:relative;white-space:nowrap;overflow:auto;width:100%;table-layout:fixed!important}.dt-headers{position:sticky;top:0;z-index:1}.dt-headers th{overflow:hidden;box-sizing:border-box}.dt-headers .dt-header-content{position:relative}.dt-sortable .dt-header-content{cursor:pointer}.dt-header-title-wrapper{display:flex;flex-direction:row;align-items:center;flex-wrap:nowrap;overflow:hidden}.dt-sort-icon{position:relative;width:var(--dt-header-sorter-width);align-self:stretch;padding:0 12px;overflow:hidden;flex-shrink:0}.dt-sort-icon:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.dt-sortable.dt-descending .dt-sort-icon:after{content:"\2191"}.dt-sortable.dt-ascending .dt-sort-icon:after{content:"\2193"}.dt-resizer{position:absolute;top:0;right:calc((var(--dt-header-resizer-width) / 2) * -1);height:100%;width:var(--dt-header-resizer-width);cursor:ew-resize;z-index:2}.dt-resizer:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:1px;height:60%;background-color:currentColor}.dt-headers>tr>th.dt-drag-over,.dt-headers>tr>th:has(.dt-drag-over){background-color:var(--dt-header-drop-color)}.data-table>tbody>tr>td,.dt-header-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.dt-empty{text-align:center;pointer-events:none}
2
2
  /*# sourceMappingURL=datatable.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/datatable.css"],"sourcesContent":[".data-table {\n --dt-header-sorter-width: 1ch;\n --dt-header-resizer-width: 10px;\n --dt-header-drop-color: rgba(255, 255, 255, 0.1);\n\n position: relative;\n white-space: nowrap;\n overflow: auto;\n width: 100%;\n table-layout: fixed !important;\n}\n\n.dt-headers {\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.dt-headers th {\n overflow: hidden;\n box-sizing: border-box;\n\n}\n\n.dt-headers .dt-header-content {\n position: relative;\n}\n\n.dt-sortable .dt-header-content {\n cursor: pointer;\n}\n\n.dt-header-title-wrapper {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex-wrap: nowrap;\n overflow: hidden;;\n}\n\n.dt-sort-icon {\n position: relative;\n width: var(--dt-header-sorter-width);\n align-self: stretch;\n padding: 0 12px;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.dt-sort-icon::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.dt-sortable.dt-descending .dt-sort-icon::after {\n content: '\\2193';\n}\n\n.dt-sortable.dt-ascending .dt-sort-icon::after {\n content: '\\2191';\n}\n\n.dt-resizer {\n position: absolute;\n top: 0;\n right: calc((var(--dt-header-resizer-width) / 2) * -1);\n height: 100%;\n width: var(--dt-header-resizer-width);\n cursor: ew-resize;\n z-index: 2;\n}\n\n.dt-resizer::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 1px;\n height: 60%;\n background-color: currentColor;\n}\n\n.dt-headers > tr > th.dt-drag-over,\n.dt-headers > tr > th:has(.dt-drag-over) {\n background-color: var(--dt-header-drop-color);\n}\n\n.data-table > tbody > tr > td,\n.dt-header-title {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.dt-empty {\n text-align: center;\n pointer-events: none;\n}\n\n.dt-scroller {\n height: 100%;\n overflow: auto;\n}\n\n/* This is a catch all to ensure*/\n*:has( .data-table:has( .dt-virtual-scroll)) {\n height: 100%;\n min-height: 0;\n}"],"mappings":"AAAA,CAAC,WACC,0BAA0B,IAC1B,2BAA2B,KAC3B,wBAAwB,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAE5C,SAAU,SACV,YAAa,OACb,SAAU,KACV,MAAO,KACP,aAAc,eAChB,CAEA,CAAC,WACC,SAAU,OACV,IAAK,EACL,QAAS,CACX,CAEA,CANC,WAMW,GACV,SAAU,OACV,WAAY,UAEd,CAEA,CAZC,WAYW,CAAC,kBACX,SAAU,QACZ,CAEA,CAAC,YAAY,CAJA,kBAKX,OAAQ,OACV,CAEA,CAAC,wBACC,QAAS,KACT,eAAgB,IAChB,YAAa,OACb,UAAW,OACX,SAAU,MACZ,CAEA,CAAC,aACC,SAAU,SACV,MAAO,IAAI,0BACX,WAAY,QA3Cd,QA4CW,EAAE,KACX,SAAU,OACV,YAAa,CACf,CAEA,CATC,YASY,OACX,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,KAC7B,CAEA,CA7BC,WA6BW,CAAC,cAAc,CAjB1B,YAiBuC,OACtC,QAAS,OACX,CAEA,CAjCC,WAiCW,CAAC,aAAa,CArBzB,YAqBsC,OACrC,QAAS,OACX,CAEA,CAAC,WACC,SAAU,SACV,IAAK,EACL,MAAO,KAAK,CAAC,IAAI,2BAA2B,EAAE,GAAG,EAAE,IACnD,OAAQ,KACR,MAAO,IAAI,2BACX,OAAQ,UACR,QAAS,CACX,CAEA,CAVC,UAUU,OACT,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,MAC3B,MAAO,IACP,OAAQ,IACR,iBAAkB,YACpB,CAEA,CA1EC,UA0EW,CAAE,EAAG,CAAE,EAAE,CAAC,aACtB,CA3EC,UA2EW,CAAE,EAAG,CAAE,EAAE,KAAK,CADJ,cAEpB,iBAAkB,IAAI,uBACxB,CAEA,CA3FC,UA2FW,CAAE,KAAM,CAAE,EAAG,CAAE,GAC3B,CAAC,gBACC,cAAe,SACf,YAAa,OACb,SAAU,MACZ,CAEA,CAAC,SACC,WAAY,OACZ,eAAgB,IAClB,CAEA,CAAC,YACC,OAAQ,KACR,SAAU,IACZ,CAGA,CAAC,KAAM,CA7GN,UA6GiB,KAAM,CAAC,oBACvB,OAAQ,KACR,WAAY,CACd","names":[]}
1
+ {"version":3,"sources":["../src/datatable.css"],"sourcesContent":[".data-table {\n --dt-header-sorter-width: 1ch;\n --dt-header-resizer-width: 10px;\n --dt-header-drop-color: rgba(255, 255, 255, 0.1);\n\n position: relative;\n white-space: nowrap;\n overflow: auto;\n width: 100%;\n table-layout: fixed !important;\n}\n\n.dt-headers {\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.dt-headers th {\n overflow: hidden;\n box-sizing: border-box;\n}\n\n.dt-headers .dt-header-content {\n position: relative;\n}\n\n.dt-sortable .dt-header-content {\n cursor: pointer;\n}\n\n.dt-header-title-wrapper {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex-wrap: nowrap;\n overflow: hidden;\n}\n\n.dt-sort-icon {\n position: relative;\n width: var(--dt-header-sorter-width);\n align-self: stretch;\n padding: 0 12px;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.dt-sort-icon::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.dt-sortable.dt-descending .dt-sort-icon::after {\n content: '\\2191';\n}\n\n.dt-sortable.dt-ascending .dt-sort-icon::after {\n content: '\\2193';\n}\n\n.dt-resizer {\n position: absolute;\n top: 0;\n right: calc((var(--dt-header-resizer-width) / 2) * -1);\n height: 100%;\n width: var(--dt-header-resizer-width);\n cursor: ew-resize;\n z-index: 2;\n}\n\n.dt-resizer::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 1px;\n height: 60%;\n background-color: currentColor;\n}\n\n.dt-headers > tr > th.dt-drag-over,\n.dt-headers > tr > th:has(.dt-drag-over) {\n background-color: var(--dt-header-drop-color);\n}\n\n.data-table > tbody > tr > td,\n.dt-header-title {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.dt-empty {\n text-align: center;\n pointer-events: none;\n}\n"],"mappings":"AAAA,CAAC,WACC,0BAA0B,IAC1B,2BAA2B,KAC3B,wBAAwB,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAE5C,SAAU,SACV,YAAa,OACb,SAAU,KACV,MAAO,KACP,aAAc,eAChB,CAEA,CAAC,WACC,SAAU,OACV,IAAK,EACL,QAAS,CACX,CAEA,CANC,WAMW,GACV,SAAU,OACV,WAAY,UACd,CAEA,CAXC,WAWW,CAAC,kBACX,SAAU,QACZ,CAEA,CAAC,YAAY,CAJA,kBAKX,OAAQ,OACV,CAEA,CAAC,wBACC,QAAS,KACT,eAAgB,IAChB,YAAa,OACb,UAAW,OACX,SAAU,MACZ,CAEA,CAAC,aACC,SAAU,SACV,MAAO,IAAI,0BACX,WAAY,QA1Cd,QA2CW,EAAE,KACX,SAAU,OACV,YAAa,CACf,CAEA,CATC,YASY,OACX,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,KAC7B,CAEA,CA7BC,WA6BW,CAAC,cAAc,CAjB1B,YAiBuC,OACtC,QAAS,OACX,CAEA,CAjCC,WAiCW,CAAC,aAAa,CArBzB,YAqBsC,OACrC,QAAS,OACX,CAEA,CAAC,WACC,SAAU,SACV,IAAK,EACL,MAAO,KAAK,CAAC,IAAI,2BAA2B,EAAE,GAAG,EAAE,IACnD,OAAQ,KACR,MAAO,IAAI,2BACX,OAAQ,UACR,QAAS,CACX,CAEA,CAVC,UAUU,OACT,QAAS,GACT,SAAU,SACV,IAAK,IACL,KAAM,IACN,UAAW,UAAU,IAAI,CAAE,MAC3B,MAAO,IACP,OAAQ,IACR,iBAAkB,YACpB,CAEA,CAzEC,UAyEW,CAAE,EAAG,CAAE,EAAE,CAAC,aACtB,CA1EC,UA0EW,CAAE,EAAG,CAAE,EAAE,KAAK,CADJ,cAEpB,iBAAkB,IAAI,uBACxB,CAEA,CA1FC,UA0FW,CAAE,KAAM,CAAE,EAAG,CAAE,GAC3B,CAAC,gBACC,cAAe,SACf,YAAa,OACb,SAAU,MACZ,CAEA,CAAC,SACC,WAAY,OACZ,eAAgB,IAClB","names":[]}
@@ -1,3 +1,11 @@
1
+ type NestedKeyOf<T> = T extends object ? {
2
+ [K in keyof T]: K extends string ? T[K] extends object ? `${K}` | `${K}.${NestedKeyOf<T[K]>}` : `${K}` : never;
3
+ }[keyof T] : never;
4
+ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
5
+ value: string;
6
+ quoted: boolean;
7
+ }[];
8
+
1
9
  /**
2
10
  * Defines the possible sorting orders for columns.
3
11
  */
@@ -7,21 +15,21 @@ type SortOrder = 'asc' | 'desc' | null;
7
15
  * @param row - The row data.
8
16
  * @param element - The row element.
9
17
  */
10
- type RowFormatterCallback = (row: any, element: HTMLElement) => void;
18
+ type RowFormatterCallback<T> = (row: T, element: HTMLElement) => void;
11
19
  /**
12
20
  * Callback for formatting the value of a cell.
13
21
  * Called when the cell is created and when exporting to CSV.
14
22
  * @param value - The value of the cell.
15
23
  * @param row - The row data.
16
24
  */
17
- type ValueFormatterCallback = (value: any, row: any) => string;
25
+ type ValueFormatterCallback<T> = (value: any, row: T) => string;
18
26
  /**
19
27
  * Callback for formatting a cell's HTML element.
20
28
  * @param value - The value of the field.
21
29
  * @param row - The row data.
22
30
  * @param element - The cell element.
23
31
  */
24
- type CellFormatterCallback = (value: any, row: any, element: HTMLElement) => void;
32
+ type CellFormatterCallback<T> = (value: any, row: T, element: HTMLElement) => void;
25
33
  /**
26
34
  * Callback for comparing two values.
27
35
  * @param a - The first value.
@@ -63,11 +71,11 @@ type ColumnFilterCallback = (value: any, filter: any) => boolean;
63
71
  /**
64
72
  * Column options for the table.
65
73
  */
66
- interface ColumnOptions {
74
+ interface ColumnOptions<T> {
67
75
  /**
68
76
  * The field name in the data object.
69
77
  */
70
- field: string;
78
+ field: NestedKeyOf<T>;
71
79
  /**
72
80
  * The title to display in the header.
73
81
  */
@@ -110,11 +118,11 @@ interface ColumnOptions {
110
118
  /**
111
119
  * A function to format the value for display.
112
120
  */
113
- valueFormatter?: ValueFormatterCallback;
121
+ valueFormatter?: ValueFormatterCallback<T>;
114
122
  /**
115
123
  * A function to format the element for display.
116
124
  */
117
- elementFormatter?: CellFormatterCallback;
125
+ elementFormatter?: CellFormatterCallback<T>;
118
126
  /**
119
127
  * A function to use for sorting the column.
120
128
  * This overrides the default sorting behavior.
@@ -177,10 +185,6 @@ interface TableClasses {
177
185
  * Classes for the tbody element.
178
186
  */
179
187
  tbody?: string | string[];
180
- /**
181
- * Classes for the tfoot element.
182
- */
183
- tfoot?: string | string[];
184
188
  /**
185
189
  * Classes for each table row element.
186
190
  */
@@ -201,19 +205,15 @@ interface TableClasses {
201
205
  /**
202
206
  * Options for configuring the table.
203
207
  */
204
- interface TableOptions {
205
- /**
206
- * The column options for the table.
207
- */
208
- columns?: ColumnOptions[];
208
+ interface TableOptions<T> {
209
209
  /**
210
210
  * The initial data to load into the table.
211
211
  */
212
- data?: any[];
212
+ data?: T[];
213
213
  /**
214
214
  * Configures virtual scrolling.
215
215
  */
216
- virtualScroll?: boolean;
216
+ virtualScroll?: boolean | number;
217
217
  /**
218
218
  * Whether to highlight search results in the table cells.
219
219
  */
@@ -261,7 +261,7 @@ interface TableOptions {
261
261
  /**
262
262
  * A function to format each row's HTML element.
263
263
  */
264
- rowFormatter?: RowFormatterCallback;
264
+ rowFormatter?: RowFormatterCallback<T>;
265
265
  /**
266
266
  * A function to use for tokenizing values for searching.
267
267
  */
@@ -273,11 +273,9 @@ interface LoadOptions {
273
273
  /** If the current scroll position should be kepts */
274
274
  keepScroll?: boolean;
275
275
  }
276
-
277
- declare const createRegexTokenizer: (exp?: string) => (value: string) => {
278
- value: string;
279
- quoted: boolean;
280
- }[];
276
+ type Filters<T> = Partial<{
277
+ [K in keyof T]: any;
278
+ }>;
281
279
 
282
280
  /**
283
281
  * Represents a dynamic and interactive table with features like sorting, searching, filtering,
@@ -285,13 +283,13 @@ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
285
283
  *
286
284
  * @example
287
285
  * ```ts
288
- * const tableElement = document.getElementById('myTable');
289
- * const options = {
290
- * columns: [
286
+ * type DataType = {id: number, name: string, age: number};
287
+ *
288
+ * const dataTable = new DataTable<DataType>('#myTable', [
291
289
  * { field: 'id', title: 'ID', sortable: true },
292
290
  * { field: 'name', title: 'Name', searchable: true },
293
291
  * { field: 'age', title: 'Age', sortable: true, valueFormatter: (value) => `${value} years` }
294
- * ],
292
+ * ], {
295
293
  * data: [
296
294
  * { id: 1, name: 'Alice', age: 30 },
297
295
  * { id: 2, name: 'Bob', age: 24 },
@@ -299,22 +297,23 @@ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
299
297
  * virtualScroll: true,
300
298
  * resizable: true,
301
299
  * rearrangeable: true,
302
- * };
303
- * const dataTable = new DataTable(tableElement, options);
300
+ * });
304
301
  * ```
305
302
  */
306
- declare class DataTable extends EventTarget {
303
+ declare class DataTable<T> extends EventTarget {
307
304
  #private;
308
305
  private static readonly MatchWeights;
309
- private static readonly DEFAULT_OPTIONS;
306
+ private readonly DEFAULT_OPTIONS;
310
307
  /**
311
308
  * Initializes a new instance of the DataTable.
312
309
  * @param table - The HTMLTableElement or a CSS selector string for the table.
310
+ * @param columns - List of {@link ColumnOptions} for the table.
313
311
  * @param options - Optional configuration options for the DataTable.
314
312
  * @throws {SyntaxError} If the table selector does not find an element.
315
313
  * @throws {TypeError} If the provided table element is not an HTMLTableElement or if columns option is not an array.
316
314
  */
317
- constructor(table: string | HTMLTableElement, options?: TableOptions);
315
+ constructor(table: string | HTMLTableElement, columns: ColumnOptions<T>[], options?: TableOptions<T>);
316
+ get options(): RequiredOptions<T>;
318
317
  /**
319
318
  * Gets or sets the state of all columns in the table.
320
319
  * This can be used to save and restore column configurations like visibility, sort order, and width.
@@ -325,35 +324,23 @@ declare class DataTable extends EventTarget {
325
324
  /**
326
325
  * Gets the currently filtered and sorted rows displayed in the table.
327
326
  */
328
- get rows(): any[];
327
+ get rows(): T[];
329
328
  /**
330
329
  * Gets the underlying data
331
330
  */
332
- get data(): any[];
333
- /**
334
- * Gets the total number of currently filtered and sorted rows.
335
- */
336
- get length(): number;
331
+ get data(): T[];
337
332
  /**
338
333
  * Gets the underlying HTMLTableElement managed by this DataTable instance.
339
334
  */
340
335
  get table(): HTMLTableElement;
341
- /**
342
- * Gets or sets the virtual scroll behavior for the table.
343
- * When `true`, virtual scrolling is enabled, rendering only visible rows for performance with large datasets.
344
- * When `false`, virtual scrolling is disabled, and all rows are rendered.
345
- * @default true
346
- */
347
- get virtualScroll(): boolean;
348
- set virtualScroll(value: boolean);
349
- get scoring(): boolean;
350
- set scoring(value: boolean);
336
+ updateOptions(options: UpdatableOptions<T>): void;
337
+ updateColumnOptions(column: ColumnField<T>, options: UpdateableColumnOptions<T>): void;
351
338
  /**
352
339
  * Loads data into the table
353
340
  * @param rows - An array of data to be loaded
354
341
  * @param options - Configuration for the load operation
355
342
  */
356
- loadData(rows: any[], options?: LoadOptions): void;
343
+ loadData(rows: T[], options?: LoadOptions): void;
357
344
  /**
358
345
  * Displays a message in the table body, typically used for "no data" or "no results" states.
359
346
  * The message is shown in a single row spanning all columns.
@@ -378,7 +365,7 @@ declare class DataTable extends EventTarget {
378
365
  * @param filters - An object defining field-based filters or a custom filter callback function.
379
366
  * @throws {TypeError} If `filters` is not an object or a function.
380
367
  */
381
- filter(filters?: any | FilterCallback): void;
368
+ filter(filters?: Filters<T> | FilterCallback): void;
382
369
  /**
383
370
  * Sorts the table by a specified column and order.
384
371
  * If `order` is `null`, the sort on this column is removed.
@@ -408,7 +395,7 @@ declare class DataTable extends EventTarget {
408
395
  * @param all - If `true`, exports all original data (ignoring filters). If `false` (default), exports only the currently visible (filtered and sorted) rows.
409
396
  */
410
397
  export(filename: string, all?: boolean): void;
411
- scrollToRow(row: any): void;
398
+ scrollToRow(row: T): void;
412
399
  /**
413
400
  * Scrolls the table to bring the row at the specified original index into view.
414
401
  * @param index - The original index of the row (from the initial dataset).
@@ -455,7 +442,7 @@ declare class DataTable extends EventTarget {
455
442
  * }
456
443
  * ```
457
444
  */
458
- updateRow(index: number, data: any): void;
445
+ updateRow(index: number, data: T): void;
459
446
  /**
460
447
  * Deletes a row at a specific original index from the table.
461
448
  * @param index - The original index of the row to delete.
@@ -467,16 +454,20 @@ declare class DataTable extends EventTarget {
467
454
  * @param callback - A function to execute. It receives the DataTable instance as its argument.
468
455
  * @example dataTable.withoutUpdates(dt => { dt.sort('name', 'asc'); dt.filter({ age: '>30' }); });
469
456
  */
470
- withoutUpdates(callback: (datatable: DataTable) => void): void;
471
- addEventListener<K extends keyof DataTableEventMap>(type: K, listener: (this: DataTable, ev: CustomEvent<DataTableEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
457
+ withoutUpdates(callback: (datatable: DataTable<T>) => void): void;
458
+ addEventListener<K extends keyof DataTableEventMap<T>>(type: K, listener: (this: DataTable<T>, ev: CustomEvent<DataTableEventMap<T>[K]>) => any, options?: boolean | AddEventListenerOptions): void;
472
459
  addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
473
460
  }
461
+ type ColumnField<T> = NestedKeyOf<T>;
462
+ type InternalClasses = Required<{
463
+ [K in keyof TableClasses]: string[];
464
+ }>;
474
465
  /**
475
466
  * Defines the mapping between event names and their detail object types.
476
467
  */
477
- interface DataTableEventMap {
468
+ interface DataTableEventMap<T> {
478
469
  'dt.row.clicked': {
479
- row: any;
470
+ row: T;
480
471
  index: number;
481
472
  column: string | undefined;
482
473
  originalEvent: MouseEvent;
@@ -500,6 +491,12 @@ interface DataTableEventMap {
500
491
  order: string[];
501
492
  };
502
493
  }
494
+ type RequiredOptions<T> = Required<Omit<TableOptions<T>, 'columns' | 'data' | 'rowFormatter' | 'classes'>> & Pick<TableOptions<T>, 'rowFormatter'> & {
495
+ classes: InternalClasses;
496
+ virtualScroll: number;
497
+ };
498
+ type UpdatableOptions<T> = Pick<TableOptions<T>, 'virtualScroll' | 'highlightSearch' | 'tokenizeSearch' | 'enableSearchScoring' | 'rearrangeable' | 'extraSearchFields' | 'noMatchText' | 'noDataText' | 'classes'>;
499
+ type UpdateableColumnOptions<T> = Pick<ColumnOptions<T>, 'title' | 'searchable' | 'resizable' | 'sortable' | 'tokenize' | 'valueFormatter' | 'elementFormatter' | 'sorter'>;
503
500
 
504
501
  interface Options {
505
502
  saveColumnSorting: boolean;
@@ -507,14 +504,17 @@ interface Options {
507
504
  saveColumnVisibility: boolean;
508
505
  saveColumnWidth: boolean;
509
506
  }
510
- declare class LocalStorageAdapter {
507
+ /**
508
+ * Monitors a {@link DataTable} instance for changes and saves the state to local storage.
509
+ */
510
+ declare class LocalStorageAdapter<T> {
511
511
  #private;
512
512
  /**
513
513
  * @param dataTable - The DataTable instance to monitor.
514
514
  * @param storageKey - The key to use for saving the state in localStorage.
515
- * @param options - The key to use for saving the state in localStorage.
515
+ * @param options - The options for configuring what is stored.
516
516
  */
517
- constructor(dataTable: DataTable, storageKey: string, options?: Options);
517
+ constructor(dataTable: DataTable<T>, storageKey: string, options?: Options);
518
518
  /**
519
519
  * Saves the current column state to localStorage.
520
520
  */
@@ -529,4 +529,4 @@ declare class LocalStorageAdapter {
529
529
  clearState(): void;
530
530
  }
531
531
 
532
- export { type CellFormatterCallback, type ColumnFilterCallback, type ColumnOptions, type ColumnState, type ComparatorCallback, DataTable, type DataTableEventMap, type FilterCallback, type LoadOptions, LocalStorageAdapter, type QueryToken, type RowFormatterCallback, type SortOrder, type SortValueCallback, type TableClasses, type TableOptions, type TokenizerCallback, type ValueFormatterCallback, createRegexTokenizer };
532
+ export { type CellFormatterCallback, type ColumnFilterCallback, type ColumnOptions, type ColumnState, type ComparatorCallback, DataTable, type DataTableEventMap, type FilterCallback, type Filters, type LoadOptions, LocalStorageAdapter, type QueryToken, type RowFormatterCallback, type SortOrder, type SortValueCallback, type TableClasses, type TableOptions, type TokenizerCallback, type ValueFormatterCallback, createRegexTokenizer };
@@ -1,3 +1,11 @@
1
+ type NestedKeyOf<T> = T extends object ? {
2
+ [K in keyof T]: K extends string ? T[K] extends object ? `${K}` | `${K}.${NestedKeyOf<T[K]>}` : `${K}` : never;
3
+ }[keyof T] : never;
4
+ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
5
+ value: string;
6
+ quoted: boolean;
7
+ }[];
8
+
1
9
  /**
2
10
  * Defines the possible sorting orders for columns.
3
11
  */
@@ -7,21 +15,21 @@ type SortOrder = 'asc' | 'desc' | null;
7
15
  * @param row - The row data.
8
16
  * @param element - The row element.
9
17
  */
10
- type RowFormatterCallback = (row: any, element: HTMLElement) => void;
18
+ type RowFormatterCallback<T> = (row: T, element: HTMLElement) => void;
11
19
  /**
12
20
  * Callback for formatting the value of a cell.
13
21
  * Called when the cell is created and when exporting to CSV.
14
22
  * @param value - The value of the cell.
15
23
  * @param row - The row data.
16
24
  */
17
- type ValueFormatterCallback = (value: any, row: any) => string;
25
+ type ValueFormatterCallback<T> = (value: any, row: T) => string;
18
26
  /**
19
27
  * Callback for formatting a cell's HTML element.
20
28
  * @param value - The value of the field.
21
29
  * @param row - The row data.
22
30
  * @param element - The cell element.
23
31
  */
24
- type CellFormatterCallback = (value: any, row: any, element: HTMLElement) => void;
32
+ type CellFormatterCallback<T> = (value: any, row: T, element: HTMLElement) => void;
25
33
  /**
26
34
  * Callback for comparing two values.
27
35
  * @param a - The first value.
@@ -63,11 +71,11 @@ type ColumnFilterCallback = (value: any, filter: any) => boolean;
63
71
  /**
64
72
  * Column options for the table.
65
73
  */
66
- interface ColumnOptions {
74
+ interface ColumnOptions<T> {
67
75
  /**
68
76
  * The field name in the data object.
69
77
  */
70
- field: string;
78
+ field: NestedKeyOf<T>;
71
79
  /**
72
80
  * The title to display in the header.
73
81
  */
@@ -110,11 +118,11 @@ interface ColumnOptions {
110
118
  /**
111
119
  * A function to format the value for display.
112
120
  */
113
- valueFormatter?: ValueFormatterCallback;
121
+ valueFormatter?: ValueFormatterCallback<T>;
114
122
  /**
115
123
  * A function to format the element for display.
116
124
  */
117
- elementFormatter?: CellFormatterCallback;
125
+ elementFormatter?: CellFormatterCallback<T>;
118
126
  /**
119
127
  * A function to use for sorting the column.
120
128
  * This overrides the default sorting behavior.
@@ -177,10 +185,6 @@ interface TableClasses {
177
185
  * Classes for the tbody element.
178
186
  */
179
187
  tbody?: string | string[];
180
- /**
181
- * Classes for the tfoot element.
182
- */
183
- tfoot?: string | string[];
184
188
  /**
185
189
  * Classes for each table row element.
186
190
  */
@@ -201,19 +205,15 @@ interface TableClasses {
201
205
  /**
202
206
  * Options for configuring the table.
203
207
  */
204
- interface TableOptions {
205
- /**
206
- * The column options for the table.
207
- */
208
- columns?: ColumnOptions[];
208
+ interface TableOptions<T> {
209
209
  /**
210
210
  * The initial data to load into the table.
211
211
  */
212
- data?: any[];
212
+ data?: T[];
213
213
  /**
214
214
  * Configures virtual scrolling.
215
215
  */
216
- virtualScroll?: boolean;
216
+ virtualScroll?: boolean | number;
217
217
  /**
218
218
  * Whether to highlight search results in the table cells.
219
219
  */
@@ -261,7 +261,7 @@ interface TableOptions {
261
261
  /**
262
262
  * A function to format each row's HTML element.
263
263
  */
264
- rowFormatter?: RowFormatterCallback;
264
+ rowFormatter?: RowFormatterCallback<T>;
265
265
  /**
266
266
  * A function to use for tokenizing values for searching.
267
267
  */
@@ -273,11 +273,9 @@ interface LoadOptions {
273
273
  /** If the current scroll position should be kepts */
274
274
  keepScroll?: boolean;
275
275
  }
276
-
277
- declare const createRegexTokenizer: (exp?: string) => (value: string) => {
278
- value: string;
279
- quoted: boolean;
280
- }[];
276
+ type Filters<T> = Partial<{
277
+ [K in keyof T]: any;
278
+ }>;
281
279
 
282
280
  /**
283
281
  * Represents a dynamic and interactive table with features like sorting, searching, filtering,
@@ -285,13 +283,13 @@ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
285
283
  *
286
284
  * @example
287
285
  * ```ts
288
- * const tableElement = document.getElementById('myTable');
289
- * const options = {
290
- * columns: [
286
+ * type DataType = {id: number, name: string, age: number};
287
+ *
288
+ * const dataTable = new DataTable<DataType>('#myTable', [
291
289
  * { field: 'id', title: 'ID', sortable: true },
292
290
  * { field: 'name', title: 'Name', searchable: true },
293
291
  * { field: 'age', title: 'Age', sortable: true, valueFormatter: (value) => `${value} years` }
294
- * ],
292
+ * ], {
295
293
  * data: [
296
294
  * { id: 1, name: 'Alice', age: 30 },
297
295
  * { id: 2, name: 'Bob', age: 24 },
@@ -299,22 +297,23 @@ declare const createRegexTokenizer: (exp?: string) => (value: string) => {
299
297
  * virtualScroll: true,
300
298
  * resizable: true,
301
299
  * rearrangeable: true,
302
- * };
303
- * const dataTable = new DataTable(tableElement, options);
300
+ * });
304
301
  * ```
305
302
  */
306
- declare class DataTable extends EventTarget {
303
+ declare class DataTable<T> extends EventTarget {
307
304
  #private;
308
305
  private static readonly MatchWeights;
309
- private static readonly DEFAULT_OPTIONS;
306
+ private readonly DEFAULT_OPTIONS;
310
307
  /**
311
308
  * Initializes a new instance of the DataTable.
312
309
  * @param table - The HTMLTableElement or a CSS selector string for the table.
310
+ * @param columns - List of {@link ColumnOptions} for the table.
313
311
  * @param options - Optional configuration options for the DataTable.
314
312
  * @throws {SyntaxError} If the table selector does not find an element.
315
313
  * @throws {TypeError} If the provided table element is not an HTMLTableElement or if columns option is not an array.
316
314
  */
317
- constructor(table: string | HTMLTableElement, options?: TableOptions);
315
+ constructor(table: string | HTMLTableElement, columns: ColumnOptions<T>[], options?: TableOptions<T>);
316
+ get options(): RequiredOptions<T>;
318
317
  /**
319
318
  * Gets or sets the state of all columns in the table.
320
319
  * This can be used to save and restore column configurations like visibility, sort order, and width.
@@ -325,35 +324,23 @@ declare class DataTable extends EventTarget {
325
324
  /**
326
325
  * Gets the currently filtered and sorted rows displayed in the table.
327
326
  */
328
- get rows(): any[];
327
+ get rows(): T[];
329
328
  /**
330
329
  * Gets the underlying data
331
330
  */
332
- get data(): any[];
333
- /**
334
- * Gets the total number of currently filtered and sorted rows.
335
- */
336
- get length(): number;
331
+ get data(): T[];
337
332
  /**
338
333
  * Gets the underlying HTMLTableElement managed by this DataTable instance.
339
334
  */
340
335
  get table(): HTMLTableElement;
341
- /**
342
- * Gets or sets the virtual scroll behavior for the table.
343
- * When `true`, virtual scrolling is enabled, rendering only visible rows for performance with large datasets.
344
- * When `false`, virtual scrolling is disabled, and all rows are rendered.
345
- * @default true
346
- */
347
- get virtualScroll(): boolean;
348
- set virtualScroll(value: boolean);
349
- get scoring(): boolean;
350
- set scoring(value: boolean);
336
+ updateOptions(options: UpdatableOptions<T>): void;
337
+ updateColumnOptions(column: ColumnField<T>, options: UpdateableColumnOptions<T>): void;
351
338
  /**
352
339
  * Loads data into the table
353
340
  * @param rows - An array of data to be loaded
354
341
  * @param options - Configuration for the load operation
355
342
  */
356
- loadData(rows: any[], options?: LoadOptions): void;
343
+ loadData(rows: T[], options?: LoadOptions): void;
357
344
  /**
358
345
  * Displays a message in the table body, typically used for "no data" or "no results" states.
359
346
  * The message is shown in a single row spanning all columns.
@@ -378,7 +365,7 @@ declare class DataTable extends EventTarget {
378
365
  * @param filters - An object defining field-based filters or a custom filter callback function.
379
366
  * @throws {TypeError} If `filters` is not an object or a function.
380
367
  */
381
- filter(filters?: any | FilterCallback): void;
368
+ filter(filters?: Filters<T> | FilterCallback): void;
382
369
  /**
383
370
  * Sorts the table by a specified column and order.
384
371
  * If `order` is `null`, the sort on this column is removed.
@@ -408,7 +395,7 @@ declare class DataTable extends EventTarget {
408
395
  * @param all - If `true`, exports all original data (ignoring filters). If `false` (default), exports only the currently visible (filtered and sorted) rows.
409
396
  */
410
397
  export(filename: string, all?: boolean): void;
411
- scrollToRow(row: any): void;
398
+ scrollToRow(row: T): void;
412
399
  /**
413
400
  * Scrolls the table to bring the row at the specified original index into view.
414
401
  * @param index - The original index of the row (from the initial dataset).
@@ -455,7 +442,7 @@ declare class DataTable extends EventTarget {
455
442
  * }
456
443
  * ```
457
444
  */
458
- updateRow(index: number, data: any): void;
445
+ updateRow(index: number, data: T): void;
459
446
  /**
460
447
  * Deletes a row at a specific original index from the table.
461
448
  * @param index - The original index of the row to delete.
@@ -467,16 +454,20 @@ declare class DataTable extends EventTarget {
467
454
  * @param callback - A function to execute. It receives the DataTable instance as its argument.
468
455
  * @example dataTable.withoutUpdates(dt => { dt.sort('name', 'asc'); dt.filter({ age: '>30' }); });
469
456
  */
470
- withoutUpdates(callback: (datatable: DataTable) => void): void;
471
- addEventListener<K extends keyof DataTableEventMap>(type: K, listener: (this: DataTable, ev: CustomEvent<DataTableEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
457
+ withoutUpdates(callback: (datatable: DataTable<T>) => void): void;
458
+ addEventListener<K extends keyof DataTableEventMap<T>>(type: K, listener: (this: DataTable<T>, ev: CustomEvent<DataTableEventMap<T>[K]>) => any, options?: boolean | AddEventListenerOptions): void;
472
459
  addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
473
460
  }
461
+ type ColumnField<T> = NestedKeyOf<T>;
462
+ type InternalClasses = Required<{
463
+ [K in keyof TableClasses]: string[];
464
+ }>;
474
465
  /**
475
466
  * Defines the mapping between event names and their detail object types.
476
467
  */
477
- interface DataTableEventMap {
468
+ interface DataTableEventMap<T> {
478
469
  'dt.row.clicked': {
479
- row: any;
470
+ row: T;
480
471
  index: number;
481
472
  column: string | undefined;
482
473
  originalEvent: MouseEvent;
@@ -500,6 +491,12 @@ interface DataTableEventMap {
500
491
  order: string[];
501
492
  };
502
493
  }
494
+ type RequiredOptions<T> = Required<Omit<TableOptions<T>, 'columns' | 'data' | 'rowFormatter' | 'classes'>> & Pick<TableOptions<T>, 'rowFormatter'> & {
495
+ classes: InternalClasses;
496
+ virtualScroll: number;
497
+ };
498
+ type UpdatableOptions<T> = Pick<TableOptions<T>, 'virtualScroll' | 'highlightSearch' | 'tokenizeSearch' | 'enableSearchScoring' | 'rearrangeable' | 'extraSearchFields' | 'noMatchText' | 'noDataText' | 'classes'>;
499
+ type UpdateableColumnOptions<T> = Pick<ColumnOptions<T>, 'title' | 'searchable' | 'resizable' | 'sortable' | 'tokenize' | 'valueFormatter' | 'elementFormatter' | 'sorter'>;
503
500
 
504
501
  interface Options {
505
502
  saveColumnSorting: boolean;
@@ -507,14 +504,17 @@ interface Options {
507
504
  saveColumnVisibility: boolean;
508
505
  saveColumnWidth: boolean;
509
506
  }
510
- declare class LocalStorageAdapter {
507
+ /**
508
+ * Monitors a {@link DataTable} instance for changes and saves the state to local storage.
509
+ */
510
+ declare class LocalStorageAdapter<T> {
511
511
  #private;
512
512
  /**
513
513
  * @param dataTable - The DataTable instance to monitor.
514
514
  * @param storageKey - The key to use for saving the state in localStorage.
515
- * @param options - The key to use for saving the state in localStorage.
515
+ * @param options - The options for configuring what is stored.
516
516
  */
517
- constructor(dataTable: DataTable, storageKey: string, options?: Options);
517
+ constructor(dataTable: DataTable<T>, storageKey: string, options?: Options);
518
518
  /**
519
519
  * Saves the current column state to localStorage.
520
520
  */
@@ -529,4 +529,4 @@ declare class LocalStorageAdapter {
529
529
  clearState(): void;
530
530
  }
531
531
 
532
- export { type CellFormatterCallback, type ColumnFilterCallback, type ColumnOptions, type ColumnState, type ComparatorCallback, DataTable, type DataTableEventMap, type FilterCallback, type LoadOptions, LocalStorageAdapter, type QueryToken, type RowFormatterCallback, type SortOrder, type SortValueCallback, type TableClasses, type TableOptions, type TokenizerCallback, type ValueFormatterCallback, createRegexTokenizer };
532
+ export { type CellFormatterCallback, type ColumnFilterCallback, type ColumnOptions, type ColumnState, type ComparatorCallback, DataTable, type DataTableEventMap, type FilterCallback, type Filters, type LoadOptions, LocalStorageAdapter, type QueryToken, type RowFormatterCallback, type SortOrder, type SortValueCallback, type TableClasses, type TableOptions, type TokenizerCallback, type ValueFormatterCallback, createRegexTokenizer };