@triptease/tt-table-wrapper 1.0.4 → 1.0.6
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.
|
@@ -28,6 +28,7 @@ class TtTableWrapper extends lit_1.LitElement {
|
|
|
28
28
|
this.pageSize = 10;
|
|
29
29
|
this.sortState = { key: '', direction: 'none' };
|
|
30
30
|
this.headerClickHandlers = new Map();
|
|
31
|
+
this.statusMessage = '';
|
|
31
32
|
}
|
|
32
33
|
render() {
|
|
33
34
|
return (0, lit_1.html) `
|
|
@@ -35,6 +36,7 @@ class TtTableWrapper extends lit_1.LitElement {
|
|
|
35
36
|
<slot @slotchange=${this.handleSlotChange}></slot>
|
|
36
37
|
<tt-paginator total-rows=${this.totalRows} page-size=${this.pageSize}></tt-paginator>
|
|
37
38
|
</div>
|
|
39
|
+
<div role="status" aria-live="polite" aria-atomic="true" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap">${this.statusMessage}</div>
|
|
38
40
|
`;
|
|
39
41
|
}
|
|
40
42
|
disconnectedCallback() {
|
|
@@ -46,9 +48,15 @@ class TtTableWrapper extends lit_1.LitElement {
|
|
|
46
48
|
this.sortState = { key: '', direction: 'none' };
|
|
47
49
|
const headers = this.querySelectorAll('th[data-sort-key]');
|
|
48
50
|
for (const header of headers) {
|
|
51
|
+
header.setAttribute('aria-sort', 'none');
|
|
52
|
+
const button = document.createElement('button');
|
|
53
|
+
while (header.firstChild) {
|
|
54
|
+
button.appendChild(header.firstChild);
|
|
55
|
+
}
|
|
56
|
+
header.appendChild(button);
|
|
49
57
|
const handler = () => this.handleSortClick(header);
|
|
50
58
|
this.headerClickHandlers.set(header, handler);
|
|
51
|
-
|
|
59
|
+
button.addEventListener('click', handler);
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
handleSortClick(header) {
|
|
@@ -59,6 +67,11 @@ class TtTableWrapper extends lit_1.LitElement {
|
|
|
59
67
|
if (direction !== 'none') {
|
|
60
68
|
header.setAttribute('aria-sort', ARIA_SORT_MAP[direction]);
|
|
61
69
|
}
|
|
70
|
+
const columnName = header.querySelector('button')?.textContent?.trim() ?? key;
|
|
71
|
+
this.statusMessage = direction === 'none'
|
|
72
|
+
? `Sort removed from ${columnName}`
|
|
73
|
+
: `Sorted by ${columnName}, ${ARIA_SORT_MAP[direction]}`;
|
|
74
|
+
this.requestUpdate();
|
|
62
75
|
this.sortState = { key, direction };
|
|
63
76
|
this.dispatchEvent(new CustomEvent('sort-change', {
|
|
64
77
|
detail: { key, direction },
|
|
@@ -69,12 +82,19 @@ class TtTableWrapper extends lit_1.LitElement {
|
|
|
69
82
|
clearAriaSortFromAll() {
|
|
70
83
|
const headers = this.querySelectorAll('th[aria-sort]');
|
|
71
84
|
for (const header of headers) {
|
|
72
|
-
header.
|
|
85
|
+
header.setAttribute('aria-sort', 'none');
|
|
73
86
|
}
|
|
74
87
|
}
|
|
75
88
|
cleanupHandlers() {
|
|
76
89
|
for (const [header, handler] of this.headerClickHandlers) {
|
|
77
|
-
header.
|
|
90
|
+
const button = header.querySelector('button');
|
|
91
|
+
if (button) {
|
|
92
|
+
button.removeEventListener('click', handler);
|
|
93
|
+
while (button.firstChild) {
|
|
94
|
+
header.insertBefore(button.firstChild, button);
|
|
95
|
+
}
|
|
96
|
+
button.remove();
|
|
97
|
+
}
|
|
78
98
|
}
|
|
79
99
|
this.headerClickHandlers.clear();
|
|
80
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtTableWrapper.js","sourceRoot":"","sources":["../../../src/TtTableWrapper.ts"],"names":[],"mappings":";;;;;;;;;AAAA,6BAAuC;AACvC,qDAA6C;AAC7C,2CAAqC;AAErC,mCAAiC;AAEjC,MAAM,aAAa,GAAkC;IACnD,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,MAAM,cAAc,GAAyC;IAC3D,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,MAAM;CACb,CAAC;
|
|
1
|
+
{"version":3,"file":"TtTableWrapper.js","sourceRoot":"","sources":["../../../src/TtTableWrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styles } from './styles.js';\nimport type { SortDirection, SortState } from './types.js';\nimport '@triptease/tt-paginator';\n\nconst ARIA_SORT_MAP: Record<SortDirection, string> = {\n asc: 'ascending',\n desc: 'descending',\n none: '',\n};\n\nconst NEXT_DIRECTION: Record<SortDirection, SortDirection> = {\n none: 'asc',\n asc: 'desc',\n desc: 'none',\n};\n\n\nexport class TtTableWrapper extends LitElement {\n static styles = styles;\n\n @property({ type: Number, attribute: 'total-rows' })\n totalRows = 0;\n\n @property({ type: Number, attribute: 'page-size' })\n pageSize = 10;\n\n private sortState: SortState = { key: '', direction: 'none' };\n private headerClickHandlers = new Map<HTMLElement, () => void>();\n private statusMessage = '';\n\n render() {\n return html`\n <div>\n <slot @slotchange=${this.handleSlotChange}></slot>\n <tt-paginator total-rows=${this.totalRows} page-size=${this.pageSize}></tt-paginator>\n </div>\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" style=\"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap\">${this.statusMessage}</div>\n `;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanupHandlers();\n }\n\n private handleSlotChange() {\n this.cleanupHandlers();\n this.sortState = { key: '', direction: 'none' };\n\n const headers = this.querySelectorAll<HTMLElement>('th[data-sort-key]');\n for (const header of headers) {\n header.setAttribute('aria-sort', 'none');\n\n const button = document.createElement('button');\n while (header.firstChild) {\n button.appendChild(header.firstChild);\n }\n header.appendChild(button);\n\n const handler = () => this.handleSortClick(header);\n this.headerClickHandlers.set(header, handler);\n button.addEventListener('click', handler);\n }\n }\n\n private handleSortClick(header: HTMLElement) {\n const key = header.dataset.sortKey!;\n const isSameColumn = key === this.sortState.key;\n\n const direction = isSameColumn ? NEXT_DIRECTION[this.sortState.direction] : 'asc';\n\n this.clearAriaSortFromAll();\n\n if (direction !== 'none') {\n header.setAttribute('aria-sort', ARIA_SORT_MAP[direction]);\n }\n\n const columnName = header.querySelector('button')?.textContent?.trim() ?? key;\n this.statusMessage = direction === 'none'\n ? `Sort removed from ${columnName}`\n : `Sorted by ${columnName}, ${ARIA_SORT_MAP[direction]}`;\n this.requestUpdate();\n\n this.sortState = { key, direction };\n\n this.dispatchEvent(\n new CustomEvent('sort-change', {\n detail: { key, direction },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private clearAriaSortFromAll() {\n const headers = this.querySelectorAll('th[aria-sort]');\n for (const header of headers) {\n header.setAttribute('aria-sort', 'none');\n }\n }\n\n private cleanupHandlers() {\n for (const [header, handler] of this.headerClickHandlers) {\n const button = header.querySelector('button');\n if (button) {\n button.removeEventListener('click', handler);\n while (button.firstChild) {\n header.insertBefore(button.firstChild, button);\n }\n button.remove();\n }\n }\n this.headerClickHandlers.clear();\n }\n}\n"]}
|
|
@@ -25,6 +25,7 @@ export class TtTableWrapper extends LitElement {
|
|
|
25
25
|
this.pageSize = 10;
|
|
26
26
|
this.sortState = { key: '', direction: 'none' };
|
|
27
27
|
this.headerClickHandlers = new Map();
|
|
28
|
+
this.statusMessage = '';
|
|
28
29
|
}
|
|
29
30
|
render() {
|
|
30
31
|
return html `
|
|
@@ -32,6 +33,7 @@ export class TtTableWrapper extends LitElement {
|
|
|
32
33
|
<slot @slotchange=${this.handleSlotChange}></slot>
|
|
33
34
|
<tt-paginator total-rows=${this.totalRows} page-size=${this.pageSize}></tt-paginator>
|
|
34
35
|
</div>
|
|
36
|
+
<div role="status" aria-live="polite" aria-atomic="true" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap">${this.statusMessage}</div>
|
|
35
37
|
`;
|
|
36
38
|
}
|
|
37
39
|
disconnectedCallback() {
|
|
@@ -43,9 +45,15 @@ export class TtTableWrapper extends LitElement {
|
|
|
43
45
|
this.sortState = { key: '', direction: 'none' };
|
|
44
46
|
const headers = this.querySelectorAll('th[data-sort-key]');
|
|
45
47
|
for (const header of headers) {
|
|
48
|
+
header.setAttribute('aria-sort', 'none');
|
|
49
|
+
const button = document.createElement('button');
|
|
50
|
+
while (header.firstChild) {
|
|
51
|
+
button.appendChild(header.firstChild);
|
|
52
|
+
}
|
|
53
|
+
header.appendChild(button);
|
|
46
54
|
const handler = () => this.handleSortClick(header);
|
|
47
55
|
this.headerClickHandlers.set(header, handler);
|
|
48
|
-
|
|
56
|
+
button.addEventListener('click', handler);
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
59
|
handleSortClick(header) {
|
|
@@ -56,6 +64,11 @@ export class TtTableWrapper extends LitElement {
|
|
|
56
64
|
if (direction !== 'none') {
|
|
57
65
|
header.setAttribute('aria-sort', ARIA_SORT_MAP[direction]);
|
|
58
66
|
}
|
|
67
|
+
const columnName = header.querySelector('button')?.textContent?.trim() ?? key;
|
|
68
|
+
this.statusMessage = direction === 'none'
|
|
69
|
+
? `Sort removed from ${columnName}`
|
|
70
|
+
: `Sorted by ${columnName}, ${ARIA_SORT_MAP[direction]}`;
|
|
71
|
+
this.requestUpdate();
|
|
59
72
|
this.sortState = { key, direction };
|
|
60
73
|
this.dispatchEvent(new CustomEvent('sort-change', {
|
|
61
74
|
detail: { key, direction },
|
|
@@ -66,12 +79,19 @@ export class TtTableWrapper extends LitElement {
|
|
|
66
79
|
clearAriaSortFromAll() {
|
|
67
80
|
const headers = this.querySelectorAll('th[aria-sort]');
|
|
68
81
|
for (const header of headers) {
|
|
69
|
-
header.
|
|
82
|
+
header.setAttribute('aria-sort', 'none');
|
|
70
83
|
}
|
|
71
84
|
}
|
|
72
85
|
cleanupHandlers() {
|
|
73
86
|
for (const [header, handler] of this.headerClickHandlers) {
|
|
74
|
-
header.
|
|
87
|
+
const button = header.querySelector('button');
|
|
88
|
+
if (button) {
|
|
89
|
+
button.removeEventListener('click', handler);
|
|
90
|
+
while (button.firstChild) {
|
|
91
|
+
header.insertBefore(button.firstChild, button);
|
|
92
|
+
}
|
|
93
|
+
button.remove();
|
|
94
|
+
}
|
|
75
95
|
}
|
|
76
96
|
this.headerClickHandlers.clear();
|
|
77
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtTableWrapper.js","sourceRoot":"","sources":["../../../src/TtTableWrapper.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,yBAAyB,CAAC;AAEjC,MAAM,aAAa,GAAkC;IACnD,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,EAAE;CACT,CAAC;AAEF,MAAM,cAAc,GAAyC;IAC3D,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,MAAM;CACb,CAAC;
|
|
1
|
+
{"version":3,"file":"TtTableWrapper.js","sourceRoot":"","sources":["../../../src/TtTableWrapper.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { styles } from './styles.js';\nimport type { SortDirection, SortState } from './types.js';\nimport '@triptease/tt-paginator';\n\nconst ARIA_SORT_MAP: Record<SortDirection, string> = {\n asc: 'ascending',\n desc: 'descending',\n none: '',\n};\n\nconst NEXT_DIRECTION: Record<SortDirection, SortDirection> = {\n none: 'asc',\n asc: 'desc',\n desc: 'none',\n};\n\n\nexport class TtTableWrapper extends LitElement {\n static styles = styles;\n\n @property({ type: Number, attribute: 'total-rows' })\n totalRows = 0;\n\n @property({ type: Number, attribute: 'page-size' })\n pageSize = 10;\n\n private sortState: SortState = { key: '', direction: 'none' };\n private headerClickHandlers = new Map<HTMLElement, () => void>();\n private statusMessage = '';\n\n render() {\n return html`\n <div>\n <slot @slotchange=${this.handleSlotChange}></slot>\n <tt-paginator total-rows=${this.totalRows} page-size=${this.pageSize}></tt-paginator>\n </div>\n <div role=\"status\" aria-live=\"polite\" aria-atomic=\"true\" style=\"position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap\">${this.statusMessage}</div>\n `;\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.cleanupHandlers();\n }\n\n private handleSlotChange() {\n this.cleanupHandlers();\n this.sortState = { key: '', direction: 'none' };\n\n const headers = this.querySelectorAll<HTMLElement>('th[data-sort-key]');\n for (const header of headers) {\n header.setAttribute('aria-sort', 'none');\n\n const button = document.createElement('button');\n while (header.firstChild) {\n button.appendChild(header.firstChild);\n }\n header.appendChild(button);\n\n const handler = () => this.handleSortClick(header);\n this.headerClickHandlers.set(header, handler);\n button.addEventListener('click', handler);\n }\n }\n\n private handleSortClick(header: HTMLElement) {\n const key = header.dataset.sortKey!;\n const isSameColumn = key === this.sortState.key;\n\n const direction = isSameColumn ? NEXT_DIRECTION[this.sortState.direction] : 'asc';\n\n this.clearAriaSortFromAll();\n\n if (direction !== 'none') {\n header.setAttribute('aria-sort', ARIA_SORT_MAP[direction]);\n }\n\n const columnName = header.querySelector('button')?.textContent?.trim() ?? key;\n this.statusMessage = direction === 'none'\n ? `Sort removed from ${columnName}`\n : `Sorted by ${columnName}, ${ARIA_SORT_MAP[direction]}`;\n this.requestUpdate();\n\n this.sortState = { key, direction };\n\n this.dispatchEvent(\n new CustomEvent('sort-change', {\n detail: { key, direction },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private clearAriaSortFromAll() {\n const headers = this.querySelectorAll('th[aria-sort]');\n for (const header of headers) {\n header.setAttribute('aria-sort', 'none');\n }\n }\n\n private cleanupHandlers() {\n for (const [header, handler] of this.headerClickHandlers) {\n const button = header.querySelector('button');\n if (button) {\n button.removeEventListener('click', handler);\n while (button.firstChild) {\n header.insertBefore(button.firstChild, button);\n }\n button.remove();\n }\n }\n this.headerClickHandlers.clear();\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Table wrapper web component with sorting and pagination",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "@triptease",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.6",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/esm/src/index.js",
|
|
9
9
|
"module": "dist/esm/src/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"test:watch": "vitest --config=./vitest.browser.config.mjs"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@triptease/stylesheet": "2.1.
|
|
40
|
-
"@triptease/tt-paginator": "1.0.
|
|
39
|
+
"@triptease/stylesheet": "2.1.4",
|
|
40
|
+
"@triptease/tt-paginator": "1.0.7",
|
|
41
41
|
"lit": "^3.1.4"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|