@zywave/zui-table 4.4.1-pre.0 → 4.4.1-pre.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/custom-elements.json +15 -17
- package/dist/zui-table-cell-css.js +1 -1
- package/dist/zui-table-cell-css.js.map +1 -1
- package/dist/zui-table-cell.d.ts +1 -0
- package/dist/zui-table-cell.js +10 -4
- package/dist/zui-table-cell.js.map +1 -1
- package/dist/zui-table.d.ts +1 -1
- package/dist/zui-table.js +8 -36
- package/dist/zui-table.js.map +1 -1
- package/lab.html +162 -4
- package/package.json +2 -2
- package/src/zui-table-cell-css.js +1 -1
- package/src/zui-table-cell.scss +19 -8
- package/src/zui-table-cell.ts +10 -4
- package/src/zui-table.ts +11 -42
- package/test/zui-table.test.ts +3 -3
|
@@ -72,6 +72,14 @@
|
|
|
72
72
|
"default": "false",
|
|
73
73
|
"description": "This private field is needed to persist state between the cell and the header row. DO NOT USE EXTERNALLY"
|
|
74
74
|
},
|
|
75
|
+
{
|
|
76
|
+
"kind": "field",
|
|
77
|
+
"name": "_header",
|
|
78
|
+
"type": {
|
|
79
|
+
"text": "string | undefined"
|
|
80
|
+
},
|
|
81
|
+
"privacy": "private"
|
|
82
|
+
},
|
|
75
83
|
{
|
|
76
84
|
"kind": "field",
|
|
77
85
|
"name": "#sort",
|
|
@@ -572,15 +580,7 @@
|
|
|
572
580
|
"name": "#internals",
|
|
573
581
|
"privacy": "private",
|
|
574
582
|
"type": {
|
|
575
|
-
"text": "ElementInternals
|
|
576
|
-
}
|
|
577
|
-
},
|
|
578
|
-
{
|
|
579
|
-
"kind": "field",
|
|
580
|
-
"name": "#mobileBreakpoint",
|
|
581
|
-
"privacy": "private",
|
|
582
|
-
"type": {
|
|
583
|
-
"text": "MediaQueryList"
|
|
583
|
+
"text": "ElementInternals"
|
|
584
584
|
}
|
|
585
585
|
},
|
|
586
586
|
{
|
|
@@ -592,11 +592,6 @@
|
|
|
592
592
|
},
|
|
593
593
|
"default": "false"
|
|
594
594
|
},
|
|
595
|
-
{
|
|
596
|
-
"kind": "field",
|
|
597
|
-
"name": "#mobileHeadersEvent",
|
|
598
|
-
"privacy": "private"
|
|
599
|
-
},
|
|
600
595
|
{
|
|
601
596
|
"kind": "method",
|
|
602
597
|
"name": "#onSlotChange",
|
|
@@ -608,9 +603,12 @@
|
|
|
608
603
|
"privacy": "private"
|
|
609
604
|
},
|
|
610
605
|
{
|
|
611
|
-
"kind": "
|
|
612
|
-
"name": "
|
|
613
|
-
"
|
|
606
|
+
"kind": "field",
|
|
607
|
+
"name": "role",
|
|
608
|
+
"type": {
|
|
609
|
+
"text": "string"
|
|
610
|
+
},
|
|
611
|
+
"default": "'table'"
|
|
614
612
|
}
|
|
615
613
|
],
|
|
616
614
|
"events": [
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const style = css `:host{--zui-table-cell-sort-active-color: var(--zui-blue);--zui-table-cell-sort-color: var(--zui-gray-300);contain:none;overflow-wrap:break-word}:host([sort=ascending]) zui-icon{--zui-icon-sort-ascending-color: var(--zui-table-cell-sort-active-color)}:host([sort=descending]) zui-icon{--zui-icon-sort-descending-color: var(--zui-table-cell-sort-active-color)}:host([action]) div{
|
|
2
|
+
export const style = css `:host{--zui-table-cell-sort-active-color: var(--zui-blue);--zui-table-cell-sort-color: var(--zui-gray-300);contain:none;overflow-wrap:break-word}:host([sort=ascending]) zui-icon{--zui-icon-sort-ascending-color: var(--zui-table-cell-sort-active-color)}:host([sort=descending]) zui-icon{--zui-icon-sort-descending-color: var(--zui-table-cell-sort-active-color)}:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.3125rem 0.9375rem}@media(min-width: 45em){:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.375rem 1.25rem;display:flex;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}.wrapper{display:grid;grid-template-columns:1fr 2fr;padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem);gap:.625rem}@media(min-width: 45em){.wrapper{display:block;padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}.mobile-header{font-weight:600}.mobile-header:empty{display:none}.mobile-header:empty+div{grid-column:span 2}@media(min-width: 45em){.mobile-header{display:none}}zui-icon{--zui-icon-size: 1.125rem;vertical-align:middle;margin-left:.625rem;fill:var(--zui-table-cell-sort-color)}.is-selectable{cursor:pointer}`;
|
|
3
3
|
//# sourceMappingURL=zui-table-cell-css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zui-table-cell-css.js","sourceRoot":"","sources":["../src/zui-table-cell-css.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA,
|
|
1
|
+
{"version":3,"file":"zui-table-cell-css.js","sourceRoot":"","sources":["../src/zui-table-cell-css.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA,grCAAgrC,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const style = css`:host{--zui-table-cell-sort-active-color: var(--zui-blue);--zui-table-cell-sort-color: var(--zui-gray-300);contain:none;overflow-wrap:break-word}:host([sort=ascending]) zui-icon{--zui-icon-sort-ascending-color: var(--zui-table-cell-sort-active-color)}:host([sort=descending]) zui-icon{--zui-icon-sort-descending-color: var(--zui-table-cell-sort-active-color)}:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.3125rem 0.9375rem}@media(min-width: 45em){:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.375rem 1.25rem;display:flex;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}.wrapper{display:grid;grid-template-columns:1fr 2fr;padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem);gap:.625rem}@media(min-width: 45em){.wrapper{display:block;padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}.mobile-header{font-weight:600}.mobile-header:empty{display:none}.mobile-header:empty+div{grid-column:span 2}@media(min-width: 45em){.mobile-header{display:none}}zui-icon{--zui-icon-size: 1.125rem;vertical-align:middle;margin-left:.625rem;fill:var(--zui-table-cell-sort-color)}.is-selectable{cursor:pointer}`;\n"]}
|
package/dist/zui-table-cell.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare class ZuiTableCellElement extends ZuiTableBaseElement {
|
|
|
32
32
|
* This private field is needed to persist state between the cell and the header row. DO NOT USE EXTERNALLY
|
|
33
33
|
*/
|
|
34
34
|
private _isAllowedSort;
|
|
35
|
+
private _header?;
|
|
35
36
|
static get styles(): (import("lit").CSSResult | import("lit").CSSResultArray)[];
|
|
36
37
|
render(): import("lit-html").TemplateResult<1>;
|
|
37
38
|
/**
|
package/dist/zui-table-cell.js
CHANGED
|
@@ -72,10 +72,13 @@ export class ZuiTableCellElement extends ZuiTableBaseElement {
|
|
|
72
72
|
import('@zywave/zui-icons');
|
|
73
73
|
}
|
|
74
74
|
const styles = { 'is-selectable': this.sortable };
|
|
75
|
-
return html `<div
|
|
76
|
-
|
|
77
|
-
${this
|
|
78
|
-
|
|
75
|
+
return html `<div class="wrapper"
|
|
76
|
+
><div class="mobile-header">${this._header ?? ''}</div
|
|
77
|
+
><div @click="${this.#onSortableClick}" class="${classMap(styles)}">
|
|
78
|
+
<slot></slot>
|
|
79
|
+
${this.sortable ? html `<zui-icon icon="zui-sort"></zui-icon>` : nothing}
|
|
80
|
+
</div></div
|
|
81
|
+
>`;
|
|
79
82
|
}
|
|
80
83
|
/**
|
|
81
84
|
* Handles click event on sortable header cells
|
|
@@ -113,5 +116,8 @@ __decorate([
|
|
|
113
116
|
__decorate([
|
|
114
117
|
state()
|
|
115
118
|
], ZuiTableCellElement.prototype, "_isAllowedSort", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
state()
|
|
121
|
+
], ZuiTableCellElement.prototype, "_header", void 0);
|
|
116
122
|
window.customElements.define('zui-table-cell', ZuiTableCellElement);
|
|
117
123
|
//# sourceMappingURL=zui-table-cell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zui-table-cell.js","sourceRoot":"","sources":["../src/zui-table-cell.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,mBAAoB,SAAQ,mBAAmB;IAA5D;;QACE;;WAEG;QAEH,WAAM,GAAG,KAAK,CAAC;QAmCf;;WAEG;QAEK,mBAAc,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"zui-table-cell.js","sourceRoot":"","sources":["../src/zui-table-cell.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZuiTableBaseElement } from './base.js';\nimport { html, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { style } from './zui-table-cell-css.js';\n\n/**\n * An individual table cell to be passed into a `<zui-table-row>`.\n *\n * @element zui-table-cell\n *\n * @slot - Default, unnamed slot; for inserting table cell content into `<zui-table-cell>`\n *\n * @cssprop [--zui-table-cell-padding=13px 20px] - Override cell padding\n * @cssprop [--zui-table-cell-sort-color=var(--zui-gray-300)] - ([sortable]): Default color of chevron when `direction` is `null`\n * @cssprop [--zui-table-cell-sort-active-color=var(--zui-blue)] - Highlight color used to indicate the active sort direction\n *\n */\nexport class ZuiTableCellElement extends ZuiTableBaseElement {\n /**\n * Set to decrease table cell padding to accommodate action button(s)\n */\n @property({ type: Boolean, reflect: true })\n action = false;\n\n /**\n * Current sort direction of the sortable cell\n * @type {null | \"ascending\" | \"descending\"}\n */\n @property({ type: String, reflect: true })\n get sort(): ZuiTableSortDirection {\n return this.#sort;\n }\n\n set sort(val: ZuiTableSortDirection) {\n const acceptableVals = ['ascending', 'descending', null];\n if (acceptableVals.includes(val)) {\n const oldVal = this.#sort;\n this.#sort = val;\n this.requestUpdate('sort', oldVal);\n this._state?.channel.dispatchEvent(new CustomEvent('sort', { detail: { sort: val, cell: this } }));\n }\n }\n\n /**\n * (`zui-table-row[header]`): Whether or not cell header is sortable; another requirement is the parent element, `<zui-table-cell header>` must have `header` attribute or property set\n */\n @property({ type: Boolean, reflect: true })\n get sortable() {\n return this._isAllowedSort && this.#sortable;\n }\n\n set sortable(val: boolean) {\n const oldVal = this.#sortable;\n this.#sortable = val;\n this.requestUpdate('sortable', oldVal);\n }\n\n /**\n * This private field is needed to persist state between the cell and the header row. DO NOT USE EXTERNALLY\n */\n @state()\n private _isAllowedSort = false;\n\n @state()\n private _header?: string;\n\n #sort: ZuiTableSortDirection = null;\n #sortable = false;\n\n static get styles() {\n return [super.styles, style];\n }\n\n render() {\n if (this.sortable) {\n import('@zywave/zui-icons');\n }\n const styles = { 'is-selectable': this.sortable };\n return html`<div class=\"wrapper\"\n ><div class=\"mobile-header\">${this._header ?? ''}</div\n ><div @click=\"${this.#onSortableClick}\" class=\"${classMap(styles)}\">\n <slot></slot>\n ${this.sortable ? html`<zui-icon icon=\"zui-sort\"></zui-icon>` : nothing}\n </div></div\n >`;\n }\n\n /**\n * Handles click event on sortable header cells\n */\n click() {\n super.click();\n\n this.#onSortableClick();\n }\n\n #onSortableClick() {\n if (this.sortable) {\n switch (this.sort) {\n case 'ascending':\n this.sort = 'descending';\n break;\n case 'descending':\n this.sort = null;\n break;\n case null:\n default:\n this.sort = 'ascending';\n break;\n }\n }\n }\n}\n\nwindow.customElements.define('zui-table-cell', ZuiTableCellElement);\n\nexport type ZuiTableSortDirection = null | 'ascending' | 'descending';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'zui-table-cell': ZuiTableCellElement;\n }\n}\n"]}
|
package/dist/zui-table.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export declare class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
50
50
|
static get styles(): (import("lit").CSSResult | import("lit").CSSResultArray)[];
|
|
51
51
|
constructor();
|
|
52
52
|
connectedCallback(): void;
|
|
53
|
-
|
|
53
|
+
firstUpdated(changedProperties: PropertyValues<this>): void;
|
|
54
54
|
updated(changedProperties: PropertyValues<this>): void;
|
|
55
55
|
render(): import("lit-html").TemplateResult<1>;
|
|
56
56
|
}
|
package/dist/zui-table.js
CHANGED
|
@@ -8,7 +8,6 @@ import { ZuiTableBaseElement } from './base.js';
|
|
|
8
8
|
import { html } from 'lit';
|
|
9
9
|
import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
10
10
|
import { style } from './zui-table-css.js';
|
|
11
|
-
import { screenBreakpoints } from '@zywave/zui-base/dist/utils/breakpoints.js';
|
|
12
11
|
import '@zywave/zui-spinner';
|
|
13
12
|
import { updateCustomState } from '@zywave/zui-base/dist/utils/update-custom-state.js';
|
|
14
13
|
/**
|
|
@@ -35,9 +34,7 @@ import { updateCustomState } from '@zywave/zui-base/dist/utils/update-custom-sta
|
|
|
35
34
|
*/
|
|
36
35
|
export class ZuiTableElement extends ZuiTableBaseElement {
|
|
37
36
|
#internals;
|
|
38
|
-
#mobileBreakpoint;
|
|
39
37
|
#sortLock;
|
|
40
|
-
#mobileHeadersEvent;
|
|
41
38
|
static get styles() {
|
|
42
39
|
return [super.styles, style];
|
|
43
40
|
}
|
|
@@ -63,12 +60,9 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
63
60
|
* Set to show a loading spinner in the table
|
|
64
61
|
*/
|
|
65
62
|
this.loading = false;
|
|
66
|
-
this.#mobileBreakpoint = window.matchMedia(`only screen and (max-width: ${screenBreakpoints.xsmall})`);
|
|
67
63
|
this.#sortLock = false;
|
|
68
|
-
this.#
|
|
69
|
-
|
|
70
|
-
};
|
|
71
|
-
this.#internals = this.attachInternals?.();
|
|
64
|
+
this.#internals = this.attachInternals();
|
|
65
|
+
this.#internals.role = 'table';
|
|
72
66
|
ZuiTableBaseElement._globalChannel.addEventListener('connected', (event) => {
|
|
73
67
|
if (this.contains(event.detail.element)) {
|
|
74
68
|
this._associateElement(event.detail.element);
|
|
@@ -86,11 +80,10 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
86
80
|
connectedCallback() {
|
|
87
81
|
super.connectedCallback();
|
|
88
82
|
this.setAttribute('role', 'table');
|
|
89
|
-
this.#mobileBreakpoint.addEventListener('change', this.#mobileHeadersEvent);
|
|
90
83
|
}
|
|
91
|
-
|
|
92
|
-
super.
|
|
93
|
-
this.#
|
|
84
|
+
firstUpdated(changedProperties) {
|
|
85
|
+
super.firstUpdated(changedProperties);
|
|
86
|
+
this.#addRowHeadersToCells();
|
|
94
87
|
}
|
|
95
88
|
updated(changedProperties) {
|
|
96
89
|
super.updated(changedProperties);
|
|
@@ -102,7 +95,6 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
102
95
|
header?.setAttribute('slot', 'header');
|
|
103
96
|
topbar?.setAttribute('slot', 'topbar');
|
|
104
97
|
summary?.setAttribute('slot', 'summary');
|
|
105
|
-
this.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
|
|
106
98
|
}
|
|
107
99
|
render() {
|
|
108
100
|
return html `<div class="wrapper">
|
|
@@ -122,42 +114,22 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
122
114
|
<div><slot name="footer"></slot></div>`;
|
|
123
115
|
}
|
|
124
116
|
#onSlotChange() {
|
|
125
|
-
this.#
|
|
117
|
+
this.#addRowHeadersToCells();
|
|
126
118
|
this.requestUpdate();
|
|
127
119
|
}
|
|
128
|
-
#addRowHeadersToCells() {
|
|
120
|
+
async #addRowHeadersToCells() {
|
|
129
121
|
const headerRow = this.querySelector('zui-table-row[header]');
|
|
130
122
|
if (headerRow) {
|
|
131
123
|
const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));
|
|
132
124
|
for (const row of rowBodyList) {
|
|
133
125
|
for (let i = 0; i < row.children.length; i++) {
|
|
134
126
|
const cell = row.children[i];
|
|
135
|
-
|
|
136
|
-
const rowHeaderContainer = document.createElement('div');
|
|
137
|
-
rowHeaderContainer.classList.add('header');
|
|
138
|
-
const rowHeaderText = headerRow.children[i].textContent;
|
|
139
|
-
rowHeaderContainer.innerText = rowHeaderText;
|
|
140
|
-
cell.shadowRoot.prepend(rowHeaderContainer);
|
|
141
|
-
}
|
|
127
|
+
cell._header = headerRow.children?.[i]?.textContent ?? '';
|
|
142
128
|
}
|
|
143
129
|
}
|
|
144
130
|
}
|
|
145
131
|
updateCustomState(this.#internals, 'add', 'mobile');
|
|
146
132
|
}
|
|
147
|
-
#removeRowHeadersFromCells() {
|
|
148
|
-
const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));
|
|
149
|
-
for (const row of rowBodyList) {
|
|
150
|
-
for (let i = 0; i < row.children.length; i++) {
|
|
151
|
-
const rowChildren = row.children[i].shadowRoot;
|
|
152
|
-
const header = rowChildren.querySelector('.header');
|
|
153
|
-
if (header) {
|
|
154
|
-
rowChildren.removeChild(header);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
// remove custom state --mobile from zui-table
|
|
159
|
-
updateCustomState(this.#internals, 'delete', 'mobile');
|
|
160
|
-
}
|
|
161
133
|
}
|
|
162
134
|
__decorate([
|
|
163
135
|
property({ type: Boolean, reflect: true })
|
package/dist/zui-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zui-table.js","sourceRoot":"","sources":["../src/zui-table.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZuiTableBaseElement, TableElementConnectedEvent } from './base.js';\nimport { html } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { style } from './zui-table-css.js';\nimport { screenBreakpoints } from '@zywave/zui-base/dist/utils/breakpoints.js';\nimport '@zywave/zui-spinner';\nimport { updateCustomState } from '@zywave/zui-base/dist/utils/update-custom-state.js';\nimport type { ZuiTableRowElement } from './zui-table-row.js';\nimport type { ZuiTableCellElement, ZuiTableSortDirection } from './zui-table-cell.js';\nimport type { PropertyValues } from 'lit';\n\ntype ZuiTableMode = 'default' | 'fixed-sizing';\n\n/**\n * A standardized responsive table component.\n *\n * @element zui-table\n *\n * @slot - Default, unnamed slot; for inserting `<zui-table-topbar>`, `<zui-table-row>`, and `<zui-table-footer>` elements, including a custom no results view, into `<zui-table>`\n * @slot no-results-message - Customize the no results message that is shown when the `no-results` attribute is set on `<zui-table>`: `<zui-table no-results>`\n * @slot footer - Only for `<zui-table-footer>`. When there is a `<zui-table-footer>` present inside `<zui-table>`, it will be auto-assigned to this slot in order to place it outside of the rendered table for styling purposes.\n *\n * @cssprop [--zui-table-cell-padding=13px 20px] - Override cell padding\n * @cssprop [--zui-table-columns-template=repeat(auto-fit, minmax(0, 1fr))] - Override the table columns template. See https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns for more information on valid values.\n * @cssprop [--zui-table-footer-margin=10px] - Override the margin between the table and footer of the table\n * @cssprop [--zui-table-max-height=none] - Set the maximum height of the table when table `mode` is set to `fixed-sizing`. Required for vertical scrolling to work.\n * @cssprop [--zui-table-max-width=none] - Set the maximum width of the table when table `mode` is set to `fixed-sizing`, but not required for horizontal scrolling to work.\n * @cssprop [--zui-table-loading-min-height=20rem] - Override the minimum height of the table body when in a loading state\n * @cssprop [--zui-table-summary-background-color=var(--zui-gray-600)] - Override the table summary background color\n * @cssprop [--zui-table-summary-text-color=#fff] - Override the the table summary text color\n *\n * @event sort - Event fires when the table's active sort changes. Event detail is an object with the `sort` direction and `cell` ZuiTableCellElement.\n *\n * @cssState mobile - Applied when the table is rendered in mobile mode\n */\nexport class ZuiTableElement extends ZuiTableBaseElement {\n /**\n * Set for alternating table row background colors\n */\n @property({ type: Boolean, reflect: true })\n banded = false;\n\n /**\n * Ability to modify the table's layout behavior. The supported values are:\n * - `default` (default): Table width is determined by its content. Columns will expand to fit the content within them.\n * - `fixed-sizing`: Opts-in to constrainig dimensions by the `--zui-table-max-width` and `--zui-table-max-height` CSS properties. This unlocks the ability to make a table vertically and horizontally scrollable within a container. The following CSS properties are required: `--zui-table-columns-template`. You should set at least one of the following: `--zui-table-max-width`, `--zui-table-max-height`.\n * @type { 'default' | 'fixed-sizing' }\n */\n @property({ reflect: true })\n mode: ZuiTableMode = 'default';\n\n // TODO: add divided prop so all table cells will have 1px border\n\n /**\n * Set to show or hide no results message when there are no results; use in conjunction with the assigned slot `no-results-message` to include a no results message\n */\n @property({ type: Boolean, reflect: true, attribute: 'no-results' })\n noResults = false;\n\n /**\n * Set to show a loading spinner in the table\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n @queryAssignedElements({ selector: 'zui-table-row' })\n private _rows: Array<ZuiTableRowElement>;\n\n #internals?: ElementInternals;\n #mobileBreakpoint: MediaQueryList = window.matchMedia(`only screen and (max-width: ${screenBreakpoints.xsmall})`);\n #sortLock = false;\n\n #mobileHeadersEvent = (b: MediaQueryListEvent) => {\n b.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();\n };\n\n static get styles() {\n return [super.styles, style];\n }\n\n constructor() {\n super();\n\n this.#internals = this.attachInternals?.();\n\n ZuiTableBaseElement._globalChannel.addEventListener('connected', (event: TableElementConnectedEvent) => {\n if (this.contains(event.detail.element)) {\n this._associateElement(event.detail.element);\n }\n });\n\n this._state.channel.addEventListener('sort', (event: CustomEvent<SortEventDetail>) => {\n if (this.#sortLock) {\n return;\n }\n this.#sortLock = true;\n this.dispatchEvent(new CustomEvent<SortEventDetail>('sort', { detail: event.detail, bubbles: true }));\n setTimeout(() => (this.#sortLock = false), 0);\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'table');\n\n this.#mobileBreakpoint.addEventListener('change', this.#mobileHeadersEvent);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n\n this.#mobileBreakpoint.removeEventListener('change', this.#mobileHeadersEvent);\n }\n\n updated(changedProperties: PropertyValues<this>) {\n super.updated(changedProperties);\n\n const footer = this.querySelector('zui-table-footer:not([slot])');\n const header = this.querySelector('zui-table-row[header]:not([slot])');\n const topbar = this.querySelector('zui-table-topbar:not([slot])');\n const summary = this.querySelector('zui-table-row[summary]:not([slot])');\n footer?.setAttribute('slot', 'footer');\n header?.setAttribute('slot', 'header');\n topbar?.setAttribute('slot', 'topbar');\n summary?.setAttribute('slot', 'summary');\n\n this.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();\n }\n\n render() {\n return html`<div class=\"wrapper\">\n <slot name=\"topbar\"></slot>\n <div class=\"table-wrapper\">\n <div class=\"table\" role=\"rowgroup\">\n <slot name=\"header\" @slotchange=\"${this.#onSlotChange}\"></slot>\n <div class=\"body\">\n <slot @slotchange=\"${this.#onSlotChange}\"></slot>\n ${this.loading ? html`<zui-spinner active=\"\" part=\"loader\"></zui-spinner>` : html``}\n <div class=\"no-results\"><slot name=\"no-results-message\"></slot></div>\n </div>\n </div>\n <slot name=\"summary\"></slot>\n </div>\n </div>\n <div><slot name=\"footer\"></slot></div>`;\n }\n\n #onSlotChange() {\n this.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();\n this.requestUpdate();\n }\n\n #addRowHeadersToCells() {\n const headerRow = this.querySelector('zui-table-row[header]');\n\n if (headerRow) {\n const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));\n for (const row of rowBodyList) {\n for (let i = 0; i < row.children.length; i++) {\n const cell = row.children[i];\n if (!cell.shadowRoot.querySelector('.header')) {\n const rowHeaderContainer = document.createElement('div');\n rowHeaderContainer.classList.add('header');\n const rowHeaderText = headerRow.children[i].textContent;\n rowHeaderContainer.innerText = rowHeaderText;\n cell.shadowRoot.prepend(rowHeaderContainer);\n }\n }\n }\n }\n\n updateCustomState(this.#internals, 'add', 'mobile');\n }\n\n #removeRowHeadersFromCells() {\n const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));\n\n for (const row of rowBodyList) {\n for (let i = 0; i < row.children.length; i++) {\n const rowChildren = row.children[i].shadowRoot;\n const header = rowChildren.querySelector('.header');\n if (header) {\n rowChildren.removeChild(header);\n }\n }\n }\n\n // remove custom state --mobile from zui-table\n updateCustomState(this.#internals, 'delete', 'mobile');\n }\n}\n\nwindow.customElements.define('zui-table', ZuiTableElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'zui-table': ZuiTableElement;\n }\n}\n\nexport type SortEventDetail = { sort: ZuiTableSortDirection; cell: ZuiTableCellElement };\n"]}
|
|
1
|
+
{"version":3,"file":"zui-table.js","sourceRoot":"","sources":["../src/zui-table.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZuiTableBaseElement, TableElementConnectedEvent } from './base.js';\nimport { html } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { style } from './zui-table-css.js';\nimport '@zywave/zui-spinner';\nimport { updateCustomState } from '@zywave/zui-base/dist/utils/update-custom-state.js';\nimport type { ZuiTableRowElement } from './zui-table-row.js';\nimport type { ZuiTableCellElement, ZuiTableSortDirection } from './zui-table-cell.js';\nimport type { PropertyValues } from 'lit';\n\ntype ZuiTableMode = 'default' | 'fixed-sizing';\n\n/**\n * A standardized responsive table component.\n *\n * @element zui-table\n *\n * @slot - Default, unnamed slot; for inserting `<zui-table-topbar>`, `<zui-table-row>`, and `<zui-table-footer>` elements, including a custom no results view, into `<zui-table>`\n * @slot no-results-message - Customize the no results message that is shown when the `no-results` attribute is set on `<zui-table>`: `<zui-table no-results>`\n * @slot footer - Only for `<zui-table-footer>`. When there is a `<zui-table-footer>` present inside `<zui-table>`, it will be auto-assigned to this slot in order to place it outside of the rendered table for styling purposes.\n *\n * @cssprop [--zui-table-cell-padding=13px 20px] - Override cell padding\n * @cssprop [--zui-table-columns-template=repeat(auto-fit, minmax(0, 1fr))] - Override the table columns template. See https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns for more information on valid values.\n * @cssprop [--zui-table-footer-margin=10px] - Override the margin between the table and footer of the table\n * @cssprop [--zui-table-max-height=none] - Set the maximum height of the table when table `mode` is set to `fixed-sizing`. Required for vertical scrolling to work.\n * @cssprop [--zui-table-max-width=none] - Set the maximum width of the table when table `mode` is set to `fixed-sizing`, but not required for horizontal scrolling to work.\n * @cssprop [--zui-table-loading-min-height=20rem] - Override the minimum height of the table body when in a loading state\n * @cssprop [--zui-table-summary-background-color=var(--zui-gray-600)] - Override the table summary background color\n * @cssprop [--zui-table-summary-text-color=#fff] - Override the the table summary text color\n *\n * @event sort - Event fires when the table's active sort changes. Event detail is an object with the `sort` direction and `cell` ZuiTableCellElement.\n *\n * @cssState mobile - Applied when the table is rendered in mobile mode\n */\nexport class ZuiTableElement extends ZuiTableBaseElement {\n /**\n * Set for alternating table row background colors\n */\n @property({ type: Boolean, reflect: true })\n banded = false;\n\n /**\n * Ability to modify the table's layout behavior. The supported values are:\n * - `default` (default): Table width is determined by its content. Columns will expand to fit the content within them.\n * - `fixed-sizing`: Opts-in to constrainig dimensions by the `--zui-table-max-width` and `--zui-table-max-height` CSS properties. This unlocks the ability to make a table vertically and horizontally scrollable within a container. The following CSS properties are required: `--zui-table-columns-template`. You should set at least one of the following: `--zui-table-max-width`, `--zui-table-max-height`.\n * @type { 'default' | 'fixed-sizing' }\n */\n @property({ reflect: true })\n mode: ZuiTableMode = 'default';\n\n // TODO: add divided prop so all table cells will have 1px border\n\n /**\n * Set to show or hide no results message when there are no results; use in conjunction with the assigned slot `no-results-message` to include a no results message\n */\n @property({ type: Boolean, reflect: true, attribute: 'no-results' })\n noResults = false;\n\n /**\n * Set to show a loading spinner in the table\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n @queryAssignedElements({ selector: 'zui-table-row' })\n private _rows: Array<ZuiTableRowElement>;\n\n #internals: ElementInternals;\n #sortLock = false;\n\n static get styles() {\n return [super.styles, style];\n }\n\n constructor() {\n super();\n\n this.#internals = this.attachInternals();\n this.#internals.role = 'table';\n\n ZuiTableBaseElement._globalChannel.addEventListener('connected', (event: TableElementConnectedEvent) => {\n if (this.contains(event.detail.element)) {\n this._associateElement(event.detail.element);\n }\n });\n\n this._state.channel.addEventListener('sort', (event: CustomEvent<SortEventDetail>) => {\n if (this.#sortLock) {\n return;\n }\n this.#sortLock = true;\n this.dispatchEvent(new CustomEvent<SortEventDetail>('sort', { detail: event.detail, bubbles: true }));\n setTimeout(() => (this.#sortLock = false), 0);\n });\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'table');\n }\n\n firstUpdated(changedProperties: PropertyValues<this>) {\n super.firstUpdated(changedProperties);\n this.#addRowHeadersToCells();\n }\n\n updated(changedProperties: PropertyValues<this>) {\n super.updated(changedProperties);\n\n const footer = this.querySelector('zui-table-footer:not([slot])');\n const header = this.querySelector('zui-table-row[header]:not([slot])');\n const topbar = this.querySelector('zui-table-topbar:not([slot])');\n const summary = this.querySelector('zui-table-row[summary]:not([slot])');\n footer?.setAttribute('slot', 'footer');\n header?.setAttribute('slot', 'header');\n topbar?.setAttribute('slot', 'topbar');\n summary?.setAttribute('slot', 'summary');\n }\n\n render() {\n return html`<div class=\"wrapper\">\n <slot name=\"topbar\"></slot>\n <div class=\"table-wrapper\">\n <div class=\"table\" role=\"rowgroup\">\n <slot name=\"header\" @slotchange=\"${this.#onSlotChange}\"></slot>\n <div class=\"body\">\n <slot @slotchange=\"${this.#onSlotChange}\"></slot>\n ${this.loading ? html`<zui-spinner active=\"\" part=\"loader\"></zui-spinner>` : html``}\n <div class=\"no-results\"><slot name=\"no-results-message\"></slot></div>\n </div>\n </div>\n <slot name=\"summary\"></slot>\n </div>\n </div>\n <div><slot name=\"footer\"></slot></div>`;\n }\n\n #onSlotChange() {\n this.#addRowHeadersToCells();\n this.requestUpdate();\n }\n\n async #addRowHeadersToCells() {\n const headerRow = this.querySelector('zui-table-row[header]');\n\n if (headerRow) {\n const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));\n for (const row of rowBodyList) {\n for (let i = 0; i < row.children.length; i++) {\n const cell = row.children[i];\n (cell as ZuiTableCellWithState)._header = headerRow.children?.[i]?.textContent ?? '';\n }\n }\n }\n\n updateCustomState(this.#internals, 'add', 'mobile');\n }\n}\n\nwindow.customElements.define('zui-table', ZuiTableElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'zui-table': ZuiTableElement;\n }\n}\n\nexport type SortEventDetail = { sort: ZuiTableSortDirection; cell: ZuiTableCellElement };\n\ntype ZuiTableCellWithState = HTMLElement & { _header: string };\n"]}
|
package/lab.html
CHANGED
|
@@ -13,10 +13,12 @@
|
|
|
13
13
|
<link rel="stylesheet" href="./dist/css/zui-table.fouc.css" />
|
|
14
14
|
<link rel="stylesheet" href="../../../node_modules/@zywave/zui-button/dist/css/zui-button.fouc.css" />
|
|
15
15
|
<link rel="stylesheet" href="../../../node_modules/@zywave/zui-icons/dist/css/zui-icons.fouc.css" />
|
|
16
|
+
<link rel="stylesheet" href="../../../node_modules/@zywave/zui-input/dist/css/zui-input.fouc.css" />
|
|
16
17
|
<link rel="stylesheet" href="../../../node_modules/@zywave/zui-pager/dist/css/zui-pager.fouc.css" />
|
|
17
18
|
<link rel="stylesheet" href="../../../node_modules/@zywave/zui-search/dist/css/zui-search.fouc.css" />
|
|
18
19
|
<script src="./dist/index.js" type="module" async></script>
|
|
19
20
|
<script src="../../../node_modules/@zywave/zui-button/dist/index.js" type="module"></script>
|
|
21
|
+
<script src="../../../node_modules/@zywave/zui-input/dist/index.js" type="module"></script>
|
|
20
22
|
<script src="../../../node_modules/@zywave/zui-pager/dist/index.js" type="module"></script>
|
|
21
23
|
<script src="../../../node_modules/@zywave/zui-search/dist/index.js" type="module"></script>
|
|
22
24
|
|
|
@@ -53,6 +55,10 @@
|
|
|
53
55
|
--zui-table-max-height: 200px;
|
|
54
56
|
--zui-table-columns-template: repeat(8, 200px);
|
|
55
57
|
}
|
|
58
|
+
|
|
59
|
+
zui-table.editable {
|
|
60
|
+
--zui-table-cell-padding: 0;
|
|
61
|
+
}
|
|
56
62
|
</style>
|
|
57
63
|
</head>
|
|
58
64
|
|
|
@@ -61,7 +67,7 @@
|
|
|
61
67
|
|
|
62
68
|
<h2>Basic table</h2>
|
|
63
69
|
|
|
64
|
-
<zui-table
|
|
70
|
+
<zui-table>
|
|
65
71
|
<zui-table-row>
|
|
66
72
|
<zui-table-cell>Paulus Atreides</zui-table-cell>
|
|
67
73
|
<zui-table-cell>Old Duke</zui-table-cell>
|
|
@@ -301,7 +307,7 @@
|
|
|
301
307
|
|
|
302
308
|
<h2>Table with row headers</h2>
|
|
303
309
|
|
|
304
|
-
<zui-table
|
|
310
|
+
<zui-table>
|
|
305
311
|
<zui-table-row header>
|
|
306
312
|
<zui-table-cell>Name</zui-table-cell>
|
|
307
313
|
<zui-table-cell>Title</zui-table-cell>
|
|
@@ -862,7 +868,7 @@
|
|
|
862
868
|
|
|
863
869
|
<h2>Table with footer</h2>
|
|
864
870
|
|
|
865
|
-
<zui-table
|
|
871
|
+
<zui-table>
|
|
866
872
|
<zui-table-topbar>
|
|
867
873
|
<zui-search placeholder="Search for a family member" no-submit></zui-search>
|
|
868
874
|
<div slot="counter">5 family members</div>
|
|
@@ -937,7 +943,7 @@
|
|
|
937
943
|
|
|
938
944
|
<h2>No results table with simple custom message</h2>
|
|
939
945
|
|
|
940
|
-
<zui-table no-results=""
|
|
946
|
+
<zui-table no-results="">
|
|
941
947
|
<zui-table-topbar>
|
|
942
948
|
<zui-search placeholder="Search for a family member" value="Spongebob Squarepants" no-submit></zui-search>
|
|
943
949
|
<div slot="counter">0 family members</div>
|
|
@@ -1222,6 +1228,158 @@
|
|
|
1222
1228
|
</zui-table-footer>
|
|
1223
1229
|
</zui-table>
|
|
1224
1230
|
|
|
1231
|
+
<h2>Loading table</h2>
|
|
1232
|
+
|
|
1233
|
+
<zui-table loading>
|
|
1234
|
+
<zui-table-topbar>
|
|
1235
|
+
<zui-search placeholder="Search for a family member" no-submit></zui-search>
|
|
1236
|
+
<div slot="counter">5 family members</div>
|
|
1237
|
+
<zui-button slot="action" type="secondary">Whisper</zui-button>
|
|
1238
|
+
<zui-button slot="action">Add a family member</zui-button>
|
|
1239
|
+
</zui-table-topbar>
|
|
1240
|
+
<zui-table-row header>
|
|
1241
|
+
<zui-table-cell>Name</zui-table-cell>
|
|
1242
|
+
<zui-table-cell>Title</zui-table-cell>
|
|
1243
|
+
<zui-table-cell>Born</zui-table-cell>
|
|
1244
|
+
<zui-table-cell>Died</zui-table-cell>
|
|
1245
|
+
<zui-table-cell>Age</zui-table-cell>
|
|
1246
|
+
<zui-table-cell>Action</zui-table-cell>
|
|
1247
|
+
</zui-table-row>
|
|
1248
|
+
<zui-table-row>
|
|
1249
|
+
<zui-table-cell>Paulus Atreides</zui-table-cell>
|
|
1250
|
+
<zui-table-cell>Old Duke</zui-table-cell>
|
|
1251
|
+
<zui-table-cell>10,089 A.G.</zui-table-cell>
|
|
1252
|
+
<zui-table-cell>10,156 A.G.</zui-table-cell>
|
|
1253
|
+
<zui-table-cell>67 years old</zui-table-cell>
|
|
1254
|
+
<zui-table-cell action>
|
|
1255
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1256
|
+
</zui-table-cell>
|
|
1257
|
+
</zui-table-row>
|
|
1258
|
+
<zui-table-row>
|
|
1259
|
+
<zui-table-cell>Leto Atreides I</zui-table-cell>
|
|
1260
|
+
<zui-table-cell>Red Duke</zui-table-cell>
|
|
1261
|
+
<zui-table-cell>10,140 A.G.</zui-table-cell>
|
|
1262
|
+
<zui-table-cell>10,191 A.G.</zui-table-cell>
|
|
1263
|
+
<zui-table-cell>51 years old</zui-table-cell>
|
|
1264
|
+
<zui-table-cell action>
|
|
1265
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1266
|
+
</zui-table-cell>
|
|
1267
|
+
</zui-table-row>
|
|
1268
|
+
<zui-table-row>
|
|
1269
|
+
<zui-table-cell>Paul Atreides</zui-table-cell>
|
|
1270
|
+
<zui-table-cell>Padishah Emperor</zui-table-cell>
|
|
1271
|
+
<zui-table-cell>10,176 A.G.</zui-table-cell>
|
|
1272
|
+
<zui-table-cell>10,219 A.G.</zui-table-cell>
|
|
1273
|
+
<zui-table-cell>43 years old</zui-table-cell>
|
|
1274
|
+
<zui-table-cell action>
|
|
1275
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1276
|
+
</zui-table-cell>
|
|
1277
|
+
</zui-table-row>
|
|
1278
|
+
<zui-table-row>
|
|
1279
|
+
<zui-table-cell>Alia Atreides</zui-table-cell>
|
|
1280
|
+
<zui-table-cell>Imperial Regent</zui-table-cell>
|
|
1281
|
+
<zui-table-cell>10,191 A.G.</zui-table-cell>
|
|
1282
|
+
<zui-table-cell>10,219 A.G.</zui-table-cell>
|
|
1283
|
+
<zui-table-cell>28 years old</zui-table-cell>
|
|
1284
|
+
<zui-table-cell action>
|
|
1285
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1286
|
+
</zui-table-cell>
|
|
1287
|
+
</zui-table-row>
|
|
1288
|
+
<zui-table-row>
|
|
1289
|
+
<zui-table-cell>Leto Atreides II</zui-table-cell>
|
|
1290
|
+
<zui-table-cell>God Emperor</zui-table-cell>
|
|
1291
|
+
<zui-table-cell>10,207 A.G.</zui-table-cell>
|
|
1292
|
+
<zui-table-cell>13,728 A.G.</zui-table-cell>
|
|
1293
|
+
<zui-table-cell>3,521 years old</zui-table-cell>
|
|
1294
|
+
<zui-table-cell action>
|
|
1295
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1296
|
+
</zui-table-cell>
|
|
1297
|
+
</zui-table-row>
|
|
1298
|
+
<zui-table-row summary>
|
|
1299
|
+
<zui-table-cell style="text-align: right"> Average lifespan: 742 years </zui-table-cell>
|
|
1300
|
+
</zui-table-row>
|
|
1301
|
+
<zui-table-footer>
|
|
1302
|
+
<zui-pager current-page="1" total-pages="10"></zui-pager>
|
|
1303
|
+
</zui-table-footer>
|
|
1304
|
+
</zui-table>
|
|
1305
|
+
|
|
1306
|
+
<h2>Table with editable cells</h2>
|
|
1307
|
+
|
|
1308
|
+
<zui-table class="editable">
|
|
1309
|
+
<zui-table-topbar>
|
|
1310
|
+
<zui-search placeholder="Search for a family member" no-submit></zui-search>
|
|
1311
|
+
<div slot="counter">5 family members</div>
|
|
1312
|
+
<zui-button slot="action" type="secondary">Whisper</zui-button>
|
|
1313
|
+
<zui-button slot="action">Add a family member</zui-button>
|
|
1314
|
+
</zui-table-topbar>
|
|
1315
|
+
<zui-table-row header>
|
|
1316
|
+
<zui-table-cell>Name</zui-table-cell>
|
|
1317
|
+
<zui-table-cell>Title</zui-table-cell>
|
|
1318
|
+
<zui-table-cell>Born</zui-table-cell>
|
|
1319
|
+
<zui-table-cell>Died</zui-table-cell>
|
|
1320
|
+
<zui-table-cell>Age</zui-table-cell>
|
|
1321
|
+
<zui-table-cell>Action</zui-table-cell>
|
|
1322
|
+
</zui-table-row>
|
|
1323
|
+
<zui-table-row>
|
|
1324
|
+
<zui-table-cell>
|
|
1325
|
+
<zui-input value="Paulus Atreides"></zui-input>
|
|
1326
|
+
</zui-table-cell>
|
|
1327
|
+
<zui-table-cell><zui-input value="Old Duke"></zui-input></zui-table-cell>
|
|
1328
|
+
<zui-table-cell><zui-input value="10,089 A.G."></zui-input></zui-table-cell>
|
|
1329
|
+
<zui-table-cell><zui-input value="10,156 A.G."></zui-input></zui-table-cell>
|
|
1330
|
+
<zui-table-cell><zui-input value="67 years old"></zui-input></zui-table-cell>
|
|
1331
|
+
<zui-table-cell action>
|
|
1332
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1333
|
+
</zui-table-cell>
|
|
1334
|
+
</zui-table-row>
|
|
1335
|
+
<zui-table-row>
|
|
1336
|
+
<zui-table-cell><zui-input value="Leto Atreides I"></zui-input></zui-table-cell>
|
|
1337
|
+
<zui-table-cell><zui-input value="Red Duke"></zui-input></zui-table-cell>
|
|
1338
|
+
<zui-table-cell><zui-input value="10,140 A.G."></zui-input></zui-table-cell>
|
|
1339
|
+
<zui-table-cell><zui-input value="10,191 A.G."></zui-input></zui-table-cell>
|
|
1340
|
+
<zui-table-cell><zui-input value="51 years old"></zui-input></zui-table-cell>
|
|
1341
|
+
<zui-table-cell action>
|
|
1342
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1343
|
+
</zui-table-cell>
|
|
1344
|
+
</zui-table-row>
|
|
1345
|
+
<zui-table-row>
|
|
1346
|
+
<zui-table-cell><zui-input value="Paul Atreides"></zui-input></zui-table-cell>
|
|
1347
|
+
<zui-table-cell><zui-input value="Padishah Emperor"></zui-input></zui-table-cell>
|
|
1348
|
+
<zui-table-cell><zui-input value="10,176 A.G."></zui-input></zui-table-cell>
|
|
1349
|
+
<zui-table-cell><zui-input value="10,219 A.G."></zui-input></zui-table-cell>
|
|
1350
|
+
<zui-table-cell><zui-input value="43 years old"></zui-input></zui-table-cell>
|
|
1351
|
+
<zui-table-cell action>
|
|
1352
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1353
|
+
</zui-table-cell>
|
|
1354
|
+
</zui-table-row>
|
|
1355
|
+
<zui-table-row>
|
|
1356
|
+
<zui-table-cell><zui-input value="Alia Atreides"></zui-input></zui-table-cell>
|
|
1357
|
+
<zui-table-cell><zui-input value="Imperial Regent"></zui-input></zui-table-cell>
|
|
1358
|
+
<zui-table-cell><zui-input value="10,191 A.G."></zui-input></zui-table-cell>
|
|
1359
|
+
<zui-table-cell><zui-input value="10,219 A.G."></zui-input></zui-table-cell>
|
|
1360
|
+
<zui-table-cell><zui-input value="28 years old"></zui-input></zui-table-cell>
|
|
1361
|
+
<zui-table-cell action>
|
|
1362
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1363
|
+
</zui-table-cell>
|
|
1364
|
+
</zui-table-row>
|
|
1365
|
+
<zui-table-row>
|
|
1366
|
+
<zui-table-cell><zui-input value="Leto Atreides II"></zui-input></zui-table-cell>
|
|
1367
|
+
<zui-table-cell><zui-input value="God Emperor"></zui-input></zui-table-cell>
|
|
1368
|
+
<zui-table-cell><zui-input value="10,207 A.G."></zui-input></zui-table-cell>
|
|
1369
|
+
<zui-table-cell><zui-input value="13,728 A.G."></zui-input></zui-table-cell>
|
|
1370
|
+
<zui-table-cell><zui-input value="3,521 years old"></zui-input></zui-table-cell>
|
|
1371
|
+
<zui-table-cell action>
|
|
1372
|
+
<zui-button type="secondary">Betray</zui-button>
|
|
1373
|
+
</zui-table-cell>
|
|
1374
|
+
</zui-table-row>
|
|
1375
|
+
<zui-table-row summary>
|
|
1376
|
+
<zui-table-cell style="text-align: right"> Average lifespan: 742 years </zui-table-cell>
|
|
1377
|
+
</zui-table-row>
|
|
1378
|
+
<zui-table-footer>
|
|
1379
|
+
<zui-pager current-page="1" total-pages="10"></zui-pager>
|
|
1380
|
+
</zui-table-footer>
|
|
1381
|
+
</zui-table>
|
|
1382
|
+
|
|
1225
1383
|
<script>
|
|
1226
1384
|
const sortableHeaders = document.querySelectorAll("zui-table-row[header] zui-table-cell[sortable]");
|
|
1227
1385
|
const displaySortDirection = document.querySelector("#table-sorting-value");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zywave/zui-table",
|
|
3
|
-
"version": "4.4.1-pre.
|
|
3
|
+
"version": "4.4.1-pre.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@zywave/zui-button": "^4.1.10-pre.0"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "1f5ba52914630b9b136b0241794a10bd6d473b0c"
|
|
33
33
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
|
|
3
|
-
export const style = css`:host{--zui-table-cell-sort-active-color: var(--zui-blue);--zui-table-cell-sort-color: var(--zui-gray-300);contain:none;overflow-wrap:break-word}:host([sort=ascending]) zui-icon{--zui-icon-sort-ascending-color: var(--zui-table-cell-sort-active-color)}:host([sort=descending]) zui-icon{--zui-icon-sort-descending-color: var(--zui-table-cell-sort-active-color)}:host([action]) div{
|
|
3
|
+
export const style = css`:host{--zui-table-cell-sort-active-color: var(--zui-blue);--zui-table-cell-sort-color: var(--zui-gray-300);contain:none;overflow-wrap:break-word}:host([sort=ascending]) zui-icon{--zui-icon-sort-ascending-color: var(--zui-table-cell-sort-active-color)}:host([sort=descending]) zui-icon{--zui-icon-sort-descending-color: var(--zui-table-cell-sort-active-color)}:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.3125rem 0.9375rem}@media(min-width: 45em){:host([action]) div:not(.mobile-header){--zui-table-cell-padding: 0.375rem 1.25rem;display:flex;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}.wrapper{display:grid;grid-template-columns:1fr 2fr;padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem);gap:.625rem}@media(min-width: 45em){.wrapper{display:block;padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}.mobile-header{font-weight:600}.mobile-header:empty{display:none}.mobile-header:empty+div{grid-column:span 2}@media(min-width: 45em){.mobile-header{display:none}}zui-icon{--zui-icon-size: 1.125rem;vertical-align:middle;margin-left:.625rem;fill:var(--zui-table-cell-sort-color)}.is-selectable{cursor:pointer}`;
|
package/src/zui-table-cell.scss
CHANGED
|
@@ -21,11 +21,12 @@
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
:host([action]) {
|
|
24
|
-
div {
|
|
25
|
-
|
|
24
|
+
div:not(.mobile-header) {
|
|
25
|
+
--zui-table-cell-padding: #{rem(5)} #{rem(15)};
|
|
26
26
|
|
|
27
27
|
@media (min-width: $bp-xs) {
|
|
28
28
|
--zui-table-cell-padding: #{rem(6)} #{rem(20)};
|
|
29
|
+
display: flex;
|
|
29
30
|
align-items: center;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -35,22 +36,32 @@
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
.wrapper {
|
|
40
|
+
display: grid;
|
|
41
|
+
grid-template-columns: 1fr 2fr;
|
|
39
42
|
padding: var(--zui-table-cell-padding, #{rem(5)} #{rem(15)});
|
|
43
|
+
gap: rem(10);
|
|
40
44
|
|
|
41
45
|
@media (min-width: $bp-xs) {
|
|
46
|
+
display: block;
|
|
42
47
|
padding: var(--zui-table-cell-padding, #{rem(13)} #{rem(20)});
|
|
43
48
|
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.mobile-header {
|
|
52
|
+
font-weight: 600;
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
width: 33.333%;
|
|
48
|
-
font-weight: 600;
|
|
54
|
+
&:empty {
|
|
55
|
+
display: none;
|
|
49
56
|
|
|
50
57
|
+ div {
|
|
51
|
-
|
|
58
|
+
grid-column: span 2;
|
|
52
59
|
}
|
|
53
60
|
}
|
|
61
|
+
|
|
62
|
+
@media (min-width: $bp-xs) {
|
|
63
|
+
display: none;
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
zui-icon {
|
package/src/zui-table-cell.ts
CHANGED
|
@@ -62,6 +62,9 @@ export class ZuiTableCellElement extends ZuiTableBaseElement {
|
|
|
62
62
|
@state()
|
|
63
63
|
private _isAllowedSort = false;
|
|
64
64
|
|
|
65
|
+
@state()
|
|
66
|
+
private _header?: string;
|
|
67
|
+
|
|
65
68
|
#sort: ZuiTableSortDirection = null;
|
|
66
69
|
#sortable = false;
|
|
67
70
|
|
|
@@ -74,10 +77,13 @@ export class ZuiTableCellElement extends ZuiTableBaseElement {
|
|
|
74
77
|
import('@zywave/zui-icons');
|
|
75
78
|
}
|
|
76
79
|
const styles = { 'is-selectable': this.sortable };
|
|
77
|
-
return html`<div
|
|
78
|
-
|
|
79
|
-
${this
|
|
80
|
-
|
|
80
|
+
return html`<div class="wrapper"
|
|
81
|
+
><div class="mobile-header">${this._header ?? ''}</div
|
|
82
|
+
><div @click="${this.#onSortableClick}" class="${classMap(styles)}">
|
|
83
|
+
<slot></slot>
|
|
84
|
+
${this.sortable ? html`<zui-icon icon="zui-sort"></zui-icon>` : nothing}
|
|
85
|
+
</div></div
|
|
86
|
+
>`;
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
/**
|
package/src/zui-table.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { ZuiTableBaseElement, TableElementConnectedEvent } from './base.js';
|
|
|
2
2
|
import { html } from 'lit';
|
|
3
3
|
import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
4
4
|
import { style } from './zui-table-css.js';
|
|
5
|
-
import { screenBreakpoints } from '@zywave/zui-base/dist/utils/breakpoints.js';
|
|
6
5
|
import '@zywave/zui-spinner';
|
|
7
6
|
import { updateCustomState } from '@zywave/zui-base/dist/utils/update-custom-state.js';
|
|
8
7
|
import type { ZuiTableRowElement } from './zui-table-row.js';
|
|
@@ -66,14 +65,9 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
66
65
|
@queryAssignedElements({ selector: 'zui-table-row' })
|
|
67
66
|
private _rows: Array<ZuiTableRowElement>;
|
|
68
67
|
|
|
69
|
-
#internals
|
|
70
|
-
#mobileBreakpoint: MediaQueryList = window.matchMedia(`only screen and (max-width: ${screenBreakpoints.xsmall})`);
|
|
68
|
+
#internals: ElementInternals;
|
|
71
69
|
#sortLock = false;
|
|
72
70
|
|
|
73
|
-
#mobileHeadersEvent = (b: MediaQueryListEvent) => {
|
|
74
|
-
b.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
|
|
75
|
-
};
|
|
76
|
-
|
|
77
71
|
static get styles() {
|
|
78
72
|
return [super.styles, style];
|
|
79
73
|
}
|
|
@@ -81,7 +75,8 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
81
75
|
constructor() {
|
|
82
76
|
super();
|
|
83
77
|
|
|
84
|
-
this.#internals = this.attachInternals
|
|
78
|
+
this.#internals = this.attachInternals();
|
|
79
|
+
this.#internals.role = 'table';
|
|
85
80
|
|
|
86
81
|
ZuiTableBaseElement._globalChannel.addEventListener('connected', (event: TableElementConnectedEvent) => {
|
|
87
82
|
if (this.contains(event.detail.element)) {
|
|
@@ -102,14 +97,11 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
102
97
|
connectedCallback() {
|
|
103
98
|
super.connectedCallback();
|
|
104
99
|
this.setAttribute('role', 'table');
|
|
105
|
-
|
|
106
|
-
this.#mobileBreakpoint.addEventListener('change', this.#mobileHeadersEvent);
|
|
107
100
|
}
|
|
108
101
|
|
|
109
|
-
|
|
110
|
-
super.
|
|
111
|
-
|
|
112
|
-
this.#mobileBreakpoint.removeEventListener('change', this.#mobileHeadersEvent);
|
|
102
|
+
firstUpdated(changedProperties: PropertyValues<this>) {
|
|
103
|
+
super.firstUpdated(changedProperties);
|
|
104
|
+
this.#addRowHeadersToCells();
|
|
113
105
|
}
|
|
114
106
|
|
|
115
107
|
updated(changedProperties: PropertyValues<this>) {
|
|
@@ -123,8 +115,6 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
123
115
|
header?.setAttribute('slot', 'header');
|
|
124
116
|
topbar?.setAttribute('slot', 'topbar');
|
|
125
117
|
summary?.setAttribute('slot', 'summary');
|
|
126
|
-
|
|
127
|
-
this.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
|
|
128
118
|
}
|
|
129
119
|
|
|
130
120
|
render() {
|
|
@@ -146,11 +136,11 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
146
136
|
}
|
|
147
137
|
|
|
148
138
|
#onSlotChange() {
|
|
149
|
-
this.#
|
|
139
|
+
this.#addRowHeadersToCells();
|
|
150
140
|
this.requestUpdate();
|
|
151
141
|
}
|
|
152
142
|
|
|
153
|
-
#addRowHeadersToCells() {
|
|
143
|
+
async #addRowHeadersToCells() {
|
|
154
144
|
const headerRow = this.querySelector('zui-table-row[header]');
|
|
155
145
|
|
|
156
146
|
if (headerRow) {
|
|
@@ -158,36 +148,13 @@ export class ZuiTableElement extends ZuiTableBaseElement {
|
|
|
158
148
|
for (const row of rowBodyList) {
|
|
159
149
|
for (let i = 0; i < row.children.length; i++) {
|
|
160
150
|
const cell = row.children[i];
|
|
161
|
-
|
|
162
|
-
const rowHeaderContainer = document.createElement('div');
|
|
163
|
-
rowHeaderContainer.classList.add('header');
|
|
164
|
-
const rowHeaderText = headerRow.children[i].textContent;
|
|
165
|
-
rowHeaderContainer.innerText = rowHeaderText;
|
|
166
|
-
cell.shadowRoot.prepend(rowHeaderContainer);
|
|
167
|
-
}
|
|
151
|
+
(cell as ZuiTableCellWithState)._header = headerRow.children?.[i]?.textContent ?? '';
|
|
168
152
|
}
|
|
169
153
|
}
|
|
170
154
|
}
|
|
171
155
|
|
|
172
156
|
updateCustomState(this.#internals, 'add', 'mobile');
|
|
173
157
|
}
|
|
174
|
-
|
|
175
|
-
#removeRowHeadersFromCells() {
|
|
176
|
-
const rowBodyList = this._rows.filter((r) => !r.hasAttribute('header') && !r.hasAttribute('summary'));
|
|
177
|
-
|
|
178
|
-
for (const row of rowBodyList) {
|
|
179
|
-
for (let i = 0; i < row.children.length; i++) {
|
|
180
|
-
const rowChildren = row.children[i].shadowRoot;
|
|
181
|
-
const header = rowChildren.querySelector('.header');
|
|
182
|
-
if (header) {
|
|
183
|
-
rowChildren.removeChild(header);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// remove custom state --mobile from zui-table
|
|
189
|
-
updateCustomState(this.#internals, 'delete', 'mobile');
|
|
190
|
-
}
|
|
191
158
|
}
|
|
192
159
|
|
|
193
160
|
window.customElements.define('zui-table', ZuiTableElement);
|
|
@@ -199,3 +166,5 @@ declare global {
|
|
|
199
166
|
}
|
|
200
167
|
|
|
201
168
|
export type SortEventDetail = { sort: ZuiTableSortDirection; cell: ZuiTableCellElement };
|
|
169
|
+
|
|
170
|
+
type ZuiTableCellWithState = HTMLElement & { _header: string };
|
package/test/zui-table.test.ts
CHANGED
|
@@ -171,13 +171,13 @@ suite('zui-table', () => {
|
|
|
171
171
|
|
|
172
172
|
const rowHeaderComputedDisplayStyle = window.getComputedStyle(rowHeader).getPropertyValue('display');
|
|
173
173
|
const rowHeaderText = rowHeaderCell.textContent;
|
|
174
|
-
const bodyCellHeaderText = cell.shadowRoot.children[0].textContent;
|
|
174
|
+
const bodyCellHeaderText = cell.shadowRoot.children[0].children[0].textContent;
|
|
175
175
|
|
|
176
176
|
assert.isTrue(isMobile(), `Expected viewport to be <${screenBreakpoints.xsmall}`);
|
|
177
177
|
assert.equal(rowHeaderComputedDisplayStyle, 'none', 'Expected table row header to be hidden on mobile');
|
|
178
178
|
assert.exists(
|
|
179
|
-
cell.shadowRoot.querySelector('.header'),
|
|
180
|
-
'Expected cell to have an element with class .header in its shadow DOM'
|
|
179
|
+
cell.shadowRoot.querySelector('.mobile-header'),
|
|
180
|
+
'Expected cell to have an element with class .mobile-header in its shadow DOM'
|
|
181
181
|
);
|
|
182
182
|
assert.equal(
|
|
183
183
|
rowHeaderText,
|