@internetarchive/ads-table 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.rollup.cache/Users/jeffwklein/work/archive/ads-common/packages/ads-table/dist/ads-table.d.ts +6 -2
- package/.rollup.cache/Users/jeffwklein/work/archive/ads-common/packages/ads-table/dist/ads-table.js +69 -15
- package/.rollup.cache/Users/jeffwklein/work/archive/ads-common/packages/ads-table/dist/ads-table.js.map +1 -1
- package/.rollup.cache/Users/jeffwklein/work/archive/ads-common/packages/ads-table/tsconfig.tsbuildinfo +1 -1
- package/dist/ads-table.d.ts +6 -2
- package/dist/ads-table.js +76 -15
- package/dist/ads-table.js.map +1 -1
- package/dist/index.js +87 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ads-table.ts +90 -15
- package/tsconfig.tsbuildinfo +1 -1
package/dist/ads-table.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
// interface class for a Lit component class that contains table data
|
|
3
3
|
import { css, html, LitElement, } from "lit";
|
|
4
|
-
import { property, state, query, customElement } from "lit/decorators.js";
|
|
4
|
+
import { property, state, query, queryAll, customElement, } from "lit/decorators.js";
|
|
5
5
|
import { EventHelpers } from "@internetarchive/ads-library";
|
|
6
6
|
import { getUserOS, UserOperatingSystem } from "@internetarchive/ads-library";
|
|
7
7
|
export class AdsTable extends LitElement {
|
|
@@ -9,6 +9,7 @@ export class AdsTable extends LitElement {
|
|
|
9
9
|
super(...arguments);
|
|
10
10
|
// base list of data that this class sorts
|
|
11
11
|
this.rows = [];
|
|
12
|
+
this.disableKeyboardNavigation = false;
|
|
12
13
|
this.noDataText = "No items found";
|
|
13
14
|
this.defaultSortDirection = "ascending";
|
|
14
15
|
this.sortDirection = this.defaultSortDirection;
|
|
@@ -16,6 +17,9 @@ export class AdsTable extends LitElement {
|
|
|
16
17
|
this.selectedRowIds = [];
|
|
17
18
|
this.isLoading = false;
|
|
18
19
|
}
|
|
20
|
+
getTableRowElementById(id) {
|
|
21
|
+
return Array.from(this.tableRows || []).find((row) => row.id === `row-${id}`);
|
|
22
|
+
}
|
|
19
23
|
updated(changedProperties) {
|
|
20
24
|
super.updated(changedProperties);
|
|
21
25
|
if (changedProperties.has("selectedRowIds")) {
|
|
@@ -230,29 +234,75 @@ export class AdsTable extends LitElement {
|
|
|
230
234
|
// emit event so users can hook into this event
|
|
231
235
|
this.emitEvent("row-double-click", { row: clickedRow });
|
|
232
236
|
}
|
|
233
|
-
//
|
|
237
|
+
// default global keyboard events implemented through this method.
|
|
238
|
+
// event.stopImmediatePropagation() in DOM keyboard event listeners will
|
|
239
|
+
// prevent this method from being called.
|
|
234
240
|
onKeyDown(event) {
|
|
235
|
-
|
|
241
|
+
if (this.disableKeyboardNavigation) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
236
244
|
switch (event.key) {
|
|
237
245
|
case "ArrowUp":
|
|
238
246
|
case "ArrowDown":
|
|
239
247
|
event.preventDefault();
|
|
240
|
-
|
|
241
|
-
(_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
242
|
-
return this.onUpDownArrowKey(event.key);
|
|
248
|
+
return this.onUpDownArrowKey(event);
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
251
|
+
// listener applies when column has focus
|
|
252
|
+
onColumnKeyDown(event, column) {
|
|
253
|
+
if (this.disableKeyboardNavigation) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
switch (event.key) {
|
|
257
|
+
case "Enter":
|
|
258
|
+
return this.onColumnClick(column);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// listener applies when row has focus
|
|
262
|
+
onRowKeyDown(event, row, index) {
|
|
263
|
+
if (this.disableKeyboardNavigation) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
switch (event.key) {
|
|
267
|
+
// enter to select, enter again to navigate within, shift + enter to deselect (and select), while in multiselect
|
|
268
|
+
case "Enter":
|
|
269
|
+
if (this.isSelected(row) &&
|
|
270
|
+
!event.shiftKey &&
|
|
271
|
+
this.selectedRows.length === 1) {
|
|
272
|
+
return this.onRowClick(event, row, index);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
event.stopImmediatePropagation();
|
|
276
|
+
return this.toggleRowSelected(row.id);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
onUpDownArrowKey(event) {
|
|
281
|
+
var _a;
|
|
282
|
+
if (this.rows.length === 0) {
|
|
283
|
+
// there are no rows to navigate or select with arrows. avoids array out of bounds.
|
|
249
284
|
return;
|
|
250
285
|
}
|
|
251
|
-
|
|
252
|
-
const indexOffset = key === "ArrowUp" ? -1 : 1;
|
|
286
|
+
const indexOffset = event.key === "ArrowUp" ? -1 : 1;
|
|
253
287
|
const newSelectedRowIndex = this.constrainIndex(this.indexOfLastSelectedRow + indexOffset);
|
|
254
288
|
const newSelectedRowId = this.rows[newSelectedRowIndex].id;
|
|
255
|
-
|
|
289
|
+
if (event.shiftKey) {
|
|
290
|
+
// - focus and (maybe) select and focus the prev or next, if it exists
|
|
291
|
+
this.groupRowSelect(newSelectedRowIndex);
|
|
292
|
+
}
|
|
293
|
+
else if (this.selectedRowIds.length === 0) {
|
|
294
|
+
// select the first row if none are selected
|
|
295
|
+
const firstRowId = this.rows[0] ? this.rows[0].id : undefined;
|
|
296
|
+
if (firstRowId) {
|
|
297
|
+
this.selectedRowIds = [firstRowId];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
// offset in the proper direction of the arrow
|
|
302
|
+
this.selectedRowIds = [newSelectedRowId];
|
|
303
|
+
}
|
|
304
|
+
// always try to focus the next element in the direction of the arrow if you can
|
|
305
|
+
(_a = this.getTableRowElementById(newSelectedRowId)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
256
306
|
}
|
|
257
307
|
// ensures index values are kept to the closest in-bounds index
|
|
258
308
|
constrainIndex(index) {
|
|
@@ -260,19 +310,21 @@ export class AdsTable extends LitElement {
|
|
|
260
310
|
}
|
|
261
311
|
connectedCallback() {
|
|
262
312
|
super.connectedCallback();
|
|
263
|
-
// attach keyboard listener
|
|
313
|
+
// attach keyboard listener for arrow keys
|
|
264
314
|
window.addEventListener("keydown", (e) => this.onKeyDown(e));
|
|
265
315
|
}
|
|
266
316
|
render() {
|
|
267
317
|
return html `
|
|
268
|
-
<table id="main-table"
|
|
318
|
+
<table id="main-table">
|
|
269
319
|
<thead>
|
|
270
320
|
<tr>
|
|
271
321
|
${this.visibleColumns.map((column) => html `
|
|
272
322
|
<th
|
|
273
323
|
@click=${() => this.onColumnClick(column)}
|
|
324
|
+
@keydown=${(e) => this.onColumnKeyDown(e, column)}
|
|
274
325
|
class=${column.dataType.compare ? "sortable" : ""}
|
|
275
326
|
style=${`flex: ${column.flexRatio}`}
|
|
327
|
+
tabindex="0"
|
|
276
328
|
>
|
|
277
329
|
${column.label}
|
|
278
330
|
${column.dataType.compare
|
|
@@ -288,9 +340,12 @@ export class AdsTable extends LitElement {
|
|
|
288
340
|
<tr
|
|
289
341
|
@click=${(e) => this.onRowClick(e, row, index)}
|
|
290
342
|
@dblclick=${() => this.onRowDoubleClick(row)}
|
|
343
|
+
@keydown=${(e) => this.onRowKeyDown(e, row, index)}
|
|
291
344
|
class=${this.isSelected(row) ? "row-selected" : ""}
|
|
292
345
|
data-row-selected=${this.isSelected(row)}
|
|
293
346
|
data-id=${row.id}
|
|
347
|
+
id=${"row-" + row.id}
|
|
348
|
+
tabindex="0"
|
|
294
349
|
>
|
|
295
350
|
${this.visibleColumns.map((column) => html `
|
|
296
351
|
<td style=${`flex: ${column.flexRatio}`}>
|
|
@@ -392,9 +447,15 @@ AdsTable.styles = css `
|
|
|
392
447
|
__decorate([
|
|
393
448
|
query("#main-table")
|
|
394
449
|
], AdsTable.prototype, "tableElement", void 0);
|
|
450
|
+
__decorate([
|
|
451
|
+
queryAll("table tr")
|
|
452
|
+
], AdsTable.prototype, "tableRows", void 0);
|
|
395
453
|
__decorate([
|
|
396
454
|
property({ type: Array })
|
|
397
455
|
], AdsTable.prototype, "rows", void 0);
|
|
456
|
+
__decorate([
|
|
457
|
+
property({ type: Boolean })
|
|
458
|
+
], AdsTable.prototype, "disableKeyboardNavigation", void 0);
|
|
398
459
|
__decorate([
|
|
399
460
|
state()
|
|
400
461
|
], AdsTable.prototype, "sortDirection", void 0);
|
package/dist/ads-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ads-table.js","sourceRoot":"","sources":["../src/ads-table.ts"],"names":[],"mappings":"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","sourcesContent":["// interface class for a Lit component class that contains table data\nimport {\n css,\n CSSResultGroup,\n html,\n LitElement,\n PropertyValues,\n TemplateResult,\n} from \"lit\";\nimport {\n SortComparisonFunction,\n TableColumn,\n TableDataType,\n TableRow,\n} from \"./types\";\nimport { property, state, query, customElement } from \"lit/decorators.js\";\nimport { EventHelpers } from \"@internetarchive/ads-library\";\nimport { getUserOS, UserOperatingSystem } from \"@internetarchive/ads-library\";\n\nexport abstract class AdsTable<T> extends LitElement {\n @query(\"#main-table\") tableElement: HTMLTableElement | undefined;\n\n // base list of data that this class sorts\n @property({ type: Array }) rows: TableRow<T>[] = [];\n\n // abstract members to override\n protected abstract columns: TableColumn<T>[];\n protected abstract sortKey: keyof T | undefined;\n protected abstract secondarySortKey: keyof T | undefined;\n\n protected noDataText: string = \"No items found\";\n\n protected readonly defaultSortDirection: \"ascending\" | \"descending\" =\n \"ascending\";\n\n @state() protected sortDirection: \"ascending\" | \"descending\" =\n this.defaultSortDirection;\n\n // list of selected rows in order of least to most recently added\n @state() protected selectedRowIds: string[] = [];\n\n @state() isLoading: boolean = false;\n\n protected override updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n if (changedProperties.has(\"selectedRowIds\")) {\n // report selected rows to parent via an event\n this.emitEvent(\"row-select\", { selectedRows: this.selectedRows });\n }\n\n // if rows change, re-ensure selected rows exist in table\n if (this.rowsDidUpdate(changedProperties)) {\n this.filterSelectedRowsToExistingRows();\n }\n }\n\n // rather than compare references, determine if 'this.rows' has updated. an update occurs if:\n // - row list is a different size\n // - any elements in the sorted list may have changed place\n protected rowsDidUpdate(changedProperties: PropertyValues): boolean {\n // if the sort properties change, assume the elements have rearranged\n if (\n changedProperties.has(\"sortKey\") ||\n changedProperties.has(\"sortDirection\")\n ) {\n return true;\n }\n if (!changedProperties.has(\"rows\") || !changedProperties.get(\"rows\")) {\n return false;\n }\n const oldRowIds: string[] = (\n changedProperties.get(\"rows\") as TableRow<T>[]\n ).map((row: TableRow<T>) => row.id);\n // first check length. if list length changes, rows have changed.\n if (oldRowIds.length !== this.rows.length) {\n return true;\n }\n // otherwise, if they're the same size, compare individual items and ensure they're the same set of items\n const newRowsIdsSet: Set<string> = new Set(this.rows.map((row) => row.id));\n return !oldRowIds.every((id) => newRowsIdsSet.has(id));\n }\n\n protected emitEvent(eventName: string, detail = {}) {\n this.dispatchEvent(\n EventHelpers.createEvent(eventName, detail ? { detail } : {}),\n );\n }\n\n protected get visibleColumns(): TableColumn<T>[] {\n return this.columns.filter(({ isHidden }) => !isHidden);\n }\n\n protected get rowsById(): { [key: string]: TableRow<T> } {\n return Object.fromEntries<TableRow<T>>(\n this.rows.map((row) => [row.id, row]),\n );\n }\n\n protected get sortedRows(): TableRow<T>[] {\n // if sorting has been done already, return the rows as-is.\n if (this.selectedColumn.preSorted) {\n return this.rows;\n }\n const sortByPrimaryKey = this.getSortFunction(\n this.sortColumnDataType,\n this.sortDirection,\n );\n const sortBySecondaryKey = this.getSortFunction(\n this.secondarySortDataType,\n this.secondarySortDataType?.defaultSortDirection || this.sortDirection,\n );\n return this.rows.sort((rowA, rowB) => {\n // sort by primary key: the selected column and direction\n const sortResult = sortByPrimaryKey?.(rowA.data, rowB.data) || 0;\n // if sort result on primary sort key is inconclusive, use secondary sort data type\n if (sortResult === 0) {\n return sortBySecondaryKey?.(rowA.data, rowB.data) || 0;\n } else {\n return sortResult;\n }\n });\n }\n\n // rows highlighted by user\n protected get selectedRows(): TableRow<T>[] {\n return this.selectedRowIds.map((id) => this.rowsById[id]).filter((x) => x);\n }\n\n // the column you are currently sorting by\n protected get selectedColumn(): TableColumn<T> {\n return this.columnByKey[this.sortKey as string];\n }\n\n // handler for when a user clicks on a column header\n protected onColumnClick(\n column: TableColumn<T>,\n defaultSortDirection: \"ascending\" | \"descending\" = this\n .defaultSortDirection,\n ): void {\n if (this.sortKey === column.key) {\n // toggle the sort direction if the column you are clicking is already sorted\n this.sortDirection =\n this.sortDirection === \"ascending\" ? \"descending\" : \"ascending\";\n } else {\n // otherwise, sort by the column you clicked on, and in the default sort direction\n this.sortKey = column.key;\n this.sortDirection =\n column.dataType.defaultSortDirection || defaultSortDirection;\n }\n this.emitEvent(\"column-click\", {\n column,\n sortKey: this.sortKey,\n sortDirection: this.sortDirection,\n });\n }\n\n // a map of column keys to their respective data types so we don't have to call .find everywhere\n protected get columnByKey(): {\n [columnKey: string]: TableColumn<T>;\n } {\n return Object.fromEntries<TableColumn<T>>(\n this.columns.map((col) => [col.key, col]),\n );\n }\n\n // data type of the currently sorted column\n protected get sortColumnDataType(): TableDataType<T> | undefined {\n if (this.sortKey) {\n return this.columnByKey[this.sortKey as string].dataType;\n } else {\n return undefined;\n }\n }\n\n // data type of the secondary sort column\n protected get secondarySortDataType(): TableDataType<T> | undefined {\n if (this.secondarySortKey) {\n return this.columnByKey[this.secondarySortKey as string].dataType;\n } else {\n return undefined;\n }\n }\n\n // swaps the parameters of the sort function to reverse the sort direction\n protected getSortFunction(\n dataType: TableDataType<T> | undefined,\n sortDirection: \"ascending\" | \"descending\",\n ): SortComparisonFunction<T> | undefined {\n if (!dataType) {\n return undefined;\n }\n if (sortDirection === \"ascending\") {\n // return the original comparison function\n return dataType.compare;\n } else if (dataType.compare !== undefined) {\n // swap compare function parameters for descending\n return (a, b) => dataType.compare?.(b, a) || 0;\n } else {\n return undefined;\n }\n }\n\n protected renderArrowIcon(columnKey: keyof T): TemplateResult {\n if (columnKey !== this.sortKey) {\n return html``;\n } else if (this.sortDirection === \"ascending\") {\n return html`▲`;\n } else {\n return html`▼`;\n }\n }\n\n protected get selectedRowIdsSet(): Set<string> {\n return new Set(this.selectedRowIds);\n }\n\n protected get rowIdsSet(): Set<string> {\n return new Set(this.rows.map((row) => row.id));\n }\n\n protected isSelected(row: TableRow<T>): boolean {\n return this.selectedRowIdsSet.has(row.id);\n }\n\n protected toggleRowSelected(rowId: string): void {\n if (this.selectedRowIdsSet.has(rowId)) {\n // row is already selected: filter out clicked id\n this.selectedRowIds = this.selectedRowIds.filter((id) => id !== rowId);\n } else {\n // row is not yet selected: append clicked id\n this.selectedRowIds = [...this.selectedRowIds, rowId];\n }\n }\n\n protected get lastSelectedRowId(): string {\n return this.selectedRowIds[this.selectedRowIds.length - 1];\n }\n\n protected get indexOfLastSelectedRow(): number {\n return this.rows.findIndex((row) => row.id === this.lastSelectedRowId);\n }\n\n // select rows in order from the last selected element up til the given index\n protected groupRowSelect(rowIndex: number): void {\n const getRowsToAdd = (): TableRow<T>[] => {\n // get rows between index of last selected until index of selected row\n if (rowIndex > this.indexOfLastSelectedRow) {\n return this.rows.filter(\n (_, i) => rowIndex >= i && i >= this.indexOfLastSelectedRow,\n );\n } else {\n // reverse order of adding rows since clicked index is lower than last selected\n return this.rows\n .filter((_, i) => this.indexOfLastSelectedRow >= i && i >= rowIndex)\n .reverse();\n }\n };\n const rowIdsToAdd: string[] = getRowsToAdd().map((row) => row.id);\n const rowIdsSet: Set<string> = new Set(rowIdsToAdd);\n // first remove ids you are about to re-add, so they'll be in renewed order\n this.selectedRowIds = this.selectedRowIds.filter(\n (id) => !rowIdsSet.has(id),\n );\n // finally, add the new rows\n this.selectedRowIds = [...this.selectedRowIds, ...rowIdsToAdd];\n }\n\n protected onRowClick(\n event: MouseEvent,\n clickedRow: TableRow<T>,\n rowIndex: number,\n ): void {\n const userOs = getUserOS();\n // meta (cmd) key for mac, control key for non-mac\n const macHoldingHotKey =\n userOs === UserOperatingSystem.MAC && event.metaKey;\n const nonMacHoldingHotKey =\n userOs !== UserOperatingSystem.MAC && event.ctrlKey;\n // if holding meta on mac or ctrl on windows/linux, toggle individual row selection\n if (macHoldingHotKey || nonMacHoldingHotKey) {\n this.toggleRowSelected(clickedRow.id);\n } else if (event.shiftKey) {\n // if holding shift, select rows between this selection and the last selection\n this.groupRowSelect(rowIndex);\n } else {\n // clicking a row will select just that row.\n this.selectedRowIds = [clickedRow.id];\n }\n this.filterSelectedRowsToExistingRows();\n // emit event so users can hook into this action\n this.emitEvent(\"row-click\", { row: clickedRow });\n }\n\n // filter selected down to rows that actually exist in the table\n protected filterSelectedRowsToExistingRows() {\n this.selectedRowIds = this.selectedRowIds.filter((id) =>\n this.rowIdsSet.has(id),\n );\n }\n\n protected onRowDoubleClick(clickedRow: TableRow<T>): void {\n // emit event so users can hook into this event\n this.emitEvent(\"row-double-click\", { row: clickedRow });\n }\n\n // All keyboard events implemented through this method.\n protected onKeyDown(event: KeyboardEvent): void {\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowDown\":\n event.preventDefault();\n // shift focus to table element when navigating with arrow keys\n this.tableElement?.focus();\n return this.onUpDownArrowKey(event.key);\n }\n }\n\n protected onUpDownArrowKey(key: \"ArrowUp\" | \"ArrowDown\"): void {\n if (this.selectedRowIds.length === 0) {\n // select the first row if none are selected\n this.selectedRowIds = [this.rows[0].id];\n return;\n }\n // offset in the proper direction of the arrow\n const indexOffset = key === \"ArrowUp\" ? -1 : 1;\n const newSelectedRowIndex = this.constrainIndex(\n this.indexOfLastSelectedRow + indexOffset,\n );\n const newSelectedRowId = this.rows[newSelectedRowIndex].id;\n this.selectedRowIds = [newSelectedRowId];\n }\n\n // ensures index values are kept to the closest in-bounds index\n protected constrainIndex(index: number): number {\n return Math.max(Math.min(index, this.rows.length - 1), 0);\n }\n\n connectedCallback() {\n super.connectedCallback();\n // attach keyboard listener\n window.addEventListener(\"keydown\", (e: KeyboardEvent) => this.onKeyDown(e));\n }\n\n render() {\n return html`\n <table id=\"main-table\" tabindex=\"0\">\n <thead>\n <tr>\n ${this.visibleColumns.map(\n (column) => html`\n <th\n @click=${() => this.onColumnClick(column)}\n class=${column.dataType.compare ? \"sortable\" : \"\"}\n style=${`flex: ${column.flexRatio}`}\n >\n ${column.label}\n ${column.dataType.compare\n ? html`<span>${this.renderArrowIcon(column.key)}</span>`\n : \"\"}\n </th>\n `,\n )}\n </tr>\n </thead>\n <tbody>\n ${!this.isLoading\n ? this.sortedRows.map(\n (row, index) => html`\n <tr\n @click=${(e: MouseEvent) => this.onRowClick(e, row, index)}\n @dblclick=${() => this.onRowDoubleClick(row)}\n class=${this.isSelected(row) ? \"row-selected\" : \"\"}\n data-row-selected=${this.isSelected(row)}\n data-id=${row.id}\n >\n ${this.visibleColumns.map(\n (column) => html`\n <td style=${`flex: ${column.flexRatio}`}>\n ${column.dataType.format(row.data)}\n </td>\n `,\n )}\n </tr>\n `,\n )\n : html`\n <tr>\n <td class=\"no-data\">Loading...</td>\n </tr>\n `}\n ${!this.isLoading && this.sortedRows.length === 0\n ? html`\n <tr>\n <td class=\"no-data\">${this.noDataText}</td>\n </tr>\n `\n : null}\n </tbody>\n </table>\n `;\n }\n\n static styles: CSSResultGroup = css`\n table {\n display: flex;\n flex-direction: column;\n user-select: none;\n border-collapse: collapse;\n }\n\n thead,\n tbody {\n display: flex;\n flex-direction: column;\n }\n\n thead {\n background: #2a282c;\n }\n\n tbody {\n scrollbar-gutter: stable;\n }\n\n tr {\n display: flex;\n width: 100%;\n min-height: 40px;\n flex-shrink: 0;\n }\n\n tr.row-selected {\n background: #ddebff;\n }\n\n td.no-data {\n font-style: italic;\n justify-content: center;\n }\n\n td,\n th {\n display: flex;\n flex: 1;\n justify-content: flex-start;\n align-items: center;\n padding: 0 12px;\n height: 40px;\n\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n }\n\n th {\n color: white;\n }\n\n th.sortable {\n cursor: pointer;\n }\n\n th.sortable:hover {\n background: #525252;\n }\n\n th span {\n padding-left: 5px;\n }\n\n td {\n border-bottom: 1px solid #bbbbbb;\n }\n `;\n}\n\n// a simple, generic, out-of-the box implementation of AdsTable\n@customElement(\"ads-simple-table\")\nexport class AdsSimpleTable<T> extends AdsTable<T> {\n // columns are exposed as a parameter like rows, not a class member to implement\n @property({ type: Array }) columns: TableColumn<T>[] = [];\n\n @property({ type: String }) secondarySortKey: keyof T | undefined = undefined;\n\n // sort key is automatically held in state\n @state() sortKey: keyof T | undefined = this.columns[0]?.key;\n\n protected override updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n if (changedProperties.has(\"columns\")) {\n this.sortKey = this.columns[0]?.key;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ads-table.js","sourceRoot":"","sources":["../src/ads-table.ts"],"names":[],"mappings":"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","sourcesContent":["// interface class for a Lit component class that contains table data\nimport {\n css,\n CSSResultGroup,\n html,\n LitElement,\n PropertyValues,\n TemplateResult,\n} from \"lit\";\nimport {\n SortComparisonFunction,\n TableColumn,\n TableDataType,\n TableRow,\n} from \"./types\";\nimport {\n property,\n state,\n query,\n queryAll,\n customElement,\n} from \"lit/decorators.js\";\nimport { EventHelpers } from \"@internetarchive/ads-library\";\nimport { getUserOS, UserOperatingSystem } from \"@internetarchive/ads-library\";\n\nexport abstract class AdsTable<T> extends LitElement {\n @query(\"#main-table\") tableElement: HTMLTableElement | undefined;\n\n @queryAll(\"table tr\") tableRows: HTMLTableRowElement[] | undefined;\n\n protected getTableRowElementById(\n id: string,\n ): HTMLTableRowElement | undefined {\n return Array.from(this.tableRows || []).find(\n (row) => row.id === `row-${id}`,\n );\n }\n\n // base list of data that this class sorts\n @property({ type: Array }) rows: TableRow<T>[] = [];\n\n @property({ type: Boolean }) disableKeyboardNavigation: boolean = false;\n\n // abstract members to override\n protected abstract columns: TableColumn<T>[];\n protected abstract sortKey: keyof T | undefined;\n protected abstract secondarySortKey: keyof T | undefined;\n\n protected noDataText: string = \"No items found\";\n\n protected readonly defaultSortDirection: \"ascending\" | \"descending\" =\n \"ascending\";\n\n @state() protected sortDirection: \"ascending\" | \"descending\" =\n this.defaultSortDirection;\n\n // list of selected rows in order of least to most recently added\n @state() protected selectedRowIds: string[] = [];\n\n @state() isLoading: boolean = false;\n\n protected override updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n if (changedProperties.has(\"selectedRowIds\")) {\n // report selected rows to parent via an event\n this.emitEvent(\"row-select\", { selectedRows: this.selectedRows });\n }\n\n // if rows change, re-ensure selected rows exist in table\n if (this.rowsDidUpdate(changedProperties)) {\n this.filterSelectedRowsToExistingRows();\n }\n }\n\n // rather than compare references, determine if 'this.rows' has updated. an update occurs if:\n // - row list is a different size\n // - any elements in the sorted list may have changed place\n protected rowsDidUpdate(changedProperties: PropertyValues): boolean {\n // if the sort properties change, assume the elements have rearranged\n if (\n changedProperties.has(\"sortKey\") ||\n changedProperties.has(\"sortDirection\")\n ) {\n return true;\n }\n if (!changedProperties.has(\"rows\") || !changedProperties.get(\"rows\")) {\n return false;\n }\n const oldRowIds: string[] = (\n changedProperties.get(\"rows\") as TableRow<T>[]\n ).map((row: TableRow<T>) => row.id);\n // first check length. if list length changes, rows have changed.\n if (oldRowIds.length !== this.rows.length) {\n return true;\n }\n // otherwise, if they're the same size, compare individual items and ensure they're the same set of items\n const newRowsIdsSet: Set<string> = new Set(this.rows.map((row) => row.id));\n return !oldRowIds.every((id) => newRowsIdsSet.has(id));\n }\n\n protected emitEvent(eventName: string, detail = {}) {\n this.dispatchEvent(\n EventHelpers.createEvent(eventName, detail ? { detail } : {}),\n );\n }\n\n protected get visibleColumns(): TableColumn<T>[] {\n return this.columns.filter(({ isHidden }) => !isHidden);\n }\n\n protected get rowsById(): { [key: string]: TableRow<T> } {\n return Object.fromEntries<TableRow<T>>(\n this.rows.map((row) => [row.id, row]),\n );\n }\n\n protected get sortedRows(): TableRow<T>[] {\n // if sorting has been done already, return the rows as-is.\n if (this.selectedColumn.preSorted) {\n return this.rows;\n }\n const sortByPrimaryKey = this.getSortFunction(\n this.sortColumnDataType,\n this.sortDirection,\n );\n const sortBySecondaryKey = this.getSortFunction(\n this.secondarySortDataType,\n this.secondarySortDataType?.defaultSortDirection || this.sortDirection,\n );\n return this.rows.sort((rowA, rowB) => {\n // sort by primary key: the selected column and direction\n const sortResult = sortByPrimaryKey?.(rowA.data, rowB.data) || 0;\n // if sort result on primary sort key is inconclusive, use secondary sort data type\n if (sortResult === 0) {\n return sortBySecondaryKey?.(rowA.data, rowB.data) || 0;\n } else {\n return sortResult;\n }\n });\n }\n\n // rows highlighted by user\n protected get selectedRows(): TableRow<T>[] {\n return this.selectedRowIds.map((id) => this.rowsById[id]).filter((x) => x);\n }\n\n // the column you are currently sorting by\n protected get selectedColumn(): TableColumn<T> {\n return this.columnByKey[this.sortKey as string];\n }\n\n // handler for when a user clicks on a column header\n protected onColumnClick(\n column: TableColumn<T>,\n defaultSortDirection: \"ascending\" | \"descending\" = this\n .defaultSortDirection,\n ): void {\n if (this.sortKey === column.key) {\n // toggle the sort direction if the column you are clicking is already sorted\n this.sortDirection =\n this.sortDirection === \"ascending\" ? \"descending\" : \"ascending\";\n } else {\n // otherwise, sort by the column you clicked on, and in the default sort direction\n this.sortKey = column.key;\n this.sortDirection =\n column.dataType.defaultSortDirection || defaultSortDirection;\n }\n this.emitEvent(\"column-click\", {\n column,\n sortKey: this.sortKey,\n sortDirection: this.sortDirection,\n });\n }\n\n // a map of column keys to their respective data types so we don't have to call .find everywhere\n protected get columnByKey(): {\n [columnKey: string]: TableColumn<T>;\n } {\n return Object.fromEntries<TableColumn<T>>(\n this.columns.map((col) => [col.key, col]),\n );\n }\n\n // data type of the currently sorted column\n protected get sortColumnDataType(): TableDataType<T> | undefined {\n if (this.sortKey) {\n return this.columnByKey[this.sortKey as string].dataType;\n } else {\n return undefined;\n }\n }\n\n // data type of the secondary sort column\n protected get secondarySortDataType(): TableDataType<T> | undefined {\n if (this.secondarySortKey) {\n return this.columnByKey[this.secondarySortKey as string].dataType;\n } else {\n return undefined;\n }\n }\n\n // swaps the parameters of the sort function to reverse the sort direction\n protected getSortFunction(\n dataType: TableDataType<T> | undefined,\n sortDirection: \"ascending\" | \"descending\",\n ): SortComparisonFunction<T> | undefined {\n if (!dataType) {\n return undefined;\n }\n if (sortDirection === \"ascending\") {\n // return the original comparison function\n return dataType.compare;\n } else if (dataType.compare !== undefined) {\n // swap compare function parameters for descending\n return (a, b) => dataType.compare?.(b, a) || 0;\n } else {\n return undefined;\n }\n }\n\n protected renderArrowIcon(columnKey: keyof T): TemplateResult {\n if (columnKey !== this.sortKey) {\n return html``;\n } else if (this.sortDirection === \"ascending\") {\n return html`▲`;\n } else {\n return html`▼`;\n }\n }\n\n protected get selectedRowIdsSet(): Set<string> {\n return new Set(this.selectedRowIds);\n }\n\n protected get rowIdsSet(): Set<string> {\n return new Set(this.rows.map((row) => row.id));\n }\n\n protected isSelected(row: TableRow<T>): boolean {\n return this.selectedRowIdsSet.has(row.id);\n }\n\n protected toggleRowSelected(rowId: string): void {\n if (this.selectedRowIdsSet.has(rowId)) {\n // row is already selected: filter out clicked id\n this.selectedRowIds = this.selectedRowIds.filter((id) => id !== rowId);\n } else {\n // row is not yet selected: append clicked id\n this.selectedRowIds = [...this.selectedRowIds, rowId];\n }\n }\n\n protected get lastSelectedRowId(): string {\n return this.selectedRowIds[this.selectedRowIds.length - 1];\n }\n\n protected get indexOfLastSelectedRow(): number {\n return this.rows.findIndex((row) => row.id === this.lastSelectedRowId);\n }\n\n // select rows in order from the last selected element up til the given index\n protected groupRowSelect(rowIndex: number): void {\n const getRowsToAdd = (): TableRow<T>[] => {\n // get rows between index of last selected until index of selected row\n if (rowIndex > this.indexOfLastSelectedRow) {\n return this.rows.filter(\n (_, i) => rowIndex >= i && i >= this.indexOfLastSelectedRow,\n );\n } else {\n // reverse order of adding rows since clicked index is lower than last selected\n return this.rows\n .filter((_, i) => this.indexOfLastSelectedRow >= i && i >= rowIndex)\n .reverse();\n }\n };\n const rowIdsToAdd: string[] = getRowsToAdd().map((row) => row.id);\n const rowIdsSet: Set<string> = new Set(rowIdsToAdd);\n // first remove ids you are about to re-add, so they'll be in renewed order\n this.selectedRowIds = this.selectedRowIds.filter(\n (id) => !rowIdsSet.has(id),\n );\n // finally, add the new rows\n this.selectedRowIds = [...this.selectedRowIds, ...rowIdsToAdd];\n }\n\n protected onRowClick(\n event: MouseEvent | KeyboardEvent,\n clickedRow: TableRow<T>,\n rowIndex: number,\n ): void {\n const userOs = getUserOS();\n // meta (cmd) key for mac, control key for non-mac\n const macHoldingHotKey =\n userOs === UserOperatingSystem.MAC && event.metaKey;\n const nonMacHoldingHotKey =\n userOs !== UserOperatingSystem.MAC && event.ctrlKey;\n // if holding meta on mac or ctrl on windows/linux, toggle individual row selection\n if (macHoldingHotKey || nonMacHoldingHotKey) {\n this.toggleRowSelected(clickedRow.id);\n } else if (event.shiftKey) {\n // if holding shift, select rows between this selection and the last selection\n this.groupRowSelect(rowIndex);\n } else {\n // clicking a row will select just that row.\n this.selectedRowIds = [clickedRow.id];\n }\n this.filterSelectedRowsToExistingRows();\n // emit event so users can hook into this action\n this.emitEvent(\"row-click\", { row: clickedRow });\n }\n\n // filter selected down to rows that actually exist in the table\n protected filterSelectedRowsToExistingRows() {\n this.selectedRowIds = this.selectedRowIds.filter((id) =>\n this.rowIdsSet.has(id),\n );\n }\n\n protected onRowDoubleClick(clickedRow: TableRow<T>): void {\n // emit event so users can hook into this event\n this.emitEvent(\"row-double-click\", { row: clickedRow });\n }\n\n // default global keyboard events implemented through this method.\n // event.stopImmediatePropagation() in DOM keyboard event listeners will\n // prevent this method from being called.\n protected onKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation) {\n return;\n }\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowDown\":\n event.preventDefault();\n return this.onUpDownArrowKey(event);\n }\n }\n\n // listener applies when column has focus\n protected onColumnKeyDown(\n event: KeyboardEvent,\n column: TableColumn<T>,\n ): void {\n if (this.disableKeyboardNavigation) {\n return;\n }\n switch (event.key) {\n case \"Enter\":\n return this.onColumnClick(column);\n }\n }\n\n // listener applies when row has focus\n protected onRowKeyDown(\n event: KeyboardEvent,\n row: TableRow<T>,\n index: number,\n ): void {\n if (this.disableKeyboardNavigation) {\n return;\n }\n switch (event.key) {\n // enter to select, enter again to navigate within, shift + enter to deselect (and select), while in multiselect\n case \"Enter\":\n if (\n this.isSelected(row) &&\n !event.shiftKey &&\n this.selectedRows.length === 1\n ) {\n return this.onRowClick(event, row, index);\n } else {\n event.stopImmediatePropagation();\n return this.toggleRowSelected(row.id);\n }\n }\n }\n\n protected onUpDownArrowKey(event: KeyboardEvent): void {\n if (this.rows.length === 0) {\n // there are no rows to navigate or select with arrows. avoids array out of bounds.\n return;\n }\n const indexOffset = event.key === \"ArrowUp\" ? -1 : 1;\n const newSelectedRowIndex = this.constrainIndex(\n this.indexOfLastSelectedRow + indexOffset,\n );\n const newSelectedRowId = this.rows[newSelectedRowIndex].id;\n\n if (event.shiftKey) {\n // - focus and (maybe) select and focus the prev or next, if it exists\n this.groupRowSelect(newSelectedRowIndex);\n } else if (this.selectedRowIds.length === 0) {\n // select the first row if none are selected\n const firstRowId = this.rows[0] ? this.rows[0].id : undefined;\n if (firstRowId) {\n this.selectedRowIds = [firstRowId];\n }\n } else {\n // offset in the proper direction of the arrow\n this.selectedRowIds = [newSelectedRowId];\n }\n // always try to focus the next element in the direction of the arrow if you can\n this.getTableRowElementById(newSelectedRowId)?.focus();\n }\n\n // ensures index values are kept to the closest in-bounds index\n protected constrainIndex(index: number): number {\n return Math.max(Math.min(index, this.rows.length - 1), 0);\n }\n\n connectedCallback() {\n super.connectedCallback();\n // attach keyboard listener for arrow keys\n window.addEventListener(\"keydown\", (e: KeyboardEvent) => this.onKeyDown(e));\n }\n\n render() {\n return html`\n <table id=\"main-table\">\n <thead>\n <tr>\n ${this.visibleColumns.map(\n (column) => html`\n <th\n @click=${() => this.onColumnClick(column)}\n @keydown=${(e: KeyboardEvent) =>\n this.onColumnKeyDown(e, column)}\n class=${column.dataType.compare ? \"sortable\" : \"\"}\n style=${`flex: ${column.flexRatio}`}\n tabindex=\"0\"\n >\n ${column.label}\n ${column.dataType.compare\n ? html`<span>${this.renderArrowIcon(column.key)}</span>`\n : \"\"}\n </th>\n `,\n )}\n </tr>\n </thead>\n <tbody>\n ${!this.isLoading\n ? this.sortedRows.map(\n (row, index) => html`\n <tr\n @click=${(e: MouseEvent) => this.onRowClick(e, row, index)}\n @dblclick=${() => this.onRowDoubleClick(row)}\n @keydown=${(e: KeyboardEvent) =>\n this.onRowKeyDown(e, row, index)}\n class=${this.isSelected(row) ? \"row-selected\" : \"\"}\n data-row-selected=${this.isSelected(row)}\n data-id=${row.id}\n id=${\"row-\" + row.id}\n tabindex=\"0\"\n >\n ${this.visibleColumns.map(\n (column) => html`\n <td style=${`flex: ${column.flexRatio}`}>\n ${column.dataType.format(row.data)}\n </td>\n `,\n )}\n </tr>\n `,\n )\n : html`\n <tr>\n <td class=\"no-data\">Loading...</td>\n </tr>\n `}\n ${!this.isLoading && this.sortedRows.length === 0\n ? html`\n <tr>\n <td class=\"no-data\">${this.noDataText}</td>\n </tr>\n `\n : null}\n </tbody>\n </table>\n `;\n }\n\n static styles: CSSResultGroup = css`\n table {\n display: flex;\n flex-direction: column;\n user-select: none;\n border-collapse: collapse;\n }\n\n thead,\n tbody {\n display: flex;\n flex-direction: column;\n }\n\n thead {\n background: #2a282c;\n }\n\n tbody {\n scrollbar-gutter: stable;\n }\n\n tr {\n display: flex;\n width: 100%;\n min-height: 40px;\n flex-shrink: 0;\n }\n\n tr.row-selected {\n background: #ddebff;\n }\n\n td.no-data {\n font-style: italic;\n justify-content: center;\n }\n\n td,\n th {\n display: flex;\n flex: 1;\n justify-content: flex-start;\n align-items: center;\n padding: 0 12px;\n height: 40px;\n\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n }\n\n th {\n color: white;\n }\n\n th.sortable {\n cursor: pointer;\n }\n\n th.sortable:hover {\n background: #525252;\n }\n\n th span {\n padding-left: 5px;\n }\n\n td {\n border-bottom: 1px solid #bbbbbb;\n }\n `;\n}\n\n// a simple, generic, out-of-the box implementation of AdsTable\n@customElement(\"ads-simple-table\")\nexport class AdsSimpleTable<T> extends AdsTable<T> {\n // columns are exposed as a parameter like rows, not a class member to implement\n @property({ type: Array }) columns: TableColumn<T>[] = [];\n\n @property({ type: String }) secondarySortKey: keyof T | undefined = undefined;\n\n // sort key is automatically held in state\n @state() sortKey: keyof T | undefined = this.columns[0]?.key;\n\n protected override updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n if (changedProperties.has(\"columns\")) {\n this.sortKey = this.columns[0]?.key;\n }\n }\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -32,20 +32,20 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
32
32
|
* Copyright 2019 Google LLC
|
|
33
33
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
34
34
|
*/
|
|
35
|
-
const t$2=globalThis,e$
|
|
35
|
+
const t$2=globalThis,e$5=t$2.ShadowRoot&&(void 0===t$2.ShadyCSS||t$2.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,s$2=Symbol(),o$4=new WeakMap;let n$3 = class n{constructor(t,e,o){if(this._$cssResult$=true,o!==s$2)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e;}get styleSheet(){let t=this.o;const s=this.t;if(e$5&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o$4.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o$4.set(s,t));}return t}toString(){return this.cssText}};const r$5=t=>new n$3("string"==typeof t?t:t+"",void 0,s$2),i$3=(t,...e)=>{const o=1===t.length?t[0]:e.reduce(((e,s,o)=>e+(t=>{if(true===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(s)+t[o+1]),t[0]);return new n$3(o,t,s$2)},S$1=(s,o)=>{if(e$5)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement("style"),n=t$2.litNonce;void 0!==n&&o.setAttribute("nonce",n),o.textContent=e.cssText,s.appendChild(o);}},c$2=e$5?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const s of t.cssRules)e+=s.cssText;return r$5(e)})(t):t;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* @license
|
|
39
39
|
* Copyright 2017 Google LLC
|
|
40
40
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
41
|
-
*/const{is:i$2,defineProperty:e$
|
|
41
|
+
*/const{is:i$2,defineProperty:e$4,getOwnPropertyDescriptor:h$1,getOwnPropertyNames:r$4,getOwnPropertySymbols:o$3,getPrototypeOf:n$2}=Object,a$1=globalThis,c$1=a$1.trustedTypes,l$1=c$1?c$1.emptyScript:"",p$1=a$1.reactiveElementPolyfillSupport,d$1=(t,s)=>t,u$1={toAttribute(t,s){switch(s){case Boolean:t=t?l$1:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t);}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t);}catch(t){i=null;}}return i}},f$1=(t,s)=>!i$2(t,s),b={attribute:true,type:String,converter:u$1,reflect:false,useDefault:false,hasChanged:f$1};Symbol.metadata??=Symbol("metadata"),a$1.litPropertyMetadata??=new WeakMap;let y$1 = class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t);}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b){if(s.state&&(s.attribute=false),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=true),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e$4(this.prototype,t,h);}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h$1(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t;}};return {get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i);},configurable:true,enumerable:true}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(d$1("elementProperties")))return;const t=n$2(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties);}static finalize(){if(this.hasOwnProperty(d$1("finalized")))return;if(this.finalized=true,this._$Ei(),this.hasOwnProperty(d$1("properties"))){const t=this.properties,s=[...r$4(t),...o$3(t)];for(const i of s)this.createProperty(i,t[i]);}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i);}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t);}this.elementStyles=this.finalizeStyles(this.styles);}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(c$2(s));}else void 0!==s&&i.push(c$2(s));return i}static _$Eu(t,s){const i=s.attribute;return false===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=false,this.hasUpdated=false,this._$Em=null,this._$Ev();}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)));}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.();}removeController(t){this._$EO?.delete(t);}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t);}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return S$1(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(true),this._$EO?.forEach((t=>t.hostConnected?.()));}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()));}attributeChangedCallback(t,s,i){this._$AK(t,i);}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&true===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u$1).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null;}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u$1;this._$Em=e;const r=h.fromAttribute(s,t.type);this[e]=r??this._$Ej?.get(e)??r,this._$Em=null;}}requestUpdate(t,s,i){if(void 0!==t){const e=this.constructor,h=this[t];if(i??=e.getPropertyOptions(t),!((i.hasChanged??f$1)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(e._$Eu(t,i))))return;this.C(t,s,i);} false===this.isUpdatePending&&(this._$ES=this._$EP());}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),true!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),true===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t));}async _$EP(){this.isUpdatePending=true;try{await this._$ES;}catch(t){Promise.reject(t);}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0;}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];true!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e);}}let t=false;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EM();}catch(s){throw t=false,this._$EM(),s}t&&this._$AE(s);}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=true,this.firstUpdated(t)),this.updated(t);}_$EM(){this._$AL=new Map,this.isUpdatePending=false;}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return true}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM();}updated(t){}firstUpdated(t){}};y$1.elementStyles=[],y$1.shadowRootOptions={mode:"open"},y$1[d$1("elementProperties")]=new Map,y$1[d$1("finalized")]=new Map,p$1?.({ReactiveElement:y$1}),(a$1.reactiveElementVersions??=[]).push("2.1.1");
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* @license
|
|
45
45
|
* Copyright 2017 Google LLC
|
|
46
46
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
47
47
|
*/
|
|
48
|
-
const t$1=globalThis,i$1=t$1.trustedTypes,s$1=i$1?i$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$
|
|
48
|
+
const t$1=globalThis,i$1=t$1.trustedTypes,s$1=i$1?i$1.createPolicy("lit-html",{createHTML:t=>t}):void 0,e$3="$lit$",h=`lit$${Math.random().toFixed(9).slice(2)}$`,o$2="?"+h,n$1=`<${o$2}>`,r$3=document,l=()=>r$3.createComment(""),c=t=>null===t||"object"!=typeof t&&"function"!=typeof t,a=Array.isArray,u=t=>a(t)||"function"==typeof t?.[Symbol.iterator],d="[ \t\n\f\r]",f=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,v=/-->/g,_=/>/g,m=RegExp(`>|${d}(?:([^\\s"'>=/]+)(${d}*=${d}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),p=/'/g,g=/"/g,$=/^(?:script|style|textarea|title)$/i,y=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),x=y(1),T=Symbol.for("lit-noChange"),E=Symbol.for("lit-nothing"),A=new WeakMap,C=r$3.createTreeWalker(r$3,129);function P(t,i){if(!a(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==s$1?s$1.createHTML(i):i}const V=(t,i)=>{const s=t.length-1,o=[];let r,l=2===i?"<svg>":3===i?"<math>":"",c=f;for(let i=0;i<s;i++){const s=t[i];let a,u,d=-1,y=0;for(;y<s.length&&(c.lastIndex=y,u=c.exec(s),null!==u);)y=c.lastIndex,c===f?"!--"===u[1]?c=v:void 0!==u[1]?c=_:void 0!==u[2]?($.test(u[2])&&(r=RegExp("</"+u[2],"g")),c=m):void 0!==u[3]&&(c=m):c===m?">"===u[0]?(c=r??f,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?m:'"'===u[3]?g:p):c===g||c===p?c=m:c===v||c===_?c=f:(c=m,r=void 0);const x=c===m&&t[i+1].startsWith("/>")?" ":"";l+=c===f?s+n$1:d>=0?(o.push(a),s.slice(0,d)+e$3+s.slice(d)+h+x):s+h+(-2===d?i:x);}return [P(t,l+(t[s]||"<?>")+(2===i?"</svg>":3===i?"</math>":"")),o]};class N{constructor({strings:t,_$litType$:s},n){let r;this.parts=[];let c=0,a=0;const u=t.length-1,d=this.parts,[f,v]=V(t,s);if(this.el=N.createElement(f,n),C.currentNode=this.el.content,2===s||3===s){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes);}for(;null!==(r=C.nextNode())&&d.length<u;){if(1===r.nodeType){if(r.hasAttributes())for(const t of r.getAttributeNames())if(t.endsWith(e$3)){const i=v[a++],s=r.getAttribute(t).split(h),e=/([.?@])?(.*)/.exec(i);d.push({type:1,index:c,name:e[2],strings:s,ctor:"."===e[1]?H:"?"===e[1]?I:"@"===e[1]?L:k}),r.removeAttribute(t);}else t.startsWith(h)&&(d.push({type:6,index:c}),r.removeAttribute(t));if($.test(r.tagName)){const t=r.textContent.split(h),s=t.length-1;if(s>0){r.textContent=i$1?i$1.emptyScript:"";for(let i=0;i<s;i++)r.append(t[i],l()),C.nextNode(),d.push({type:2,index:++c});r.append(t[s],l());}}}else if(8===r.nodeType)if(r.data===o$2)d.push({type:2,index:c});else {let t=-1;for(;-1!==(t=r.data.indexOf(h,t+1));)d.push({type:7,index:c}),t+=h.length-1;}c++;}}static createElement(t,i){const s=r$3.createElement("template");return s.innerHTML=t,s}}function S(t,i,s=t,e){if(i===T)return i;let h=void 0!==e?s._$Co?.[e]:s._$Cl;const o=c(i)?void 0:i._$litDirective$;return h?.constructor!==o&&(h?._$AO?.(false),void 0===o?h=void 0:(h=new o(t),h._$AT(t,s,e)),void 0!==e?(s._$Co??=[])[e]=h:s._$Cl=h),void 0!==h&&(i=S(t,h._$AS(t,i.values),h,e)),i}class M{constructor(t,i){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=i;}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:i},parts:s}=this._$AD,e=(t?.creationScope??r$3).importNode(i,true);C.currentNode=e;let h=C.nextNode(),o=0,n=0,l=s[0];for(;void 0!==l;){if(o===l.index){let i;2===l.type?i=new R(h,h.nextSibling,this,t):1===l.type?i=new l.ctor(h,l.name,l.strings,this,t):6===l.type&&(i=new z(h,this,t)),this._$AV.push(i),l=s[++n];}o!==l?.index&&(h=C.nextNode(),o++);}return C.currentNode=r$3,e}p(t){let i=0;for(const s of this._$AV) void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,i),i+=s.strings.length-2):s._$AI(t[i])),i++;}}class R{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,i,s,e){this.type=2,this._$AH=E,this._$AN=void 0,this._$AA=t,this._$AB=i,this._$AM=s,this.options=e,this._$Cv=e?.isConnected??true;}get parentNode(){let t=this._$AA.parentNode;const i=this._$AM;return void 0!==i&&11===t?.nodeType&&(t=i.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,i=this){t=S(this,t,i),c(t)?t===E||null==t||""===t?(this._$AH!==E&&this._$AR(),this._$AH=E):t!==this._$AH&&t!==T&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):u(t)?this.k(t):this._(t);}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t));}_(t){this._$AH!==E&&c(this._$AH)?this._$AA.nextSibling.data=t:this.T(r$3.createTextNode(t)),this._$AH=t;}$(t){const{values:i,_$litType$:s}=t,e="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=N.createElement(P(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===e)this._$AH.p(i);else {const t=new M(e,this),s=t.u(this.options);t.p(i),this.T(s),this._$AH=t;}}_$AC(t){let i=A.get(t.strings);return void 0===i&&A.set(t.strings,i=new N(t)),i}k(t){a(this._$AH)||(this._$AH=[],this._$AR());const i=this._$AH;let s,e=0;for(const h of t)e===i.length?i.push(s=new R(this.O(l()),this.O(l()),this,this.options)):s=i[e],s._$AI(h),e++;e<i.length&&(this._$AR(s&&s._$AB.nextSibling,e),i.length=e);}_$AR(t=this._$AA.nextSibling,i){for(this._$AP?.(false,true,i);t!==this._$AB;){const i=t.nextSibling;t.remove(),t=i;}}setConnected(t){ void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t));}}class k{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,i,s,e,h){this.type=1,this._$AH=E,this._$AN=void 0,this.element=t,this.name=i,this._$AM=e,this.options=h,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=E;}_$AI(t,i=this,s,e){const h=this.strings;let o=false;if(void 0===h)t=S(this,t,i,0),o=!c(t)||t!==this._$AH&&t!==T,o&&(this._$AH=t);else {const e=t;let n,r;for(t=h[0],n=0;n<h.length-1;n++)r=S(this,e[s+n],i,n),r===T&&(r=this._$AH[n]),o||=!c(r)||r!==this._$AH[n],r===E?t=E:t!==E&&(t+=(r??"")+h[n+1]),this._$AH[n]=r;}o&&!e&&this.j(t);}j(t){t===E?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"");}}class H extends k{constructor(){super(...arguments),this.type=3;}j(t){this.element[this.name]=t===E?void 0:t;}}class I extends k{constructor(){super(...arguments),this.type=4;}j(t){this.element.toggleAttribute(this.name,!!t&&t!==E);}}class L extends k{constructor(t,i,s,e,h){super(t,i,s,e,h),this.type=5;}_$AI(t,i=this){if((t=S(this,t,i,0)??E)===T)return;const s=this._$AH,e=t===E&&s!==E||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,h=t!==E&&(s===E||e);e&&this.element.removeEventListener(this.name,this,s),h&&this.element.addEventListener(this.name,this,t),this._$AH=t;}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t);}}class z{constructor(t,i,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=i,this.options=s;}get _$AU(){return this._$AM._$AU}_$AI(t){S(this,t);}}const j=t$1.litHtmlPolyfillSupport;j?.(N,R),(t$1.litHtmlVersions??=[]).push("3.3.1");const B=(t,i,s)=>{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new R(i.insertBefore(l(),t),t,void 0,s??{});}return h._$AI(t),h};
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* @license
|
|
@@ -64,26 +64,33 @@ const t=t=>(e,o)=>{ void 0!==o?o.addInitializer((()=>{customElements.define(t,e)
|
|
|
64
64
|
* @license
|
|
65
65
|
* Copyright 2017 Google LLC
|
|
66
66
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
67
|
-
*/const o={attribute:true,type:String,converter:u$1,reflect:false,hasChanged:f$1},r$
|
|
67
|
+
*/const o={attribute:true,type:String,converter:u$1,reflect:false,hasChanged:f$1},r$2=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),"setter"===n&&((t=Object.create(t)).wrapped=true),s.set(r.name,t),"accessor"===n){const{name:o}=r;return {set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t);},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if("setter"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t);}}throw Error("Unsupported decorator location: "+n)};function n(t){return (e,o)=>"object"==typeof o?r$2(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* @license
|
|
71
71
|
* Copyright 2017 Google LLC
|
|
72
72
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
73
|
-
*/function r(r){return n({...r,state:true,attribute:false})}
|
|
73
|
+
*/function r$1(r){return n({...r,state:true,attribute:false})}
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* @license
|
|
77
77
|
* Copyright 2017 Google LLC
|
|
78
78
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
79
79
|
*/
|
|
80
|
-
const e$
|
|
80
|
+
const e$2=(e,t,c)=>(c.configurable=true,c.enumerable=true,Reflect.decorate&&"object"!=typeof t&&Object.defineProperty(e,t,c),c);
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
83
|
* @license
|
|
84
84
|
* Copyright 2017 Google LLC
|
|
85
85
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
86
|
-
*/function e(e,r){return (n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;return e$
|
|
86
|
+
*/function e$1(e,r){return (n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;return e$2(n,s,{get(){return o(this)}})}}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @license
|
|
90
|
+
* Copyright 2017 Google LLC
|
|
91
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
92
|
+
*/
|
|
93
|
+
let e;function r(r){return (n,o)=>e$2(n,o,{get(){return (this.renderRoot??(e??=document.createDocumentFragment())).querySelectorAll(r)}})}
|
|
87
94
|
|
|
88
95
|
// static class that encapsulates shorthands and utilities for emitting events.
|
|
89
96
|
class EventHelpers {
|
|
@@ -468,6 +475,9 @@ class AdsTable extends i {
|
|
|
468
475
|
this.selectedRowIds = [];
|
|
469
476
|
this.isLoading = false;
|
|
470
477
|
}
|
|
478
|
+
getTableRowElementById(id) {
|
|
479
|
+
return Array.from(this.tableRows || []).find((row) => row.id === `row-${id}`);
|
|
480
|
+
}
|
|
471
481
|
updated(changedProperties) {
|
|
472
482
|
super.updated(changedProperties);
|
|
473
483
|
if (changedProperties.has("selectedRowIds")) {
|
|
@@ -682,9 +692,10 @@ class AdsTable extends i {
|
|
|
682
692
|
// emit event so users can hook into this event
|
|
683
693
|
this.emitEvent("row-double-click", { row: clickedRow });
|
|
684
694
|
}
|
|
685
|
-
//
|
|
695
|
+
// default global keyboard events implemented through this method.
|
|
696
|
+
// event.stopImmediatePropagation() in DOM keyboard event listeners will
|
|
697
|
+
// prevent this method from being called.
|
|
686
698
|
onKeyDown(event) {
|
|
687
|
-
var _a;
|
|
688
699
|
if (this.disableKeyboardNavigation) {
|
|
689
700
|
return;
|
|
690
701
|
}
|
|
@@ -692,22 +703,64 @@ class AdsTable extends i {
|
|
|
692
703
|
case "ArrowUp":
|
|
693
704
|
case "ArrowDown":
|
|
694
705
|
event.preventDefault();
|
|
695
|
-
|
|
696
|
-
(_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
697
|
-
return this.onUpDownArrowKey(event.key);
|
|
706
|
+
return this.onUpDownArrowKey(event);
|
|
698
707
|
}
|
|
699
708
|
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
709
|
+
// listener applies when column has focus
|
|
710
|
+
onColumnKeyDown(event, column) {
|
|
711
|
+
if (this.disableKeyboardNavigation) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
switch (event.key) {
|
|
715
|
+
case "Enter":
|
|
716
|
+
return this.onColumnClick(column);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
// listener applies when row has focus
|
|
720
|
+
onRowKeyDown(event, row, index) {
|
|
721
|
+
if (this.disableKeyboardNavigation) {
|
|
704
722
|
return;
|
|
705
723
|
}
|
|
706
|
-
|
|
707
|
-
|
|
724
|
+
switch (event.key) {
|
|
725
|
+
// enter to select, enter again to navigate within, shift + enter to deselect (and select), while in multiselect
|
|
726
|
+
case "Enter":
|
|
727
|
+
if (this.isSelected(row) &&
|
|
728
|
+
!event.shiftKey &&
|
|
729
|
+
this.selectedRows.length === 1) {
|
|
730
|
+
return this.onRowClick(event, row, index);
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
event.stopImmediatePropagation();
|
|
734
|
+
return this.toggleRowSelected(row.id);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
onUpDownArrowKey(event) {
|
|
739
|
+
var _a;
|
|
740
|
+
if (this.rows.length === 0) {
|
|
741
|
+
// there are no rows to navigate or select with arrows. avoids array out of bounds.
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
const indexOffset = event.key === "ArrowUp" ? -1 : 1;
|
|
708
745
|
const newSelectedRowIndex = this.constrainIndex(this.indexOfLastSelectedRow + indexOffset);
|
|
709
746
|
const newSelectedRowId = this.rows[newSelectedRowIndex].id;
|
|
710
|
-
|
|
747
|
+
if (event.shiftKey) {
|
|
748
|
+
// - focus and (maybe) select and focus the prev or next, if it exists
|
|
749
|
+
this.groupRowSelect(newSelectedRowIndex);
|
|
750
|
+
}
|
|
751
|
+
else if (this.selectedRowIds.length === 0) {
|
|
752
|
+
// select the first row if none are selected
|
|
753
|
+
const firstRowId = this.rows[0] ? this.rows[0].id : undefined;
|
|
754
|
+
if (firstRowId) {
|
|
755
|
+
this.selectedRowIds = [firstRowId];
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
// offset in the proper direction of the arrow
|
|
760
|
+
this.selectedRowIds = [newSelectedRowId];
|
|
761
|
+
}
|
|
762
|
+
// always try to focus the next element in the direction of the arrow if you can
|
|
763
|
+
(_a = this.getTableRowElementById(newSelectedRowId)) === null || _a === void 0 ? void 0 : _a.focus();
|
|
711
764
|
}
|
|
712
765
|
// ensures index values are kept to the closest in-bounds index
|
|
713
766
|
constrainIndex(index) {
|
|
@@ -715,19 +768,21 @@ class AdsTable extends i {
|
|
|
715
768
|
}
|
|
716
769
|
connectedCallback() {
|
|
717
770
|
super.connectedCallback();
|
|
718
|
-
// attach keyboard listener
|
|
771
|
+
// attach keyboard listener for arrow keys
|
|
719
772
|
window.addEventListener("keydown", (e) => this.onKeyDown(e));
|
|
720
773
|
}
|
|
721
774
|
render() {
|
|
722
775
|
return x `
|
|
723
|
-
<table id="main-table"
|
|
776
|
+
<table id="main-table">
|
|
724
777
|
<thead>
|
|
725
778
|
<tr>
|
|
726
779
|
${this.visibleColumns.map((column) => x `
|
|
727
780
|
<th
|
|
728
781
|
@click=${() => this.onColumnClick(column)}
|
|
782
|
+
@keydown=${(e) => this.onColumnKeyDown(e, column)}
|
|
729
783
|
class=${column.dataType.compare ? "sortable" : ""}
|
|
730
784
|
style=${`flex: ${column.flexRatio}`}
|
|
785
|
+
tabindex="0"
|
|
731
786
|
>
|
|
732
787
|
${column.label}
|
|
733
788
|
${column.dataType.compare
|
|
@@ -743,9 +798,12 @@ class AdsTable extends i {
|
|
|
743
798
|
<tr
|
|
744
799
|
@click=${(e) => this.onRowClick(e, row, index)}
|
|
745
800
|
@dblclick=${() => this.onRowDoubleClick(row)}
|
|
801
|
+
@keydown=${(e) => this.onRowKeyDown(e, row, index)}
|
|
746
802
|
class=${this.isSelected(row) ? "row-selected" : ""}
|
|
747
803
|
data-row-selected=${this.isSelected(row)}
|
|
748
804
|
data-id=${row.id}
|
|
805
|
+
id=${"row-" + row.id}
|
|
806
|
+
tabindex="0"
|
|
749
807
|
>
|
|
750
808
|
${this.visibleColumns.map((column) => x `
|
|
751
809
|
<td style=${`flex: ${column.flexRatio}`}>
|
|
@@ -845,8 +903,11 @@ AdsTable.styles = i$3 `
|
|
|
845
903
|
}
|
|
846
904
|
`;
|
|
847
905
|
__decorate([
|
|
848
|
-
e("#main-table")
|
|
906
|
+
e$1("#main-table")
|
|
849
907
|
], AdsTable.prototype, "tableElement", void 0);
|
|
908
|
+
__decorate([
|
|
909
|
+
r("table tr")
|
|
910
|
+
], AdsTable.prototype, "tableRows", void 0);
|
|
850
911
|
__decorate([
|
|
851
912
|
n({ type: Array })
|
|
852
913
|
], AdsTable.prototype, "rows", void 0);
|
|
@@ -854,13 +915,13 @@ __decorate([
|
|
|
854
915
|
n({ type: Boolean })
|
|
855
916
|
], AdsTable.prototype, "disableKeyboardNavigation", void 0);
|
|
856
917
|
__decorate([
|
|
857
|
-
r()
|
|
918
|
+
r$1()
|
|
858
919
|
], AdsTable.prototype, "sortDirection", void 0);
|
|
859
920
|
__decorate([
|
|
860
|
-
r()
|
|
921
|
+
r$1()
|
|
861
922
|
], AdsTable.prototype, "selectedRowIds", void 0);
|
|
862
923
|
__decorate([
|
|
863
|
-
r()
|
|
924
|
+
r$1()
|
|
864
925
|
], AdsTable.prototype, "isLoading", void 0);
|
|
865
926
|
// a simple, generic, out-of-the box implementation of AdsTable
|
|
866
927
|
let AdsSimpleTable = class AdsSimpleTable extends AdsTable {
|
|
@@ -888,7 +949,7 @@ __decorate([
|
|
|
888
949
|
n({ type: String })
|
|
889
950
|
], AdsSimpleTable.prototype, "secondarySortKey", void 0);
|
|
890
951
|
__decorate([
|
|
891
|
-
r()
|
|
952
|
+
r$1()
|
|
892
953
|
], AdsSimpleTable.prototype, "sortKey", void 0);
|
|
893
954
|
AdsSimpleTable = __decorate([
|
|
894
955
|
t("ads-simple-table")
|