@zywave/zui-table 4.4.1-pre.0 → 4.4.1-pre.2

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.
@@ -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 | undefined"
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": "method",
612
- "name": "#removeRowHeadersFromCells",
613
- "privacy": "private"
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{display:flex}@media(min-width: 45em){:host([action]) div{--zui-table-cell-padding: 0.375rem 1.25rem;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem)}@media(min-width: 45em){div{padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}div.header{float:left;width:33.333%;font-weight:600}div.header+div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem 0.3125rem 0)}zui-icon{--zui-icon-size: 1.125rem;vertical-align:middle;margin-left:.625rem;fill:var(--zui-table-cell-sort-color)}.is-selectable{cursor:pointer}`;
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,m/BAAm/B,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{display:flex}@media(min-width: 45em){:host([action]) div{--zui-table-cell-padding: 0.375rem 1.25rem;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem)}@media(min-width: 45em){div{padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}div.header{float:left;width:33.333%;font-weight:600}div.header+div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem 0.3125rem 0)}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"]}
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"]}
@@ -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
  /**
@@ -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 @click="${this.#onSortableClick}" class="${classMap(styles)}">
76
- <slot></slot>
77
- ${this.sortable ? html `<zui-icon icon="zui-sort"></zui-icon>` : nothing}
78
- </div>`;
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":"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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 #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 @click=\"${this.#onSortableClick}\" class=\"${classMap(styles)}\">\n <slot></slot>\n ${this.sortable ? html`<zui-icon icon=\"zui-sort\"></zui-icon>` : nothing}\n </div>`;\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"]}
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"]}
@@ -41,10 +41,11 @@ export class ZuiTableRowElement extends ZuiTableBaseElement {
41
41
  }
42
42
  firstUpdated() {
43
43
  if (this.header) {
44
- const firstCellWithDirection = this._slottedCells?.find((cell) => cell?.hasAttribute('sort'));
44
+ const firstCellWithDirection = this._slottedCells?.find((cell) => cell?.hasAttribute('sort') || cell?.sort !== null);
45
45
  this._slottedCells.forEach((cell) => {
46
- if (cell.sort && cell !== firstCellWithDirection) {
46
+ if ((cell?.hasAttribute('sort') || cell.sort) && cell !== firstCellWithDirection) {
47
47
  cell.sort = null;
48
+ cell.removeAttribute('sort');
48
49
  }
49
50
  });
50
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"zui-table-row.js","sourceRoot":"","sources":["../src/zui-table-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZuiTableBaseElement } from './base.js';\nimport { html } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { style } from './zui-table-row-css.js';\nimport type { ZuiTableCellElement } from './zui-table-cell.js';\n\n/**\n * Insert into `<zui-table>`; `<zui-table-row>` holds a row of `<zui-table-cell>` elements.\n *\n * @element zui-table-row\n *\n * @slot - Default, unnamed slot; for inserting `<zui-table-cell>` elements into `<zui-table-row>`\n *\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-summary-background-color=var(--zui-gray-600)] - Override the table summary background color\n * @cssprop [--zui-table-summary-text-color=#fff] - Override the table summary text color\n */\nexport class ZuiTableRowElement extends ZuiTableBaseElement {\n /**\n * Declare a table header; typically the first row in `<zui-table>`\n */\n @property({ type: Boolean, reflect: true })\n header = false;\n\n /**\n * Declare a table summary row; typically the last row in `<zui-table>` before `<zui-table-footer>`\n */\n @property({ type: Boolean, reflect: true })\n summary = false;\n\n @queryAssignedElements({ selector: 'zui-table-cell' })\n private _slottedCells: Array<ZuiTableCellElement>;\n\n #sortLock?: boolean;\n\n static get styles() {\n return [super.styles, style];\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n }\n\n firstUpdated() {\n if (this.header) {\n const firstCellWithDirection = this._slottedCells?.find((cell) => cell?.hasAttribute('sort'));\n this._slottedCells.forEach((cell) => {\n if (cell.sort && cell !== firstCellWithDirection) {\n cell.sort = null;\n }\n });\n }\n }\n\n updated(changedProperties: Map<string | number | symbol, unknown>) {\n super.updated(changedProperties);\n if (changedProperties.has('header')) {\n this.#ensureCellState();\n if (this.header) {\n this._state?.channel.addEventListener('sort', (e: CustomEvent<{ cell: HTMLElement }>) => this.#onTableSort(e));\n }\n }\n }\n\n render() {\n return html`<div>\n <slot @slotchange=\"${this.#ensureCellState()}\"></slot>\n </div>`;\n }\n\n #onTableSort(event: CustomEvent<{ cell: HTMLElement }>) {\n if (this.#sortLock) {\n return;\n }\n this.#sortLock = true;\n this._slottedCells?.forEach((cell) => {\n if (cell !== event.detail.cell) {\n cell.sort = null;\n }\n });\n setTimeout(() => {\n this.#sortLock = false;\n }, 0);\n }\n\n #ensureCellState() {\n if (!this._slottedCells) {\n return;\n }\n\n /* eslint-disable @typescript-eslint/no-explicit-any */\n\n if (this.header) {\n this._slottedCells.forEach((cell) => {\n cell.setAttribute('role', 'columnheader');\n (cell as any)._isAllowedSort = true;\n });\n } else {\n this._slottedCells.forEach((cell) => {\n cell.setAttribute('role', 'cell');\n (cell as any)._isAllowedSort = false;\n });\n }\n\n /* eslint-enable @typescript-eslint/no-explicit-any */\n }\n}\n\nwindow.customElements.define('zui-table-row', ZuiTableRowElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'zui-table-row': ZuiTableRowElement;\n }\n}\n"]}
1
+ {"version":3,"file":"zui-table-row.js","sourceRoot":"","sources":["../src/zui-table-row.ts"],"names":[],"mappings":"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","sourcesContent":["import { ZuiTableBaseElement } from './base.js';\nimport { html } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { style } from './zui-table-row-css.js';\nimport type { ZuiTableCellElement } from './zui-table-cell.js';\n\n/**\n * Insert into `<zui-table>`; `<zui-table-row>` holds a row of `<zui-table-cell>` elements.\n *\n * @element zui-table-row\n *\n * @slot - Default, unnamed slot; for inserting `<zui-table-cell>` elements into `<zui-table-row>`\n *\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-summary-background-color=var(--zui-gray-600)] - Override the table summary background color\n * @cssprop [--zui-table-summary-text-color=#fff] - Override the table summary text color\n */\nexport class ZuiTableRowElement extends ZuiTableBaseElement {\n /**\n * Declare a table header; typically the first row in `<zui-table>`\n */\n @property({ type: Boolean, reflect: true })\n header = false;\n\n /**\n * Declare a table summary row; typically the last row in `<zui-table>` before `<zui-table-footer>`\n */\n @property({ type: Boolean, reflect: true })\n summary = false;\n\n @queryAssignedElements({ selector: 'zui-table-cell' })\n private _slottedCells: Array<ZuiTableCellElement>;\n\n #sortLock?: boolean;\n\n static get styles() {\n return [super.styles, style];\n }\n\n connectedCallback() {\n super.connectedCallback();\n this.setAttribute('role', 'row');\n }\n\n firstUpdated() {\n if (this.header) {\n const firstCellWithDirection = this._slottedCells?.find(\n (cell) => cell?.hasAttribute('sort') || cell?.sort !== null\n );\n this._slottedCells.forEach((cell) => {\n if ((cell?.hasAttribute('sort') || cell.sort) && cell !== firstCellWithDirection) {\n cell.sort = null;\n cell.removeAttribute('sort');\n }\n });\n }\n }\n\n updated(changedProperties: Map<string | number | symbol, unknown>) {\n super.updated(changedProperties);\n if (changedProperties.has('header')) {\n this.#ensureCellState();\n if (this.header) {\n this._state?.channel.addEventListener('sort', (e: CustomEvent<{ cell: HTMLElement }>) => this.#onTableSort(e));\n }\n }\n }\n\n render() {\n return html`<div>\n <slot @slotchange=\"${this.#ensureCellState()}\"></slot>\n </div>`;\n }\n\n #onTableSort(event: CustomEvent<{ cell: HTMLElement }>) {\n if (this.#sortLock) {\n return;\n }\n this.#sortLock = true;\n this._slottedCells?.forEach((cell) => {\n if (cell !== event.detail.cell) {\n cell.sort = null;\n }\n });\n setTimeout(() => {\n this.#sortLock = false;\n }, 0);\n }\n\n #ensureCellState() {\n if (!this._slottedCells) {\n return;\n }\n\n /* eslint-disable @typescript-eslint/no-explicit-any */\n\n if (this.header) {\n this._slottedCells.forEach((cell) => {\n cell.setAttribute('role', 'columnheader');\n (cell as any)._isAllowedSort = true;\n });\n } else {\n this._slottedCells.forEach((cell) => {\n cell.setAttribute('role', 'cell');\n (cell as any)._isAllowedSort = false;\n });\n }\n\n /* eslint-enable @typescript-eslint/no-explicit-any */\n }\n}\n\nwindow.customElements.define('zui-table-row', ZuiTableRowElement);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'zui-table-row': ZuiTableRowElement;\n }\n}\n"]}
@@ -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
- disconnectedCallback(): void;
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.#mobileHeadersEvent = (b) => {
69
- b.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
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
- disconnectedCallback() {
92
- super.disconnectedCallback();
93
- this.#mobileBreakpoint.removeEventListener('change', this.#mobileHeadersEvent);
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.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
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
- if (!cell.shadowRoot.querySelector('.header')) {
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 })
@@ -1 +1 @@
1
- {"version":3,"file":"zui-table.js","sourceRoot":"","sources":["../src/zui-table.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,mBAAmB,EAA8B,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAC/E,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oDAAoD,CAAC;AAOvF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,eAAgB,SAAQ,mBAAmB;IAiCtD,UAAU,CAAoB;IAC9B,iBAAiB,CAAiG;IAClH,SAAS,CAAS;IAElB,mBAAmB,CAEjB;IAEF,MAAM,KAAK,MAAM;QACf,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;QACE,KAAK,EAAE,CAAC;QA7CV;;WAEG;QAEH,WAAM,GAAG,KAAK,CAAC;QAEf;;;;;WAKG;QAEH,SAAI,GAAiB,SAAS,CAAC;QAE/B,iEAAiE;QAEjE;;WAEG;QAEH,cAAS,GAAG,KAAK,CAAC;QAElB;;WAEG;QAEH,YAAO,GAAG,KAAK,CAAC;QAMhB,sBAAiB,GAAmB,MAAM,CAAC,UAAU,CAAC,+BAA+B,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;QAClH,cAAS,GAAG,KAAK,CAAC;QAElB,wBAAmB,GAAG,CAAC,CAAsB,EAAE,EAAE;YAC/C,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAC/E,CAAC,CAAC;QASA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QAE3C,mBAAmB,CAAC,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,KAAiC,EAAE,EAAE;YACrG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,KAAmC,EAAE,EAAE;YACnF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAkB,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACtG,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAEnC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC9E,CAAC;IAED,oBAAoB;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAE7B,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,CAAC,iBAAuC;QAC7C,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAEjC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,8BAA8B,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,oCAAoC,CAAC,CAAC;QACzE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACvC,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAEzC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;IACpG,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;+CAIgC,IAAI,CAAC,aAAa;;mCAE9B,IAAI,CAAC,aAAa;gBACrC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,qDAAqD,CAAC,CAAC,CAAC,IAAI,CAAA,EAAE;;;;;;;6CAOpD,CAAC;IAC5C,CAAC;IAED,aAAa;QACX,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAClG,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAED,qBAAqB;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC;QAE9D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;YACtG,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;gBAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC9C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBACzD,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBAC3C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;wBACxD,kBAAkB,CAAC,SAAS,GAAG,aAAa,CAAC;wBAC7C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;oBAC9C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;IAED,0BAA0B;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;QAEtG,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC/C,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;gBACpD,IAAI,MAAM,EAAE,CAAC;oBACX,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC;CACF;AAtJC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;+CAC5B;AASf;IADC,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;6CACG;AAQ/B;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;kDAClD;AAMlB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gDAC3B;AAGR;IADP,qBAAqB,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;8CACZ;AA8H3C,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC","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 loading="">
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 loading="">
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 loading="">
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="" loading="">
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.0",
3
+ "version": "4.4.1-pre.2",
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": "3749b9b5bd4d2c0fa1b7e4ed68b695c960f99b4e"
32
+ "gitHead": "cdf7b9622b4f662734912310f3582350ab1afd75"
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{display:flex}@media(min-width: 45em){:host([action]) div{--zui-table-cell-padding: 0.375rem 1.25rem;align-items:center}}:host([action]) ::slotted(zui-button:not(:first-of-type)){margin-left:.625rem}div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem)}@media(min-width: 45em){div{padding:var(--zui-table-cell-padding, 0.8125rem 1.25rem)}}div.header{float:left;width:33.333%;font-weight:600}div.header+div{padding:var(--zui-table-cell-padding, 0.3125rem 0.9375rem 0.3125rem 0)}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
+ 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}`;
@@ -21,11 +21,12 @@
21
21
  }
22
22
 
23
23
  :host([action]) {
24
- div {
25
- display: flex;
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
- div {
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
- &.header {
46
- float: left;
47
- width: 33.333%;
48
- font-weight: 600;
54
+ &:empty {
55
+ display: none;
49
56
 
50
57
  + div {
51
- padding: var(--zui-table-cell-padding, #{rem(5)} #{rem(15)} #{rem(5)} 0);
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 {
@@ -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 @click="${this.#onSortableClick}" class="${classMap(styles)}">
78
- <slot></slot>
79
- ${this.sortable ? html`<zui-icon icon="zui-sort"></zui-icon>` : nothing}
80
- </div>`;
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
  /**
@@ -44,10 +44,13 @@ export class ZuiTableRowElement extends ZuiTableBaseElement {
44
44
 
45
45
  firstUpdated() {
46
46
  if (this.header) {
47
- const firstCellWithDirection = this._slottedCells?.find((cell) => cell?.hasAttribute('sort'));
47
+ const firstCellWithDirection = this._slottedCells?.find(
48
+ (cell) => cell?.hasAttribute('sort') || cell?.sort !== null
49
+ );
48
50
  this._slottedCells.forEach((cell) => {
49
- if (cell.sort && cell !== firstCellWithDirection) {
51
+ if ((cell?.hasAttribute('sort') || cell.sort) && cell !== firstCellWithDirection) {
50
52
  cell.sort = null;
53
+ cell.removeAttribute('sort');
51
54
  }
52
55
  });
53
56
  }
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?: ElementInternals;
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
- disconnectedCallback() {
110
- super.disconnectedCallback();
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.#mobileBreakpoint.matches ? this.#addRowHeadersToCells() : this.#removeRowHeadersFromCells();
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
- if (!cell.shadowRoot.querySelector('.header')) {
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 };
@@ -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,