@timlassiter11/yatl 0.3.22 → 1.0.1

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/dist/index.js ADDED
@@ -0,0 +1,1969 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+
28
+ // src/index.ts
29
+ var src_exports = {};
30
+ __export(src_exports, {
31
+ YatlChangeEvent: () => YatlChangeEvent,
32
+ YatlColumnReorderEvent: () => YatlColumnReorderEvent,
33
+ YatlColumnResizeEvent: () => YatlColumnResizeEvent,
34
+ YatlColumnToggleEvent: () => YatlColumnToggleEvent,
35
+ YatlEvent: () => YatlEvent,
36
+ YatlRowClickEvent: () => YatlRowClickEvent,
37
+ YatlSearchEvent: () => YatlSearchEvent,
38
+ YatlSortEvent: () => YatlSortEvent,
39
+ YatlStateChangeEvent: () => YatlStateChangeEvent,
40
+ YatlTable: () => YatlTable,
41
+ createRegexTokenizer: () => createRegexTokenizer,
42
+ findColumn: () => findColumn,
43
+ whitespaceTokenizer: () => whitespaceTokenizer
44
+ });
45
+ module.exports = __toCommonJS(src_exports);
46
+
47
+ // src/events.ts
48
+ var YatlEvent = class extends CustomEvent {
49
+ constructor(name, detail, options = {}) {
50
+ super(name, {
51
+ bubbles: true,
52
+ composed: true,
53
+ cancelable: false,
54
+ ...options,
55
+ detail
56
+ });
57
+ }
58
+ };
59
+ var _YatlRowClickEvent = class _YatlRowClickEvent extends YatlEvent {
60
+ constructor(row, index, field, originalEvent) {
61
+ super(_YatlRowClickEvent.EVENT_NAME, {
62
+ row,
63
+ index,
64
+ field,
65
+ originalEvent
66
+ });
67
+ }
68
+ };
69
+ _YatlRowClickEvent.EVENT_NAME = "yatl-row-click";
70
+ var YatlRowClickEvent = _YatlRowClickEvent;
71
+ var _YatlChangeEvent = class _YatlChangeEvent extends YatlEvent {
72
+ constructor(data) {
73
+ super(_YatlChangeEvent.EVENT_NAME, { data });
74
+ }
75
+ };
76
+ _YatlChangeEvent.EVENT_NAME = "yatl-change";
77
+ var YatlChangeEvent = _YatlChangeEvent;
78
+ var _YatlSortEvent = class _YatlSortEvent extends YatlEvent {
79
+ constructor(field, order) {
80
+ super(
81
+ _YatlSortEvent.EVENT_NAME,
82
+ {
83
+ field,
84
+ order
85
+ },
86
+ {
87
+ cancelable: true
88
+ }
89
+ );
90
+ }
91
+ };
92
+ _YatlSortEvent.EVENT_NAME = "yatl-sort";
93
+ var YatlSortEvent = _YatlSortEvent;
94
+ var _YatlColumnToggleEvent = class _YatlColumnToggleEvent extends YatlEvent {
95
+ constructor(field, visible) {
96
+ super(
97
+ _YatlColumnToggleEvent.EVENT_NAME,
98
+ {
99
+ field,
100
+ visible
101
+ },
102
+ {
103
+ cancelable: true
104
+ }
105
+ );
106
+ }
107
+ };
108
+ _YatlColumnToggleEvent.EVENT_NAME = "yatl-column-toggle";
109
+ var YatlColumnToggleEvent = _YatlColumnToggleEvent;
110
+ var _YatlColumnResizeEvent = class _YatlColumnResizeEvent extends YatlEvent {
111
+ constructor(field, width) {
112
+ super(_YatlColumnResizeEvent.EVENT_NAME, {
113
+ field,
114
+ width
115
+ });
116
+ }
117
+ };
118
+ _YatlColumnResizeEvent.EVENT_NAME = "yatl-column-resize";
119
+ var YatlColumnResizeEvent = _YatlColumnResizeEvent;
120
+ var _YatlColumnReorderEvent = class _YatlColumnReorderEvent extends YatlEvent {
121
+ constructor(draggedColumn, droppedColumn, order) {
122
+ super(
123
+ _YatlColumnReorderEvent.EVENT_NAME,
124
+ {
125
+ draggedColumn,
126
+ droppedColumn,
127
+ order
128
+ },
129
+ {
130
+ cancelable: true
131
+ }
132
+ );
133
+ }
134
+ };
135
+ _YatlColumnReorderEvent.EVENT_NAME = "yatl-column-reorder";
136
+ var YatlColumnReorderEvent = _YatlColumnReorderEvent;
137
+ var _YatlSearchEvent = class _YatlSearchEvent extends YatlEvent {
138
+ constructor(query2) {
139
+ super(_YatlSearchEvent.EVENT_NAME, { query: query2 });
140
+ }
141
+ };
142
+ _YatlSearchEvent.EVENT_NAME = "yatl-search";
143
+ var YatlSearchEvent = _YatlSearchEvent;
144
+ var _YatlStateChangeEvent = class _YatlStateChangeEvent extends YatlEvent {
145
+ constructor(state2, triggers) {
146
+ super(_YatlStateChangeEvent.EVENT_NAME, { state: state2, triggers });
147
+ this.triggers = triggers;
148
+ }
149
+ };
150
+ _YatlStateChangeEvent.EVENT_NAME = "yatl-state-change";
151
+ var YatlStateChangeEvent = _YatlStateChangeEvent;
152
+
153
+ // src/utils.ts
154
+ var import_lit = require("lit");
155
+ var toHumanReadable = (str) => {
156
+ return str.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (char) => char.toUpperCase());
157
+ };
158
+ var createRegexTokenizer = (exp = "\\S+") => {
159
+ const regex = new RegExp(`"[^"]*"|${exp}`, "g");
160
+ return (value) => {
161
+ const matches = value.match(regex) || [];
162
+ return matches.map((token) => {
163
+ token = token.toLocaleLowerCase().trim();
164
+ if (token.startsWith('"') && token.endsWith('"')) {
165
+ return { value: token.slice(1, -1), quoted: true };
166
+ }
167
+ return { value: token, quoted: false };
168
+ });
169
+ };
170
+ };
171
+ var whitespaceTokenizer = createRegexTokenizer();
172
+ function isValidKey(key, obj) {
173
+ return key in obj;
174
+ }
175
+ function getNestedValue(obj, path) {
176
+ const keys = path.split(".");
177
+ let current = obj;
178
+ for (const key of keys) {
179
+ if (current && isValidKey(key, current)) {
180
+ current = current[key];
181
+ } else {
182
+ return void 0;
183
+ }
184
+ }
185
+ return current;
186
+ }
187
+ function findColumn(field, columns) {
188
+ return columns.find((c) => c.field === field);
189
+ }
190
+ function highlightText(text, ranges) {
191
+ if (!text || !ranges || ranges.length === 0) {
192
+ return text;
193
+ }
194
+ const sortedRanges = [...ranges].sort((a, b) => a[0] - b[0]);
195
+ const mergedRanges = [];
196
+ let currentRange = sortedRanges[0];
197
+ for (let i = 1; i < sortedRanges.length; i++) {
198
+ const nextRange = sortedRanges[i];
199
+ if (nextRange[0] < currentRange[1]) {
200
+ currentRange[1] = Math.max(currentRange[1], nextRange[1]);
201
+ } else {
202
+ mergedRanges.push(currentRange);
203
+ currentRange = nextRange;
204
+ }
205
+ }
206
+ mergedRanges.push(currentRange);
207
+ const result = [];
208
+ let lastIndex = 0;
209
+ for (const [start, end] of mergedRanges) {
210
+ const safeStart = Math.max(0, Math.min(start, text.length));
211
+ const safeEnd = Math.max(0, Math.min(end, text.length));
212
+ if (safeStart > lastIndex) {
213
+ result.push(text.slice(lastIndex, safeStart));
214
+ }
215
+ result.push(
216
+ import_lit.html`<mark class="highlight">${text.slice(safeStart, safeEnd)}</mark>`
217
+ );
218
+ lastIndex = safeEnd;
219
+ }
220
+ if (lastIndex < text.length) {
221
+ result.push(text.slice(lastIndex));
222
+ }
223
+ return import_lit.html`${result}`;
224
+ }
225
+ function widthsToGridTemplates(widths, defaultWidth = "1fr") {
226
+ return widths.map((width) => width ? `${width}px` : defaultWidth);
227
+ }
228
+ function isCompareable(value) {
229
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value instanceof Date;
230
+ }
231
+
232
+ // src/yatl-table.ts
233
+ var import_lit3 = require("lit");
234
+ var import_decorators = require("lit/decorators.js");
235
+ var import_class_map = require("lit/directives/class-map.js");
236
+ var import_if_defined = require("lit/directives/if-defined.js");
237
+ var import_repeat = require("lit/directives/repeat.js");
238
+ var import_style_map = require("lit/directives/style-map.js");
239
+ var import_virtualizer = require("@lit-labs/virtualizer");
240
+
241
+ // src/yatl-table.styles.ts
242
+ var import_lit2 = require("lit");
243
+ var yatl_table_styles_default = import_lit2.css`
244
+ /* Style declarations */
245
+ :host {
246
+ /* Typography */
247
+ --yatl-font-family: var(
248
+ --yatl-table-font,
249
+ -apple-system,
250
+ BlinkMacSystemFont,
251
+ 'Segoe UI',
252
+ Roboto,
253
+ Helvetica,
254
+ Arial,
255
+ sans-serif,
256
+ 'Apple Color Emoji',
257
+ 'Segoe UI Emoji'
258
+ );
259
+ --yatl-font-size: var(--yatl-table-font-size, 0.875rem);
260
+ --yatl-line-height: var(--yatl-table-line-height, 1.25rem);
261
+
262
+ /* Spacing */
263
+ --yatl-cell-padding: var(--yatl-table-cell-padding, 10px 16px);
264
+ --yatl-header-padding: var(--yatl-table-header-padding, 12px 16px);
265
+
266
+ /* Colors */
267
+ --yatl-bg: var(--yatl-table-bg, #ffffff);
268
+ --yatl-text: var(--yatl-table-text, #0f172a);
269
+ --yatl-text-muted: var(--yatl-table-text-muted, #64748b);
270
+ --yatl-border-color: var(--yatl-table-border-color, #e2e8f0);
271
+
272
+ --yatl-header-bg: var(--yatl-table-header-bg, #f8fafc);
273
+ --yatl-header-text: var(--yatl-table-header-text, #475569);
274
+
275
+ --yatl-row-hover-bg: var(--yatl-table-row-hover-bg, #f1f5f9);
276
+ --yatl-row-selected-bg: var(--yatl-table-row-selected-bg, #e0f2fe);
277
+
278
+ /* Resize grab handle width */
279
+ --yatl-resizer-width: 10px;
280
+ /* z-index for the header */
281
+ --header-z-index: 2;
282
+ /* Drop target background color */
283
+ --header-drop-color: rgba(255, 255, 255, 0.1);
284
+
285
+ font-family: var(--yatl-font-family);
286
+ font-size: var(--yatl-font-size);
287
+ color: var(--yatl-text);
288
+ }
289
+
290
+ :host(.dark) {
291
+ --yatl-table-bg: #1e293b;
292
+ --yatl-table-text: #f1f5f9;
293
+ --yatl-table-text-muted: #94a3b8;
294
+ --yatl-table-border-color: #334155;
295
+
296
+ --yatl-table-header-bg: #0f172a;
297
+ --yatl-table-header-text: #cbd5e1;
298
+
299
+ --yatl-table-row-hover-bg: #334155;
300
+ --yatl-table-row-selected-bg: #1e3a8a;
301
+ }
302
+
303
+ @media (prefers-color-scheme: dark) {
304
+ :host {
305
+ --yatl-bg: var(--yatl-table-bg, #1e293b);
306
+ --yatl-text: var(--yatl-table-text, #f1f5f9);
307
+ --yatl-text-muted: var(--yatl-table-text-muted, #94a3b8);
308
+ --yatl-border-color: var(--yatl-table-border-color, #334155);
309
+
310
+ --yatl-header-bg: var(--yatl-table-header-bg, #0f172a);
311
+ --yatl-header-text: var(--yatl-table-header-text, #cbd5e1);
312
+
313
+ --yatl-row-hover-bg: var(--yatl-table-row-hover-bg, #334155);
314
+ --yatl-row-selected-bg: var(--yatl-table-row-selected-bg, #1e3a8a);
315
+ }
316
+ }
317
+
318
+ :host {
319
+ font-family: system-ui, sans-serif;
320
+ }
321
+
322
+ .table {
323
+ background-color: var(--yatl-bg);
324
+ border: 1px solid var(--yatl-border-color);
325
+ border-radius: 6px;
326
+ }
327
+
328
+ .header.row {
329
+ background-color: var(--yatl-header-bg);
330
+ border-bottom: 1px solid var(--yatl-border-color);
331
+ font-weight: 600;
332
+ color: var(--yatl-header-text);
333
+ }
334
+
335
+ .row {
336
+ background-color: var(--yatl-bg);
337
+ border-bottom: 1px solid var(--yatl-border-color);
338
+ transition: background-color 50ms;
339
+ position: relative;
340
+ }
341
+
342
+ .row:last-child {
343
+ border-bottom: none;
344
+ }
345
+
346
+ .header .cell::after,
347
+ .row:not(.header)::after {
348
+ content: '';
349
+ position: absolute;
350
+ inset: 0;
351
+ pointer-events: none;
352
+ background-color: transparent;
353
+ transition: background-color 50ms;
354
+ z-index: 1;
355
+ }
356
+
357
+ .header .cell:hover::after,
358
+ .row:not(.header):hover::after {
359
+ background-color: rgba(0, 0, 0, 0.2);
360
+ }
361
+
362
+ .cell {
363
+ align-items: center;
364
+ padding: var(--yatl-cell-padding);
365
+ }
366
+
367
+ .header .cell {
368
+ padding: var(--yatl-header-padding);
369
+ }
370
+
371
+ .footer {
372
+ padding: 8px 12px;
373
+ background-color: var(--yatl-header-bg);
374
+ border-top: 1px solid var(--yatl-border-color);
375
+ color: var(--yatl-text-muted);
376
+ font-size: 0.8em;
377
+ }
378
+
379
+ .resizer::after {
380
+ height: 60%;
381
+ width: 1px;
382
+ background-color: color-mix(in srgb, currentColor 30%, transparent);
383
+ transition: background-color 0.2s;
384
+ }
385
+
386
+ .resizer:hover::after {
387
+ background-color: currentColor;
388
+ width: 2px;
389
+ }
390
+
391
+ .drop-indicator {
392
+ background: rgba(0, 0, 0, 0.4);
393
+ }
394
+
395
+ .message {
396
+ font-size: large;
397
+ }
398
+
399
+ /* Layout stuff
400
+ * Most of this is functional and needed
401
+ * for the table to work properly.
402
+ * Modify with caution!
403
+ */
404
+ :host {
405
+ display: block;
406
+ height: 100%;
407
+ width: 100%;
408
+ }
409
+
410
+ .table {
411
+ display: flex;
412
+ flex-direction: column;
413
+ height: 100%;
414
+ width: 100%;
415
+ min-height: 0;
416
+ overflow: auto;
417
+ box-sizing: border-box;
418
+ }
419
+
420
+ .header {
421
+ z-index: var(--header-z-index);
422
+ flex-shrink: 0;
423
+ position: sticky;
424
+ top: 0;
425
+ }
426
+
427
+ .header-content {
428
+ position: relative;
429
+ width: 100%;
430
+ display: flex;
431
+ flex-direction: row;
432
+ align-items: baseline;
433
+ gap: 0.5rem;
434
+ }
435
+
436
+ .sort-icon {
437
+ position: relative;
438
+ width: 1ch;
439
+ align-self: stretch;
440
+ padding: 0;
441
+ overflow: hidden;
442
+ flex-shrink: 0;
443
+ }
444
+
445
+ .sort-icon::after {
446
+ content: '';
447
+ position: absolute;
448
+ }
449
+
450
+ .sort-icon.descending::after {
451
+ content: '\\2191';
452
+ }
453
+
454
+ .sort-icon.ascending::after {
455
+ content: '\\2193';
456
+ }
457
+
458
+ .resizer {
459
+ position: absolute;
460
+ top: 0;
461
+ bottom: 0;
462
+ right: 0;
463
+ width: var(--yatl-resizer-width);
464
+ cursor: col-resize;
465
+ display: flex;
466
+ justify-content: center;
467
+ align-items: center;
468
+ }
469
+
470
+ .resizer::after {
471
+ content: '';
472
+ display: block;
473
+ }
474
+
475
+ .drop-indicator {
476
+ display: none;
477
+ position: absolute;
478
+ top: 0;
479
+ left: 0;
480
+ right: 0;
481
+ bottom: 0;
482
+ pointer-events: none;
483
+ z-index: calc(var(--header-z-index) + 1);
484
+ }
485
+
486
+ .drop-indicator.active {
487
+ display: block;
488
+ }
489
+
490
+ .sortable {
491
+ cursor: pointer;
492
+ }
493
+
494
+ /* Footer */
495
+ .footer {
496
+ display: flex;
497
+ align-items: center;
498
+ justify-content: space-between;
499
+ flex-shrink: 0;
500
+
501
+ position: sticky;
502
+ bottom: 0;
503
+ z-index: var(--header-z-index);
504
+ }
505
+
506
+ /* Generic table parts */
507
+ .row {
508
+ display: grid;
509
+ grid-template-columns: var(--grid-template);
510
+ min-width: 100%;
511
+ width: fit-content;
512
+ }
513
+
514
+ .cell {
515
+ white-space: nowrap;
516
+ overflow: hidden;
517
+ text-overflow: ellipsis;
518
+ position: relative;
519
+ display: flex;
520
+ align-items: center;
521
+ }
522
+
523
+ .message {
524
+ width: 100%;
525
+ height: 100%;
526
+ text-align: center;
527
+ pointer-events: none;
528
+ display: flex;
529
+ align-items: center;
530
+ justify-content: center;
531
+ }
532
+
533
+ .truncate {
534
+ display: block;
535
+ white-space: nowrap;
536
+ overflow: hidden;
537
+ text-overflow: ellipsis;
538
+ }
539
+ `;
540
+
541
+ // src/yatl-table.ts
542
+ var STATE_SAVE_DEBOUNCE = 1e3;
543
+ var DEFAULT_STORAGE_OPTIONS = {
544
+ storage: "local",
545
+ saveColumnSortOrders: true,
546
+ saveColumnVisibility: true,
547
+ saveColumnWidths: true,
548
+ saveColumnOrder: true
549
+ };
550
+ var SAVE_TRIGGERS = /* @__PURE__ */ new Set([
551
+ "searchQuery",
552
+ "filters",
553
+ "columns",
554
+ "columnSort",
555
+ "columnOrder",
556
+ "columnVisibility",
557
+ "columnWidths",
558
+ "storageOptions"
559
+ ]);
560
+ var MATCH_WEIGHTS = {
561
+ EXACT: 100,
562
+ PREFIX: 50,
563
+ SUBSTRING: 10
564
+ };
565
+ var YatlTable = class extends import_lit3.LitElement {
566
+ constructor() {
567
+ super(...arguments);
568
+ // #region --- State Data ---
569
+ // Property data
570
+ this._enableSearchTokenization = false;
571
+ this._enableSearchScoring = false;
572
+ this._columns = [];
573
+ this._columnStates = [];
574
+ this._columnOrder = [];
575
+ this._storageOptions = null;
576
+ this._data = [];
577
+ this._searchQuery = "";
578
+ this._searchIncludedFields = [];
579
+ this._searchTokenizer = whitespaceTokenizer;
580
+ this._filters = null;
581
+ this._filteredData = [];
582
+ // Flag if we have already restored the state or not.
583
+ this.hasRestoredState = false;
584
+ // save state debounce timer
585
+ this.saveTimer = 0;
586
+ // Flags set when something changes that
587
+ // requires the filter or sort logic to re-run.
588
+ this.filterDirty = false;
589
+ this.sortDirty = false;
590
+ // The last time the data was updated.
591
+ // For displaying in the footer only.
592
+ this.dataLastUpdate = null;
593
+ // Maps rows to their metadata
594
+ this.rowMetadata = /* @__PURE__ */ new WeakMap();
595
+ // List of tokens created from the current query
596
+ this.queryTokens = null;
597
+ // Column resize state
598
+ this.resizeState = null;
599
+ // Column drag & drop state
600
+ this.dragColumn = null;
601
+ this.enableVirtualScroll = false;
602
+ this.enableSearchHighlight = true;
603
+ this.enableColumnReorder = true;
604
+ this.enableFooter = false;
605
+ this.nullValuePlaceholder = "-";
606
+ this.emptyMessage = "No records to display";
607
+ this.noResultsMessage = "No matching records found";
608
+ this.rowParts = null;
609
+ // #endregion
610
+ // #region --- Event Handlers ---
611
+ this.handleHeaderClicked = (event, column) => {
612
+ const target = event.target;
613
+ if (!column.sortable || target.classList.contains("resizer")) {
614
+ return;
615
+ }
616
+ const multiSort = event.shiftKey;
617
+ const state2 = this.getColumnState(column.field);
618
+ if (!state2?.sort) {
619
+ this.sort(column.field, "asc", !multiSort);
620
+ } else if (state2.sort.order === "asc") {
621
+ this.sort(column.field, "desc", !multiSort);
622
+ } else if (state2.sort.order) {
623
+ this.sort(column.field, null, !multiSort);
624
+ }
625
+ };
626
+ this.handleCellClick = (event, row, field) => {
627
+ if (window.getSelection()?.toString()) return;
628
+ const rowIndex = this.rowMetadata.get(row).index;
629
+ this.dispatchEvent(new YatlRowClickEvent(row, rowIndex, field, event));
630
+ };
631
+ this.handleResizeMouseMove = (event) => {
632
+ if (!this.resizeState?.active) return;
633
+ requestAnimationFrame(() => {
634
+ if (!this.resizeState?.active) return;
635
+ const deltaX = event.pageX - this.resizeState.startX;
636
+ const newWidth = Math.max(50, this.resizeState.startWidth + deltaX);
637
+ this.resizeState.currentWidths[this.resizeState.columnIndex] = `${newWidth}px`;
638
+ this.tableElement.style.setProperty(
639
+ "--grid-template",
640
+ this.resizeState.currentWidths.join(" ")
641
+ );
642
+ });
643
+ };
644
+ this.handleResizeMouseUp = (_event) => {
645
+ window.removeEventListener("mousemove", this.handleResizeMouseMove);
646
+ window.removeEventListener("mouseup", this.handleResizeMouseUp);
647
+ document.body.style.cursor = "";
648
+ if (this.resizeState?.active) {
649
+ const finalWidth = parseFloat(
650
+ this.resizeState.currentWidths[this.resizeState.columnIndex]
651
+ );
652
+ const columnWidths = this.columnWidths;
653
+ const state2 = findColumn(this.resizeState.columnField, columnWidths);
654
+ state2.width = finalWidth;
655
+ this.columnWidths = columnWidths;
656
+ this.dispatchEvent(new YatlColumnResizeEvent(state2.field, state2.width));
657
+ }
658
+ this.resizeState = null;
659
+ };
660
+ this.handleDragColumnStart = (event, field) => {
661
+ const target = event.target;
662
+ if (target?.classList.contains("resizer")) {
663
+ event.preventDefault();
664
+ return;
665
+ }
666
+ if (event.dataTransfer) {
667
+ event.dataTransfer.effectAllowed = "move";
668
+ event.dataTransfer.setData("text/plain", field);
669
+ this.dragColumn = field;
670
+ }
671
+ };
672
+ this.handleDragColumnEnter = (event) => {
673
+ const cell = event.currentTarget;
674
+ cell.querySelector(".drop-indicator")?.classList.add("active");
675
+ };
676
+ this.handleDragColumnLeave = (event) => {
677
+ const cell = event.currentTarget;
678
+ const enteringElement = event.relatedTarget;
679
+ if (cell.contains(enteringElement)) {
680
+ return;
681
+ }
682
+ cell.querySelector(".drop-indicator")?.classList.remove("active");
683
+ };
684
+ this.handleDragColumnOver = (event) => {
685
+ event.preventDefault();
686
+ if (event.dataTransfer) {
687
+ event.dataTransfer.dropEffect = "move";
688
+ }
689
+ };
690
+ this.handleDragColumnDrop = (event, field) => {
691
+ if (!this.dragColumn || this.dragColumn === field) {
692
+ return;
693
+ }
694
+ event.preventDefault();
695
+ event.stopPropagation();
696
+ const newColumnOrder = [...this.columnOrder];
697
+ const dragIndex = newColumnOrder.findIndex((col) => col === this.dragColumn);
698
+ const dropIndex = newColumnOrder.findIndex((col) => col === field);
699
+ if (dragIndex > -1 && dropIndex > -1) {
700
+ const [draggedColumn] = newColumnOrder.splice(dragIndex, 1);
701
+ const droppedColumn = findColumn(field, this.columns);
702
+ if (!droppedColumn) return;
703
+ newColumnOrder.splice(dropIndex, 0, draggedColumn);
704
+ const reorderEvent = new YatlColumnReorderEvent(
705
+ draggedColumn,
706
+ droppedColumn.field,
707
+ newColumnOrder
708
+ );
709
+ if (!this.dispatchEvent(reorderEvent)) {
710
+ return;
711
+ }
712
+ this.columnOrder = [...newColumnOrder];
713
+ }
714
+ };
715
+ this.handleDragColumnEnd = () => {
716
+ this.dragColumn = null;
717
+ this.tableElement.querySelectorAll(".drop-indicator.active").forEach((element) => element.classList.remove("active"));
718
+ };
719
+ }
720
+ get enableSearchTokenization() {
721
+ return this._enableSearchTokenization;
722
+ }
723
+ set enableSearchTokenization(enable) {
724
+ if (this._enableSearchTokenization === enable) {
725
+ return;
726
+ }
727
+ const oldValue = this._enableSearchTokenization;
728
+ this._enableSearchTokenization = enable;
729
+ this.updateInternalQuery();
730
+ this.filterDirty = true;
731
+ this.requestUpdate("enableSearchTokenization", oldValue);
732
+ }
733
+ get enableSearchScoring() {
734
+ return this._enableSearchScoring;
735
+ }
736
+ set enableSearchScoring(enable) {
737
+ if (this._enableSearchScoring === enable) {
738
+ return;
739
+ }
740
+ const oldValue = this._enableSearchScoring;
741
+ this._enableSearchScoring = enable;
742
+ this.filterDirty = true;
743
+ this.requestUpdate("enableSearchScoring", oldValue);
744
+ }
745
+ get columns() {
746
+ return this._columns;
747
+ }
748
+ set columns(columns) {
749
+ if (this._columns === columns) {
750
+ return;
751
+ }
752
+ const oldValue = this._columns;
753
+ this._columns = columns;
754
+ this.filterDirty = true;
755
+ this.requestUpdate("columns", oldValue);
756
+ }
757
+ get columnOrder() {
758
+ const finalOrder = /* @__PURE__ */ new Set();
759
+ for (const field of this._columnOrder) {
760
+ const col = findColumn(field, this.columns);
761
+ if (col) {
762
+ finalOrder.add(field);
763
+ }
764
+ }
765
+ for (const col of this.columns) {
766
+ if (!finalOrder.has(col.field)) {
767
+ finalOrder.add(col.field);
768
+ }
769
+ }
770
+ return [...finalOrder];
771
+ }
772
+ set columnOrder(columns) {
773
+ if (this._columnOrder === columns) {
774
+ return;
775
+ }
776
+ const oldValue = this._columnOrder;
777
+ this._columnOrder = [...columns];
778
+ this.requestUpdate("columnOrder", oldValue);
779
+ }
780
+ get columnVisibility() {
781
+ return this.columnOrder.map((field) => ({
782
+ field,
783
+ visible: this.getColumnState(field).visible
784
+ }));
785
+ }
786
+ set columnVisibility(columns) {
787
+ const oldValue = this.columnVisibility;
788
+ let changed = false;
789
+ for (const column of columns) {
790
+ const state2 = this.getColumnState(column.field);
791
+ if (state2 && state2.visible !== column.visible) {
792
+ changed = true;
793
+ state2.visible = column.visible;
794
+ }
795
+ }
796
+ if (!changed) {
797
+ return;
798
+ }
799
+ this.requestUpdate("columnVisibility", oldValue);
800
+ }
801
+ get columnSort() {
802
+ return this.columnOrder.map((field) => ({
803
+ field,
804
+ sort: this.getColumnState(field).sort
805
+ }));
806
+ }
807
+ set columnSort(columns) {
808
+ const oldValue = this.columnSort;
809
+ let changed = false;
810
+ for (const column of columns) {
811
+ const state2 = this.getColumnState(column.field);
812
+ if (state2 && (state2.sort?.order !== column.sort?.order || state2.sort?.priority !== column.sort?.priority)) {
813
+ changed = true;
814
+ state2.sort = column.sort;
815
+ }
816
+ }
817
+ if (!changed) {
818
+ return;
819
+ }
820
+ this.sortDirty = true;
821
+ this.requestUpdate("columnSort", oldValue);
822
+ }
823
+ get columnWidths() {
824
+ return this.columnOrder.map((field) => ({
825
+ field,
826
+ width: this.getColumnState(field).width
827
+ }));
828
+ }
829
+ set columnWidths(columns) {
830
+ const oldValue = this.columnWidths;
831
+ let changed = false;
832
+ for (const column of columns) {
833
+ const state2 = this.getColumnState(column.field);
834
+ if (state2 && state2.width !== column.width) {
835
+ changed = true;
836
+ state2.width = column.width;
837
+ }
838
+ }
839
+ if (!changed) {
840
+ return;
841
+ }
842
+ this.requestUpdate("columnWidths", oldValue);
843
+ }
844
+ get searchQuery() {
845
+ return this._searchQuery;
846
+ }
847
+ set searchQuery(query2) {
848
+ if (this._searchQuery === query2) {
849
+ return;
850
+ }
851
+ const oldValue = this._searchQuery;
852
+ this._searchQuery = query2;
853
+ this.updateInternalQuery();
854
+ this.filterDirty = true;
855
+ this.requestUpdate("searchQuery", oldValue);
856
+ }
857
+ get searchIncludedFields() {
858
+ return this._searchIncludedFields;
859
+ }
860
+ set searchIncludedFields(fields) {
861
+ if (this._searchIncludedFields === fields) {
862
+ return;
863
+ }
864
+ const oldValue = this._searchIncludedFields;
865
+ this._searchIncludedFields = fields;
866
+ this.filterDirty = true;
867
+ this.requestUpdate("searchIncludedFields", oldValue);
868
+ }
869
+ get searchTokenizer() {
870
+ return this._searchTokenizer;
871
+ }
872
+ set searchTokenizer(tokenizer) {
873
+ if (this._searchTokenizer === tokenizer) {
874
+ return;
875
+ }
876
+ const oldValue = this._searchTokenizer;
877
+ this._searchTokenizer = tokenizer;
878
+ this.filterDirty = true;
879
+ this.requestUpdate("searchTokenizer", oldValue);
880
+ }
881
+ get filters() {
882
+ return this._filters;
883
+ }
884
+ set filters(filters) {
885
+ if (this._filters === filters) {
886
+ return;
887
+ }
888
+ const oldValue = this._filters;
889
+ this._filters = filters;
890
+ this.filterDirty = true;
891
+ this.requestUpdate("filters", oldValue);
892
+ }
893
+ get storageOptions() {
894
+ return this._storageOptions;
895
+ }
896
+ set storageOptions(options) {
897
+ if (this._storageOptions === options) {
898
+ return;
899
+ }
900
+ const oldValue = this._storageOptions;
901
+ this._storageOptions = options;
902
+ if (!this.hasRestoredState) {
903
+ this.loadStateFromStorage();
904
+ }
905
+ this.requestUpdate("storageOptions", oldValue);
906
+ }
907
+ get data() {
908
+ return this._data;
909
+ }
910
+ set data(value) {
911
+ const oldValue = this._data;
912
+ this._data = value;
913
+ this.dataLastUpdate = /* @__PURE__ */ new Date();
914
+ this.createMetadata();
915
+ this.filterDirty = true;
916
+ this.requestUpdate("data", oldValue);
917
+ }
918
+ get filteredData() {
919
+ if (this.filterDirty) {
920
+ this.filterRows();
921
+ } else if (this.sortDirty) {
922
+ this.sortRows();
923
+ }
924
+ this.filterDirty = false;
925
+ this.sortDirty = false;
926
+ return [...this._filteredData];
927
+ }
928
+ // #endregion
929
+ // #region --- Public Methods ---
930
+ /**
931
+ * Gets a copy of the current state of the table.
932
+ */
933
+ getState() {
934
+ return {
935
+ searchQuery: this.searchQuery,
936
+ filters: this.filters,
937
+ columnOrder: this.columnOrder,
938
+ columns: this.columns.map((column) => {
939
+ const state2 = this.getColumnState(column.field);
940
+ return {
941
+ field: column.field,
942
+ visible: state2.visible,
943
+ sort: state2.sort,
944
+ width: state2.width
945
+ };
946
+ })
947
+ };
948
+ }
949
+ /**
950
+ * Restores the table to the provided state.
951
+ * @param state - The state to restore the table to.
952
+ */
953
+ restoreState(state2) {
954
+ if ("searchQuery" in state2 && state2.searchQuery !== void 0) {
955
+ this.searchQuery = state2.searchQuery;
956
+ }
957
+ if ("filters" in state2 && state2.filters !== void 0) {
958
+ this.filters = state2.filters;
959
+ }
960
+ if ("columnOrder" in state2 && state2.columnOrder !== void 0) {
961
+ this.columnOrder = state2.columnOrder;
962
+ }
963
+ if ("columns" in state2 && state2.columns !== void 0) {
964
+ const newColumnStates = [];
965
+ for (const newState of state2.columns) {
966
+ const currentState = this.getColumnState(newState.field);
967
+ newColumnStates.push(currentState);
968
+ if (!newState) {
969
+ continue;
970
+ }
971
+ if ("visible" in newState && newState.visible !== void 0) {
972
+ currentState.visible = newState.visible;
973
+ }
974
+ if ("sort" in newState && newState.sort !== void 0) {
975
+ currentState.sort = newState.sort;
976
+ }
977
+ if ("width" in newState && newState.width !== void 0) {
978
+ currentState.width = newState.width;
979
+ }
980
+ }
981
+ this._columnStates = newColumnStates;
982
+ this.requestUpdate();
983
+ }
984
+ }
985
+ /**
986
+ * Sorts the table by a specified column and order.
987
+ * If `order` is `null`, the sort on this column is removed.
988
+ * @param field - The field name of the column to sort by.
989
+ * @param order - The sort order: 'asc', 'desc', or `null` to remove sorting for this column.
990
+ * @param clear - Clear all other sorting
991
+ */
992
+ sort(field, order, clear = true) {
993
+ const sortStates = this.columnSort;
994
+ const state2 = findColumn(field, sortStates);
995
+ if (!state2) {
996
+ throw new Error(`Cannot get options for non-existent column "${field}"`);
997
+ }
998
+ if (order === state2.sort?.order) {
999
+ return;
1000
+ }
1001
+ if (!this.dispatchEvent(new YatlSortEvent(field, order))) {
1002
+ return;
1003
+ }
1004
+ if (order && !state2.sort) {
1005
+ const priorities = sortStates.map((col) => col.sort?.priority).filter((priority2) => priority2 !== void 0);
1006
+ const maxPriority = this.columns.length + 1;
1007
+ const priority = Math.min(maxPriority, ...priorities) - 1;
1008
+ state2.sort = { order, priority };
1009
+ } else if (order && state2.sort) {
1010
+ state2.sort.order = order;
1011
+ } else {
1012
+ state2.sort = null;
1013
+ }
1014
+ if (clear) {
1015
+ for (const state3 of sortStates) {
1016
+ if (state3.field !== field) {
1017
+ state3.sort = null;
1018
+ }
1019
+ }
1020
+ }
1021
+ this.columnSort = sortStates;
1022
+ }
1023
+ /**
1024
+ * Sets the visibility of a specified column.
1025
+ * @param field - The field name of the column.
1026
+ * @param visible - `true` to show the column, `false` to hide it.
1027
+ */
1028
+ setColumnVisibility(field, visible) {
1029
+ const visibilityStates = this.columnVisibility;
1030
+ const state2 = findColumn(field, visibilityStates);
1031
+ if (!state2) {
1032
+ throw new Error(`Cannot get options for non-existent column "${field}"`);
1033
+ }
1034
+ if (state2.visible === visible) {
1035
+ return;
1036
+ }
1037
+ if (!this.dispatchEvent(new YatlColumnToggleEvent(field, visible))) {
1038
+ return;
1039
+ }
1040
+ state2.visible = visible;
1041
+ this.columnVisibility = visibilityStates;
1042
+ }
1043
+ /**
1044
+ * Toggles the visibility of hte specified column
1045
+ * @param field - The field name of the column to toggle.
1046
+ */
1047
+ toggleColumnVisibility(field) {
1048
+ const state2 = this.getColumnState(field);
1049
+ this.setColumnVisibility(field, !state2);
1050
+ }
1051
+ /**
1052
+ * Shows the specified column
1053
+ * @param field - The field name of the column to show.
1054
+ */
1055
+ showColumn(field) {
1056
+ this.setColumnVisibility(field, true);
1057
+ }
1058
+ /**
1059
+ * Hides the specified column
1060
+ * @param field - The field name of the column to hide.
1061
+ */
1062
+ hideColumn(field) {
1063
+ this.setColumnVisibility(field, false);
1064
+ }
1065
+ /**
1066
+ * Export the current visible table data to a CSV file.
1067
+ * @param filename - The name of the file to save.
1068
+ * @param all - If `true`, exports all original data (ignoring filters). If `false` (default), exports only the currently visible (filtered and sorted) rows.
1069
+ */
1070
+ export(filename, all = false) {
1071
+ const data = all ? this.data : this.filteredData;
1072
+ const rows = [...data.values()];
1073
+ const columnData = this.columnData;
1074
+ const csvHeaders = columnData.filter((col) => all || col.state?.visible).map((col) => `"${col.options.title}"`).join(",");
1075
+ const csvRows = rows.map((row) => {
1076
+ const list = [];
1077
+ for (const col of columnData) {
1078
+ let value = getNestedValue(row, col.field);
1079
+ if (all || col.state.visible) {
1080
+ if (typeof col.options.valueFormatter === "function") {
1081
+ value = col.options.valueFormatter(value, row);
1082
+ }
1083
+ value = String(value).replace('"', '""');
1084
+ list.push(`"${value}"`);
1085
+ }
1086
+ }
1087
+ return list.join(",");
1088
+ }).join("\n");
1089
+ const csvContent = csvHeaders + "\n" + csvRows;
1090
+ const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8," });
1091
+ const a = document.createElement("a");
1092
+ a.style.display = "none";
1093
+ a.href = URL.createObjectURL(blob);
1094
+ a.download = `${filename}.csv`;
1095
+ document.body.append(a);
1096
+ a.click();
1097
+ a.remove();
1098
+ }
1099
+ scrollToRow(row) {
1100
+ const index = this.data.findIndex((v) => v === row);
1101
+ if (typeof index === "number") {
1102
+ return this.scrollToOriginalIndex(index);
1103
+ } else {
1104
+ throw new Error("Row not in table");
1105
+ }
1106
+ }
1107
+ /**
1108
+ * Scrolls the table to bring the row at the specified original index into view.
1109
+ * @param index - The original index of the row (from the initial dataset).
1110
+ */
1111
+ scrollToOriginalIndex(index) {
1112
+ const rowData = this.data[index];
1113
+ if (rowData) {
1114
+ const filteredIndex = this.filteredData.indexOf(rowData);
1115
+ if (filteredIndex >= 0) {
1116
+ return this.scrollToFilteredIndex(filteredIndex);
1117
+ } else {
1118
+ throw new Error("Cannot scroll to filtered out row");
1119
+ }
1120
+ } else {
1121
+ throw new RangeError(`Row index ${index} out of range`);
1122
+ }
1123
+ }
1124
+ async scrollToFilteredIndex(index) {
1125
+ const rowData = this.filteredData[index];
1126
+ if (!rowData) {
1127
+ throw new RangeError(`Row index ${index} out of range`);
1128
+ }
1129
+ await this.updateComplete;
1130
+ if (this.virtualizer) {
1131
+ this.virtualizer.element(index)?.scrollIntoView({
1132
+ block: "start",
1133
+ behavior: "instant"
1134
+ });
1135
+ } else {
1136
+ const row = this.tableElement.querySelector(
1137
+ `.row[data-filtered-index="${index}"]`
1138
+ );
1139
+ row?.scrollIntoView({
1140
+ block: "start",
1141
+ behavior: "smooth"
1142
+ });
1143
+ }
1144
+ }
1145
+ async scrollToPx(px) {
1146
+ await this.updateComplete;
1147
+ if (this.virtualizer) {
1148
+ this.virtualizer.scrollTop = px;
1149
+ } else {
1150
+ this.tableElement.scrollTop = px;
1151
+ }
1152
+ }
1153
+ /**
1154
+ * Finds the first row
1155
+ * @param field
1156
+ * @param value
1157
+ * @returns
1158
+ */
1159
+ findRow(field, value) {
1160
+ return this.data.find((row) => {
1161
+ const rowValue = getNestedValue(row, field);
1162
+ return rowValue === value;
1163
+ });
1164
+ }
1165
+ /**
1166
+ * Finds the original index of the first row where the specified field matches the given value.
1167
+ * This searches through the original, unfiltered dataset.
1168
+ * @param field - The field name within the row data to search.
1169
+ * @param value - The value to match against the field's content.
1170
+ * @returns The original index of the found row, or -1 if no match is found.
1171
+ * @example
1172
+ * ```ts
1173
+ * const index = dataTable.indexOf('id', 12345);
1174
+ * if (index >= 0) {
1175
+ * dataTable.updateRow({description: "Updated description"}, index);
1176
+ * }
1177
+ * ```
1178
+ */
1179
+ findRowIndex(field, value) {
1180
+ const row = this.findRow(field, value);
1181
+ if (row) {
1182
+ return this.rowMetadata.get(row).index;
1183
+ }
1184
+ return -1;
1185
+ }
1186
+ /**
1187
+ * Updates the data of a row at a specific original index.
1188
+ * @param index - The original index of the row to update.
1189
+ * @param data - An object containing the new data to assign to the row. Existing fields will be updated, and new fields will be added.
1190
+ *
1191
+ * @example
1192
+ * ```ts
1193
+ * const index = dataTable.indexOf('id', 12345);
1194
+ * if (index >= 0) {
1195
+ * dataTable.updateRow(index, {description: "Updated description"});
1196
+ * }
1197
+ * ```
1198
+ */
1199
+ updateRow(index, data) {
1200
+ const current_row = this.data[index];
1201
+ if (current_row) {
1202
+ Object.assign(current_row, data);
1203
+ this.requestUpdate("data");
1204
+ }
1205
+ }
1206
+ /**
1207
+ * Deletes a row at a specific original index from the table.
1208
+ * @param index - The original index of the row to delete.
1209
+ */
1210
+ deleteRow(index) {
1211
+ this.data = this.data.toSpliced(index, 1);
1212
+ }
1213
+ // #endregion
1214
+ // #region --- Render Methods ---
1215
+ renderColumnSortIcon(column, state2) {
1216
+ return column.sortable ? import_lit3.html`<div
1217
+ part="header-sort-icon"
1218
+ class=${(0, import_class_map.classMap)({
1219
+ "sort-icon": true,
1220
+ ascending: state2.sort?.order === "asc",
1221
+ descending: state2.sort?.order === "desc"
1222
+ })}
1223
+ ></div>` : import_lit3.nothing;
1224
+ }
1225
+ renderColumnResizer(column, _state) {
1226
+ return column.resizable ? import_lit3.html`<div
1227
+ part="header-resizer"
1228
+ class="resizer"
1229
+ @click=${(event) => event.stopPropagation()}
1230
+ @mousedown=${(event) => this.handleResizeMouseDown(event, column.field)}
1231
+ ></div>` : import_lit3.nothing;
1232
+ }
1233
+ renderHeaderCell(field) {
1234
+ const column = findColumn(field, this.columns);
1235
+ const state2 = this.getColumnState(column.field);
1236
+ if (state2.visible == false) {
1237
+ return import_lit3.nothing;
1238
+ }
1239
+ return import_lit3.html`
1240
+ <div
1241
+ part="cell header-cell"
1242
+ class=${(0, import_class_map.classMap)({
1243
+ cell: true,
1244
+ sortable: column.sortable ?? false
1245
+ })}
1246
+ draggable=${(0, import_if_defined.ifDefined)(this.enableColumnReorder ? true : void 0)}
1247
+ data-field=${column.field}
1248
+ @dragstart=${(event) => this.handleDragColumnStart(event, column.field)}
1249
+ @dragenter=${this.handleDragColumnEnter}
1250
+ @dragleave=${this.handleDragColumnLeave}
1251
+ @dragover=${this.handleDragColumnOver}
1252
+ @drop=${(event) => this.handleDragColumnDrop(event, column.field)}
1253
+ @dragend=${this.handleDragColumnEnd}
1254
+ @click=${(event) => this.handleHeaderClicked(event, column)}
1255
+ >
1256
+ <div class="header-content">
1257
+ <span class="header-title truncate" part="header-title">
1258
+ ${column.title ?? toHumanReadable(column.field)}
1259
+ </span>
1260
+ ${this.renderColumnSortIcon(column, state2)}
1261
+ </div>
1262
+ ${this.renderColumnResizer(column, state2)}
1263
+ <div part="drop-indicator" class="drop-indicator"></div>
1264
+ </div>
1265
+ `;
1266
+ }
1267
+ renderHeader() {
1268
+ return import_lit3.html`
1269
+ <div part="header" class="header row">
1270
+ ${this.columnOrder.map((field) => this.renderHeaderCell(field))}
1271
+ </div>
1272
+ `;
1273
+ }
1274
+ renderCellContents(value, column, row) {
1275
+ if (column.cellRenderer) {
1276
+ return column.cellRenderer(value, column.field, row);
1277
+ }
1278
+ if (value == null) {
1279
+ return this.nullValuePlaceholder;
1280
+ }
1281
+ const indices = this.rowMetadata.get(row).highlightIndices;
1282
+ return this.enableSearchHighlight && indices ? highlightText(String(value), indices[column.field]) : value;
1283
+ }
1284
+ renderCell(field, row) {
1285
+ const column = findColumn(field, this.columns);
1286
+ const state2 = this.getColumnState(column.field);
1287
+ if (!state2.visible) {
1288
+ return import_lit3.nothing;
1289
+ }
1290
+ let value = getNestedValue(row, column.field);
1291
+ let userParts = column.cellParts?.call(this, value, column.field, row);
1292
+ if (Array.isArray(userParts)) {
1293
+ userParts = userParts.join(" ");
1294
+ }
1295
+ if (typeof column.valueFormatter === "function") {
1296
+ value = column.valueFormatter(value, row);
1297
+ }
1298
+ return import_lit3.html`
1299
+ <div
1300
+ part="cell body-cell cell-${column.field} ${userParts}"
1301
+ data-field=${column.field}
1302
+ class="cell"
1303
+ title=${(0, import_if_defined.ifDefined)(value ? String(value) : void 0)}
1304
+ @click=${(event) => this.handleCellClick(event, row, column.field)}
1305
+ >
1306
+ <span class="truncate">
1307
+ ${this.renderCellContents(value, column, row)}
1308
+ </span>
1309
+ </div>
1310
+ `;
1311
+ }
1312
+ renderRow(row, index) {
1313
+ const metadata = this.rowMetadata.get(row);
1314
+ let userParts = this.rowParts?.(row) ?? "";
1315
+ if (Array.isArray(userParts)) {
1316
+ userParts = userParts.join(" ");
1317
+ }
1318
+ return import_lit3.html`
1319
+ <div
1320
+ part=${"row " + userParts}
1321
+ class="row"
1322
+ data-index=${metadata.index}
1323
+ data-filtered-index=${index}
1324
+ >
1325
+ ${this.columnOrder.map((field) => this.renderCell(field, row))}
1326
+ </div>
1327
+ `;
1328
+ }
1329
+ renderBody() {
1330
+ if (this.columnWidths.length === 0) {
1331
+ return import_lit3.html`
1332
+ <div part="message" class="message">No visible columns.</div>
1333
+ `;
1334
+ }
1335
+ if (this.data.length === 0) {
1336
+ return import_lit3.html`<div part="message" class="message">
1337
+ ${this.emptyMessage}
1338
+ </div>`;
1339
+ }
1340
+ if (this.filteredData.length === 0) {
1341
+ return import_lit3.html`<div part="message" class="message">
1342
+ ${this.noResultsMessage}
1343
+ </div>`;
1344
+ }
1345
+ if (this.enableVirtualScroll) {
1346
+ return import_lit3.html`
1347
+ <lit-virtualizer
1348
+ .items=${this.filteredData}
1349
+ .renderItem=${(item, index) => this.renderRow(item, index)}
1350
+ ></lit-virtualizer>
1351
+ `;
1352
+ }
1353
+ return import_lit3.html`
1354
+ ${(0, import_repeat.repeat)(
1355
+ this.filteredData,
1356
+ (item) => this.rowMetadata.get(item).index,
1357
+ (item, index) => this.renderRow(item, index)
1358
+ )}
1359
+ `;
1360
+ }
1361
+ renderFooter() {
1362
+ if (!this.enableFooter) {
1363
+ return import_lit3.nothing;
1364
+ }
1365
+ const total = this.data.length;
1366
+ const filtered = this.filteredData.length;
1367
+ const fmt = new Intl.NumberFormat(void 0);
1368
+ const totalStr = fmt.format(total);
1369
+ const filteredStr = fmt.format(filtered);
1370
+ const rowCountText = total !== filtered ? `Showing ${filteredStr} of ${totalStr} records` : `Total records: ${totalStr}`;
1371
+ const formatter = Intl.DateTimeFormat(void 0, {
1372
+ dateStyle: "short",
1373
+ timeStyle: "short"
1374
+ });
1375
+ const lastUpdateText = this.dataLastUpdate ? formatter.format(this.dataLastUpdate) : "Never";
1376
+ return import_lit3.html`
1377
+ <div part="footer" class="footer">
1378
+ <slot name="footer">
1379
+ <span part="row-count">${rowCountText}</span>
1380
+ <span part="timestamp">${lastUpdateText}</span>
1381
+ </slot>
1382
+ </div>
1383
+ `;
1384
+ }
1385
+ render() {
1386
+ const gridWidths = this.getGridWidths();
1387
+ const gridTemplate = widthsToGridTemplates(gridWidths).join(" ");
1388
+ return import_lit3.html`
1389
+ <div
1390
+ part="table"
1391
+ class="table"
1392
+ style=${(0, import_style_map.styleMap)({ "--grid-template": gridTemplate })}
1393
+ >
1394
+ ${this.renderHeader()} ${this.renderBody()} ${this.renderFooter()}
1395
+ </div>
1396
+ `;
1397
+ }
1398
+ // #endregion
1399
+ // #region --- Lifecycle Methods ---
1400
+ updated(changedProperties) {
1401
+ super.updated(changedProperties);
1402
+ super.updated(changedProperties);
1403
+ const stateProps = [
1404
+ "columnOrder",
1405
+ "columnVisibility",
1406
+ "columnSort",
1407
+ "columnWidths",
1408
+ "searchQuery",
1409
+ "filters"
1410
+ ];
1411
+ const changedStateProp = stateProps.filter(
1412
+ (prop) => changedProperties.has(prop)
1413
+ );
1414
+ if (changedStateProp.length) {
1415
+ this.dispatchEvent(
1416
+ new YatlStateChangeEvent(this.getState(), changedStateProp)
1417
+ );
1418
+ }
1419
+ if (this.storageOptions?.key) {
1420
+ const shouldSave = Array.from(changedProperties.keys()).some(
1421
+ (prop) => SAVE_TRIGGERS.has(prop)
1422
+ );
1423
+ if (shouldSave) {
1424
+ this.scheduleSave();
1425
+ }
1426
+ }
1427
+ }
1428
+ disconnectedCallback() {
1429
+ super.disconnectedCallback();
1430
+ window.addEventListener("mousemove", this.handleResizeMouseMove);
1431
+ window.addEventListener("mouseup", this.handleResizeMouseUp);
1432
+ }
1433
+ // #endregion
1434
+ // #region --- Filter Methods ---
1435
+ /**
1436
+ * Calculates a relevance score for a given query against a target string.
1437
+ *
1438
+ * This function implements a tiered matching strategy:
1439
+ * 1. **Exact Match**: The query exactly matches the target. This yields the highest score.
1440
+ * 2. **Prefix Match**: The target starts with the query. This is the next most relevant.
1441
+ * 3. **Substring Match**: The target contains the query somewhere. This is the least relevant.
1442
+ *
1443
+ * The final score is weighted and adjusted by the length difference between the query and the target
1444
+ * to ensure that more specific matches (e.g., "apple" vs "application" for the query "apple") rank higher.
1445
+ *
1446
+ * @param query The search term (e.g., "app").
1447
+ * @param target The string to be searched (e.g., "Apple" or "Application").
1448
+ * @returns A numerical score representing the relevance of the match. Higher is better. Returns 0 if no match is found.
1449
+ */
1450
+ calculateSearchScore(query2, target) {
1451
+ const results = { score: 0, ranges: [] };
1452
+ if (!query2 || !target) {
1453
+ return results;
1454
+ }
1455
+ let baseScore = 0;
1456
+ let matchTypeWeight = 0;
1457
+ if (target === query2) {
1458
+ matchTypeWeight = MATCH_WEIGHTS.EXACT;
1459
+ baseScore = query2.length;
1460
+ results.ranges.push([0, target.length]);
1461
+ } else if (target.startsWith(query2)) {
1462
+ matchTypeWeight = MATCH_WEIGHTS.PREFIX;
1463
+ baseScore = query2.length;
1464
+ results.ranges.push([0, query2.length]);
1465
+ } else {
1466
+ const index = target.indexOf(query2);
1467
+ if (index !== -1) {
1468
+ matchTypeWeight = MATCH_WEIGHTS.SUBSTRING;
1469
+ baseScore = query2.length;
1470
+ let cursor = index;
1471
+ while (cursor !== -1) {
1472
+ results.ranges.push([cursor, cursor + query2.length]);
1473
+ cursor = target.indexOf(query2, cursor + 1);
1474
+ }
1475
+ } else {
1476
+ return results;
1477
+ }
1478
+ }
1479
+ const lengthDifference = target.length - query2.length;
1480
+ const specificityBonus = 1 / (1 + lengthDifference);
1481
+ results.score = baseScore * matchTypeWeight * specificityBonus;
1482
+ return results;
1483
+ }
1484
+ searchField(query2, value, tokens) {
1485
+ const result = { score: 0, ranges: [] };
1486
+ const addRangesFromValue = (searchTerm) => {
1487
+ let idx = value.indexOf(searchTerm);
1488
+ while (idx !== -1) {
1489
+ result.ranges.push([idx, idx + searchTerm.length]);
1490
+ idx = value.indexOf(searchTerm, idx + 1);
1491
+ }
1492
+ };
1493
+ if (query2.quoted || !tokens) {
1494
+ if (!this.enableSearchScoring) {
1495
+ if (value.includes(query2.value)) {
1496
+ result.score = 1;
1497
+ addRangesFromValue(query2.value);
1498
+ }
1499
+ } else {
1500
+ const calculation = this.calculateSearchScore(query2.value, value);
1501
+ result.score = calculation.score;
1502
+ result.ranges = calculation.ranges;
1503
+ }
1504
+ return result;
1505
+ }
1506
+ if (!this.enableSearchScoring) {
1507
+ const isMatch = tokens.some((token) => token.includes(query2.value));
1508
+ if (isMatch) {
1509
+ result.score = 1;
1510
+ addRangesFromValue(query2.value);
1511
+ }
1512
+ return result;
1513
+ }
1514
+ for (const token of tokens) {
1515
+ const calculation = this.calculateSearchScore(query2.value, token);
1516
+ if (calculation.score > 0) {
1517
+ result.score += calculation.score;
1518
+ addRangesFromValue(query2.value);
1519
+ }
1520
+ }
1521
+ return result;
1522
+ }
1523
+ filterField(value, filter, filterFunction = null) {
1524
+ if (Array.isArray(filter)) {
1525
+ if (filter.length === 0) {
1526
+ return true;
1527
+ }
1528
+ return filter.some(
1529
+ (element) => this.filterField(value, element, filterFunction)
1530
+ );
1531
+ }
1532
+ if (Array.isArray(value)) {
1533
+ if (value.length === 0) {
1534
+ return false;
1535
+ }
1536
+ return value.some(
1537
+ (element) => this.filterField(element, filter, filterFunction)
1538
+ );
1539
+ }
1540
+ if (typeof filterFunction === "function") {
1541
+ return filterFunction(value, filter);
1542
+ }
1543
+ if (filter instanceof RegExp) {
1544
+ return filter.test(String(value));
1545
+ }
1546
+ return filter === value;
1547
+ }
1548
+ filterRow(row, index) {
1549
+ if (!this.filters) {
1550
+ return true;
1551
+ }
1552
+ if (typeof this.filters === "function") {
1553
+ return this.filters(row, index);
1554
+ }
1555
+ for (const field in this.filters) {
1556
+ const filter = getNestedValue(this.filters, field);
1557
+ const value = getNestedValue(row, field);
1558
+ if (typeof filter === "function") {
1559
+ if (!filter(value)) {
1560
+ return false;
1561
+ }
1562
+ } else {
1563
+ const col = findColumn(field, this.columns);
1564
+ const filterCallback = col ? col.filter : void 0;
1565
+ if (!this.filterField(value, filter, filterCallback)) {
1566
+ return false;
1567
+ }
1568
+ }
1569
+ }
1570
+ return true;
1571
+ }
1572
+ filterRows() {
1573
+ const searchableFields = [...this.columnData.values()].filter((col) => col.options.searchable).map((c) => c.field);
1574
+ const fields = [...searchableFields, ...this.searchIncludedFields];
1575
+ this._filteredData = this.data.filter((row, index) => {
1576
+ const metadata = this.rowMetadata.get(row);
1577
+ metadata.searchScore = 0;
1578
+ metadata.highlightIndices = {};
1579
+ if (!this.filterRow(row, index)) {
1580
+ return false;
1581
+ }
1582
+ if (!this.queryTokens) {
1583
+ return true;
1584
+ }
1585
+ for (const field of fields) {
1586
+ const originalValue = getNestedValue(row, field);
1587
+ const compareValue = metadata.searchValues[field];
1588
+ const columnTokens = metadata.searchTokens[field];
1589
+ if (typeof originalValue !== "string" || typeof compareValue !== "string") {
1590
+ continue;
1591
+ }
1592
+ const fieldResults = { score: 0, ranges: [] };
1593
+ for (const token of this.queryTokens) {
1594
+ const results = this.searchField(token, compareValue, columnTokens);
1595
+ fieldResults.score += results.score;
1596
+ fieldResults.ranges.push(...results.ranges);
1597
+ }
1598
+ if (fieldResults.score > 0) {
1599
+ metadata.searchScore += fieldResults.score;
1600
+ metadata.highlightIndices[field] = fieldResults.ranges;
1601
+ }
1602
+ }
1603
+ return metadata.searchScore > 0;
1604
+ });
1605
+ this.filterDirty = false;
1606
+ this.sortRows();
1607
+ this.dispatchEvent(new YatlChangeEvent(this.data));
1608
+ }
1609
+ // #endregion
1610
+ // #region --- Sort Methods ---
1611
+ compareRows(a, b, field) {
1612
+ let aValue, bValue;
1613
+ const columnData = findColumn(field, this.columnData);
1614
+ if (!columnData.state.sort) {
1615
+ return 0;
1616
+ }
1617
+ const aMetadata = this.rowMetadata.get(a);
1618
+ const bMetadata = this.rowMetadata.get(b);
1619
+ if (columnData.state.sort?.order === "asc") {
1620
+ aValue = aMetadata.sortValues[columnData.field];
1621
+ bValue = bMetadata.sortValues[columnData.field];
1622
+ } else {
1623
+ aValue = bMetadata.sortValues[columnData.field];
1624
+ bValue = aMetadata.sortValues[columnData.field];
1625
+ }
1626
+ if (typeof columnData.options.sorter === "function") {
1627
+ const ret = columnData.options.sorter(aValue, bValue);
1628
+ if (ret !== 0) return ret;
1629
+ }
1630
+ const aIsNull = aValue == null;
1631
+ const bIsNull = bValue == null;
1632
+ if (aIsNull && !bIsNull) return -1;
1633
+ if (bIsNull && !aIsNull) return 1;
1634
+ if (aValue < bValue) return -1;
1635
+ if (aValue > bValue) return 1;
1636
+ return 0;
1637
+ }
1638
+ sortRows() {
1639
+ if (this.filterDirty) {
1640
+ this.filterRows();
1641
+ return;
1642
+ }
1643
+ const sortedColumns = this.columnData.filter((col) => col.state.visible && col.state.sort).sort((a, b) => b.state.sort.priority - a.state.sort.priority);
1644
+ this._filteredData = this._filteredData.toSorted((a, b) => {
1645
+ const aMetadata = this.rowMetadata.get(a);
1646
+ const bMetadata = this.rowMetadata.get(b);
1647
+ if (this.enableSearchScoring && this.queryTokens) {
1648
+ const aValue = aMetadata.searchScore || 0;
1649
+ const bValue = bMetadata.searchScore || 0;
1650
+ if (aValue > bValue) return -1;
1651
+ if (aValue < bValue) return 1;
1652
+ }
1653
+ for (const col of sortedColumns) {
1654
+ const comp = this.compareRows(a, b, col.field);
1655
+ if (comp !== 0) {
1656
+ return comp;
1657
+ }
1658
+ }
1659
+ return aMetadata.index - bMetadata.index;
1660
+ });
1661
+ this.sortDirty = false;
1662
+ }
1663
+ // #endregion
1664
+ // #region --- Utilities ---
1665
+ createMetadata() {
1666
+ this.rowMetadata = /* @__PURE__ */ new WeakMap();
1667
+ let index = 0;
1668
+ for (const row of this.data) {
1669
+ const metadata = {
1670
+ index: index++,
1671
+ searchTokens: {},
1672
+ searchValues: {},
1673
+ sortValues: {}
1674
+ };
1675
+ this.rowMetadata.set(row, metadata);
1676
+ for (const column of this.columns) {
1677
+ const value = getNestedValue(row, column.field);
1678
+ if (typeof column.sortValue === "function") {
1679
+ metadata.sortValues[column.field] = column.sortValue(value);
1680
+ } else if (typeof value === "string") {
1681
+ metadata.sortValues[column.field] = value.toLocaleLowerCase();
1682
+ } else if (isCompareable(value)) {
1683
+ metadata.sortValues[column.field] = value;
1684
+ } else {
1685
+ metadata.sortValues[column.field] = String(value);
1686
+ }
1687
+ if (typeof value === "string") {
1688
+ metadata.searchValues[column.field] = value.toLocaleLowerCase();
1689
+ }
1690
+ if (column.searchable && column.tokenize && value) {
1691
+ const tokenizer = column.searchTokenizer ?? this.searchTokenizer;
1692
+ metadata.searchTokens[column.field] = tokenizer(String(value)).map(
1693
+ (token) => token.value
1694
+ );
1695
+ }
1696
+ }
1697
+ for (const field of this.searchIncludedFields) {
1698
+ const value = getNestedValue(row, field);
1699
+ if (typeof value === "string") {
1700
+ metadata.searchValues[field] = value.toLocaleLowerCase();
1701
+ }
1702
+ }
1703
+ }
1704
+ }
1705
+ updateInternalQuery() {
1706
+ if (this.searchQuery.length === 0) {
1707
+ this.queryTokens = null;
1708
+ return;
1709
+ }
1710
+ this.queryTokens = [
1711
+ { value: this.searchQuery.toLocaleLowerCase(), quoted: true }
1712
+ ];
1713
+ if (this.enableSearchTokenization) {
1714
+ this.queryTokens.push(...this.searchTokenizer(this.searchQuery));
1715
+ }
1716
+ }
1717
+ get columnData() {
1718
+ return this.columns.map((column) => ({
1719
+ field: column.field,
1720
+ options: column,
1721
+ state: this.getColumnState(column.field)
1722
+ }));
1723
+ }
1724
+ /**
1725
+ * Gets the width of each column in the
1726
+ * order they will appear in the grid.
1727
+ */
1728
+ getGridWidths() {
1729
+ return this.columnOrder.map((field) => this.getColumnState(field)).filter((state2) => state2.visible).map((state2) => state2.width);
1730
+ }
1731
+ scheduleSave() {
1732
+ window.clearTimeout(this.saveTimer);
1733
+ this.saveTimer = window.setTimeout(() => {
1734
+ this.saveStateToStorage();
1735
+ }, STATE_SAVE_DEBOUNCE);
1736
+ }
1737
+ getColumnState(field) {
1738
+ let state2 = findColumn(field, this._columnStates);
1739
+ if (!state2) {
1740
+ state2 = {
1741
+ field,
1742
+ visible: true,
1743
+ sort: null,
1744
+ width: null
1745
+ };
1746
+ this._columnStates.push(state2);
1747
+ }
1748
+ return state2;
1749
+ }
1750
+ // #endregion
1751
+ // #region --- Storage Methods ---
1752
+ saveStateToStorage() {
1753
+ if (!this.storageOptions) {
1754
+ return;
1755
+ }
1756
+ const options = { ...DEFAULT_STORAGE_OPTIONS, ...this.storageOptions };
1757
+ const savedTableState = {
1758
+ columns: []
1759
+ };
1760
+ const tableState = this.getState();
1761
+ if (options.saveColumnOrder) {
1762
+ savedTableState.columnOrder = tableState.columnOrder;
1763
+ }
1764
+ for (const columnState of tableState.columns) {
1765
+ const savedColumnState = {
1766
+ field: columnState.field
1767
+ };
1768
+ if (options.saveColumnSortOrders) {
1769
+ savedColumnState.sort = columnState.sort;
1770
+ }
1771
+ if (options.saveColumnVisibility) {
1772
+ savedColumnState.visible = columnState.visible;
1773
+ }
1774
+ if (options.saveColumnWidths) {
1775
+ savedColumnState.width = columnState.width;
1776
+ }
1777
+ savedTableState.columns?.push(savedColumnState);
1778
+ }
1779
+ const storage = options.storage === "session" ? sessionStorage : localStorage;
1780
+ try {
1781
+ storage.setItem(options.key, JSON.stringify(savedTableState));
1782
+ } catch (error) {
1783
+ console.warn("Failed to save table state", error);
1784
+ }
1785
+ }
1786
+ loadStateFromStorage() {
1787
+ if (!this.storageOptions) {
1788
+ return;
1789
+ }
1790
+ const options = { ...DEFAULT_STORAGE_OPTIONS, ...this.storageOptions };
1791
+ const json = localStorage.getItem(options.key);
1792
+ if (!json) {
1793
+ return;
1794
+ }
1795
+ try {
1796
+ const savedTableState = JSON.parse(json);
1797
+ const tableStateToRestore = {};
1798
+ if (options.saveColumnOrder) {
1799
+ tableStateToRestore.columnOrder = savedTableState.columnOrder;
1800
+ }
1801
+ if (savedTableState.columns) {
1802
+ tableStateToRestore.columns = [];
1803
+ for (const savedColumnState of savedTableState.columns) {
1804
+ const columnStateToRestore = {
1805
+ field: savedColumnState.field
1806
+ };
1807
+ if (options.saveColumnVisibility) {
1808
+ columnStateToRestore.visible = savedColumnState.visible;
1809
+ }
1810
+ if (options.saveColumnWidths) {
1811
+ columnStateToRestore.width = savedColumnState.width;
1812
+ }
1813
+ if (options.saveColumnSortOrders) {
1814
+ columnStateToRestore.sort = savedColumnState.sort;
1815
+ }
1816
+ tableStateToRestore.columns.push(columnStateToRestore);
1817
+ }
1818
+ }
1819
+ this.restoreState(tableStateToRestore);
1820
+ this.hasRestoredState = true;
1821
+ } catch (error) {
1822
+ console.error("Failed to restore DataTable state:", error);
1823
+ }
1824
+ }
1825
+ handleResizeMouseDown(event, field) {
1826
+ event.preventDefault();
1827
+ event.stopPropagation();
1828
+ const target = event.target;
1829
+ const header = target.closest(".cell");
1830
+ if (!header) {
1831
+ return;
1832
+ }
1833
+ const columnIndex = this.columnOrder.findIndex((col) => col === field);
1834
+ if (columnIndex < 0) {
1835
+ return;
1836
+ }
1837
+ this.tableElement.querySelectorAll(".header .cell").forEach((element) => {
1838
+ const field2 = element.dataset.field;
1839
+ if (field2) {
1840
+ const state2 = this.getColumnState(field2);
1841
+ if (state2) {
1842
+ state2.width = element.getBoundingClientRect().width;
1843
+ }
1844
+ }
1845
+ });
1846
+ this.resizeState = {
1847
+ active: true,
1848
+ startX: event.pageX,
1849
+ startWidth: header.getBoundingClientRect().width,
1850
+ columnIndex,
1851
+ columnField: field,
1852
+ currentWidths: widthsToGridTemplates(this.getGridWidths())
1853
+ };
1854
+ this.tableElement.style.setProperty(
1855
+ "--grid-template",
1856
+ this.resizeState.currentWidths.join(" ")
1857
+ );
1858
+ window.addEventListener("mousemove", this.handleResizeMouseMove);
1859
+ window.addEventListener("mouseup", this.handleResizeMouseUp);
1860
+ document.body.style.cursor = "col-resize";
1861
+ }
1862
+ addEventListener(type, listener, options) {
1863
+ super.addEventListener(
1864
+ type,
1865
+ listener,
1866
+ options
1867
+ );
1868
+ }
1869
+ removeEventListener(type, listener, options) {
1870
+ super.removeEventListener(type, listener, options);
1871
+ }
1872
+ dispatchEvent(event) {
1873
+ return super.dispatchEvent(event);
1874
+ }
1875
+ // #endregion
1876
+ };
1877
+ YatlTable.styles = [yatl_table_styles_default];
1878
+ __decorateClass([
1879
+ (0, import_decorators.query)(".table")
1880
+ ], YatlTable.prototype, "tableElement", 2);
1881
+ __decorateClass([
1882
+ (0, import_decorators.query)("lit-virtualizer")
1883
+ ], YatlTable.prototype, "virtualizer", 2);
1884
+ __decorateClass([
1885
+ (0, import_decorators.state)()
1886
+ ], YatlTable.prototype, "_filteredData", 2);
1887
+ __decorateClass([
1888
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-virtual-scroll" })
1889
+ ], YatlTable.prototype, "enableVirtualScroll", 2);
1890
+ __decorateClass([
1891
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-search-highlight" })
1892
+ ], YatlTable.prototype, "enableSearchHighlight", 2);
1893
+ __decorateClass([
1894
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-search-tokenization" })
1895
+ ], YatlTable.prototype, "enableSearchTokenization", 1);
1896
+ __decorateClass([
1897
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-search-scoring" })
1898
+ ], YatlTable.prototype, "enableSearchScoring", 1);
1899
+ __decorateClass([
1900
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-column-reorder" })
1901
+ ], YatlTable.prototype, "enableColumnReorder", 2);
1902
+ __decorateClass([
1903
+ (0, import_decorators.property)({ type: Boolean, attribute: "enable-footer" })
1904
+ ], YatlTable.prototype, "enableFooter", 2);
1905
+ __decorateClass([
1906
+ (0, import_decorators.property)({ type: String, attribute: "null-value-placeholder" })
1907
+ ], YatlTable.prototype, "nullValuePlaceholder", 2);
1908
+ __decorateClass([
1909
+ (0, import_decorators.property)({ type: String, attribute: "empty-message" })
1910
+ ], YatlTable.prototype, "emptyMessage", 2);
1911
+ __decorateClass([
1912
+ (0, import_decorators.property)({ type: String, attribute: "no-results-message" })
1913
+ ], YatlTable.prototype, "noResultsMessage", 2);
1914
+ __decorateClass([
1915
+ (0, import_decorators.property)({ attribute: false })
1916
+ ], YatlTable.prototype, "columns", 1);
1917
+ __decorateClass([
1918
+ (0, import_decorators.property)({ attribute: false })
1919
+ ], YatlTable.prototype, "columnOrder", 1);
1920
+ __decorateClass([
1921
+ (0, import_decorators.property)({ attribute: false })
1922
+ ], YatlTable.prototype, "columnVisibility", 1);
1923
+ __decorateClass([
1924
+ (0, import_decorators.property)({ attribute: false })
1925
+ ], YatlTable.prototype, "columnSort", 1);
1926
+ __decorateClass([
1927
+ (0, import_decorators.property)({ attribute: false })
1928
+ ], YatlTable.prototype, "columnWidths", 1);
1929
+ __decorateClass([
1930
+ (0, import_decorators.property)({ type: String, attribute: "search-query" })
1931
+ ], YatlTable.prototype, "searchQuery", 1);
1932
+ __decorateClass([
1933
+ (0, import_decorators.property)({ type: Array, attribute: "search-included-fields" })
1934
+ ], YatlTable.prototype, "searchIncludedFields", 1);
1935
+ __decorateClass([
1936
+ (0, import_decorators.property)({ attribute: false })
1937
+ ], YatlTable.prototype, "searchTokenizer", 1);
1938
+ __decorateClass([
1939
+ (0, import_decorators.property)({ attribute: false })
1940
+ ], YatlTable.prototype, "filters", 1);
1941
+ __decorateClass([
1942
+ (0, import_decorators.property)({ attribute: false })
1943
+ ], YatlTable.prototype, "rowParts", 2);
1944
+ __decorateClass([
1945
+ (0, import_decorators.property)({ type: Object, attribute: "storage-options" })
1946
+ ], YatlTable.prototype, "storageOptions", 1);
1947
+ __decorateClass([
1948
+ (0, import_decorators.property)({ attribute: false })
1949
+ ], YatlTable.prototype, "data", 1);
1950
+ YatlTable = __decorateClass([
1951
+ (0, import_decorators.customElement)("yatl-table")
1952
+ ], YatlTable);
1953
+ // Annotate the CommonJS export names for ESM import in node:
1954
+ 0 && (module.exports = {
1955
+ YatlChangeEvent,
1956
+ YatlColumnReorderEvent,
1957
+ YatlColumnResizeEvent,
1958
+ YatlColumnToggleEvent,
1959
+ YatlEvent,
1960
+ YatlRowClickEvent,
1961
+ YatlSearchEvent,
1962
+ YatlSortEvent,
1963
+ YatlStateChangeEvent,
1964
+ YatlTable,
1965
+ createRegexTokenizer,
1966
+ findColumn,
1967
+ whitespaceTokenizer
1968
+ });
1969
+ //# sourceMappingURL=index.js.map