@justeattakeaway/pie-data-table 0.0.0-snapshot-release-20250818110841 → 0.0.0-snapshot-release-20250910151748

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.
@@ -16,9 +16,9 @@
16
16
  "kind": "variable",
17
17
  "name": "defaultProps",
18
18
  "type": {
19
- "text": "ComponentDefaultProps<DataTableProps, keyof Omit<DataTableProps, 'columns' | 'data'>>"
19
+ "text": "ComponentDefaultProps<DataTableProps, keyof Omit<DataTableProps, 'columns' | 'data' >>"
20
20
  },
21
- "default": "{\n hasBorder: true,\n isStriped: false,\n}"
21
+ "default": "{\n additionalRows: [],\n}"
22
22
  }
23
23
  ],
24
24
  "exports": [
@@ -61,6 +61,43 @@
61
61
  "default": "[]",
62
62
  "description": "Array of data objects to display"
63
63
  },
64
+ {
65
+ "kind": "field",
66
+ "name": "additionalRows",
67
+ "type": {
68
+ "text": "DataTableAdditionalRow[] | undefined"
69
+ },
70
+ "privacy": "public",
71
+ "description": "Arbitrary additional rows to display at the bottom of the table"
72
+ },
73
+ {
74
+ "kind": "method",
75
+ "name": "mapTextAlignClasses",
76
+ "privacy": "private",
77
+ "parameters": [
78
+ {
79
+ "name": "prefix",
80
+ "type": {
81
+ "text": "string"
82
+ },
83
+ "description": "The prefix for the CSS class"
84
+ },
85
+ {
86
+ "name": "textAlign",
87
+ "optional": true,
88
+ "type": {
89
+ "text": "string"
90
+ },
91
+ "description": "The text alignment value"
92
+ }
93
+ ],
94
+ "description": "Maps text alignment values to corresponding CSS classes",
95
+ "return": {
96
+ "type": {
97
+ "text": ""
98
+ }
99
+ }
100
+ },
64
101
  {
65
102
  "kind": "method",
66
103
  "name": "renderHeaderCell",
@@ -109,6 +146,51 @@
109
146
  "name": "renderTableRows",
110
147
  "privacy": "private",
111
148
  "description": "Renders the table rows"
149
+ },
150
+ {
151
+ "kind": "method",
152
+ "name": "renderAdditionalRows",
153
+ "privacy": "private",
154
+ "description": "Renders the additional rows for the table"
155
+ },
156
+ {
157
+ "kind": "method",
158
+ "name": "isHTMLString",
159
+ "privacy": "private",
160
+ "return": {
161
+ "type": {
162
+ "text": "boolean"
163
+ }
164
+ },
165
+ "parameters": [
166
+ {
167
+ "name": "str",
168
+ "type": {
169
+ "text": "string"
170
+ }
171
+ }
172
+ ],
173
+ "description": "Util method that checks if a string contains HTML tags"
174
+ },
175
+ {
176
+ "kind": "method",
177
+ "name": "renderCellContent",
178
+ "privacy": "private",
179
+ "return": {
180
+ "type": {
181
+ "text": "unknown"
182
+ }
183
+ },
184
+ "parameters": [
185
+ {
186
+ "name": "value",
187
+ "type": {
188
+ "text": "unknown"
189
+ },
190
+ "description": "The content to render in the cell"
191
+ }
192
+ ],
193
+ "description": "Renders the content of a table cell, handling different types of content"
112
194
  }
113
195
  ],
114
196
  "mixins": [
package/dist/defs.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
2
+ type TextAlign = 'left' | 'right' | 'center';
2
3
  export interface Column {
3
4
  /**
4
5
  * Unique identifier for the column
@@ -11,7 +12,7 @@ export interface Column {
11
12
  /**
12
13
  * Optional property to specify the text alignment of the column
13
14
  * */
14
- textAlign?: 'left' | 'right' | 'center';
15
+ textAlign?: TextAlign;
15
16
  /**
16
17
  * Optional property to specify the width of the column
17
18
  * */
@@ -21,6 +22,16 @@ export interface Column {
21
22
  * */
22
23
  accessor?: string;
23
24
  }
25
+ export type AdditionalCell = {
26
+ content: string | number;
27
+ textAlign?: TextAlign;
28
+ colSpan?: number;
29
+ hideCell?: boolean;
30
+ };
31
+ export type DataTableAdditionalRow = {
32
+ cells: AdditionalCell[];
33
+ hideRow?: boolean;
34
+ };
24
35
  export interface DataTableProps {
25
36
  /**
26
37
  * Array of column definitions
@@ -30,6 +41,11 @@ export interface DataTableProps {
30
41
  * Array of data objects to display
31
42
  */
32
43
  data: Record<string, unknown>[];
44
+ /**
45
+ * Arbitrary additional rows to display at the bottom of the table
46
+ */
47
+ additionalRows?: DataTableAdditionalRow[];
33
48
  }
34
49
  export declare const defaultProps: ComponentDefaultProps<DataTableProps, keyof Omit<DataTableProps, 'columns' | 'data'>>;
50
+ export {};
35
51
  //# sourceMappingURL=defs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../src/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,MAAM,WAAW,MAAM;IACrB;;SAEK;IACL,EAAE,EAAE,MAAM,CAAC;IACX;;SAEK;IACL,OAAO,EAAE,MAAM,CAAC;IAChB;;SAEK;IACL,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAExC;;SAEK;IACL,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;SAEK;IACL,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACjC;AAED,eAAO,MAAM,YAAY,EAAE,qBAAqB,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,MAAM,CAAC,CAG9G,CAAC"}
1
+ {"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../src/defs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5E,KAAK,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE7C,MAAM,WAAW,MAAM;IACrB;;SAEK;IACL,EAAE,EAAE,MAAM,CAAC;IACX;;SAEK;IACL,OAAO,EAAE,MAAM,CAAC;IAChB;;SAEK;IACL,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;SAEK;IACL,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;SAEK;IACL,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAEhC;;OAEG;IACH,cAAc,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC3C;AAED,eAAO,MAAM,YAAY,EAAE,qBAAqB,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,MAAM,CAAE,CAE/G,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PieElement } from '@justeattakeaway/pie-webc-core/src/internals/PieElement';
2
- import { DataTableProps, Column } from './defs';
2
+ import { DataTableProps, Column, DataTableAdditionalRow } from './defs';
3
3
  export * from './defs';
4
4
  declare const componentSelector = "pie-data-table";
5
5
  declare const PieDataTable_base: import('@justeattakeaway/pie-webc-core').GenericConstructor<import('@justeattakeaway/pie-webc-core').RTLInterface> & typeof PieElement;
@@ -15,6 +15,18 @@ export declare class PieDataTable extends PieDataTable_base implements DataTable
15
15
  * Array of data objects to display
16
16
  */
17
17
  data: Record<string, unknown>[];
18
+ /**
19
+ * Arbitrary additional rows to display at the bottom of the table
20
+ */
21
+ additionalRows?: DataTableAdditionalRow[];
22
+ /**
23
+ * Maps text alignment values to corresponding CSS classes
24
+ *
25
+ * @param prefix - The prefix for the CSS class
26
+ * @param textAlign - The text alignment value
27
+ * @returns An object with CSS classes as keys and boolean values indicating whether the class should be applied
28
+ */
29
+ private mapTextAlignClasses;
18
30
  /**
19
31
  * Renders a header cell for the table
20
32
  * @param column - The column definition to render
@@ -34,6 +46,20 @@ export declare class PieDataTable extends PieDataTable_base implements DataTable
34
46
  * Renders the table rows
35
47
  */
36
48
  private renderTableRows;
49
+ /**
50
+ * Renders the additional rows for the table
51
+ */
52
+ private renderAdditionalRows;
53
+ /**
54
+ * Util method that checks if a string contains HTML tags
55
+ */
56
+ private isHTMLString;
57
+ /**
58
+ * Renders the content of a table cell, handling different types of content
59
+ *
60
+ * @param value - The content to render in the cell
61
+ */
62
+ private renderCellContent;
37
63
  render(): import('lit-html').TemplateResult<1>;
38
64
  static styles: import('lit').CSSResult;
39
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAKrF,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,MAAM,EACd,MAAM,QAAQ,CAAC;AAGhB,cAAc,QAAQ,CAAC;AAEvB,QAAA,MAAM,iBAAiB,mBAAmB,CAAC;;AAE3C;;GAEG;AACH,qBACa,YAAa,SAAQ,iBAAqB,YAAW,cAAc;IAC5E;;OAEG;IAEI,OAAO,EAAE,MAAM,EAAE,CAAM;IAE9B;;OAEG;IAEI,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAE5C;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAiBxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAevB;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB,MAAM;IAiBN,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,YAAY,CAAC;KACrC;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAKrF,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,sBAAsB,EAE9B,MAAM,QAAQ,CAAC;AAGhB,cAAc,QAAQ,CAAC;AAEvB,QAAA,MAAM,iBAAiB,mBAAmB,CAAC;;AAE3C;;GAEG;AACH,qBACa,YAAa,SAAQ,iBAAqB,YAAW,cAAc;IAC5E;;OAEG;IAEI,OAAO,EAAE,MAAM,EAAE,CAAM;IAE9B;;OAEG;IAEI,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAM;IAE5C;;OAEG;IAEI,cAAc,CAAC,EAAE,sBAAsB,EAAE,CAA+B;IAE/E;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAQ3B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmC5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAoBzB,MAAM;IAkBN,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,YAAY,CAAC;KACrC;CACJ"}
package/dist/index.js CHANGED
@@ -1,35 +1,47 @@
1
- import { nothing as n, html as d, unsafeCSS as g } from "lit";
1
+ import { nothing as i, html as l, unsafeCSS as p } from "lit";
2
+ import { unsafeHTML as g } from "lit/directives/unsafe-html.js";
2
3
  import { property as h } from "lit/decorators.js";
3
- import { P as p } from "./PieElement-Y2VnHR4y.js";
4
- import { RtlMixin as u, safeCustomElement as f } from "@justeattakeaway/pie-webc-core";
5
- import { classMap as i } from "lit/directives/class-map.js";
6
- const x = "*,*:after,*:before{box-sizing:inherit}:host{display:block}.c-data-table{--data-table-background-color: var(--dt-color-container-default);--data-table-background-hover-or-active: var(--dt-color-container-subtle);--data-table-border-color: var(--dt-color-border-default);--data-table-border-radius: var(--dt-radius-rounded-c);--data-table-text-color: var(--dt-color-content-default);background-color:var(--data-table-background-color);border:1px solid var(--data-table-border-color);border-radius:var(--data-table-border-radius);color:var(--data-table-text-color);width:100%;overflow:hidden}.c-data-table table{border-spacing:0;width:100%}.c-data-table tbody{overflow:auto}.c-data-table tbody tr:hover{background-color:var(--data-table-background-hover-or-active)}.c-data-table-header{background-color:transparent;font-weight:var(--dt-font-weight-bold);color:var(--data-table-header-color);text-align:left;padding:var(--dt-spacing-d);border-bottom:1px solid var(--data-table-border-color)}.c-data-table-header-text-align--left{text-align:left}.c-data-table-header-text-align--right{text-align:right}.c-data-table-header-text-align--center{text-align:center}.c-data-table-cell{padding:var(--dt-spacing-d);border-bottom:1px solid var(--data-table-border-color)}.c-data-table-cell-text-align--left{text-align:left}.c-data-table-cell-text-align--right{text-align:right}.c-data-table-cell-text-align--center{text-align:center}", T = {
7
- hasBorder: !0,
8
- isStriped: !1
4
+ import { P as u } from "./PieElement-Y2VnHR4y.js";
5
+ import { RtlMixin as f, safeCustomElement as m } from "@justeattakeaway/pie-webc-core";
6
+ import { classMap as n } from "lit/directives/class-map.js";
7
+ const w = "*,*:after,*:before{box-sizing:inherit}:host{display:block}.c-data-table{--data-table-background-color: var(--dt-color-container-default);--data-table-background-hover-or-active: var(--dt-color-container-subtle);--data-table-border-color: var(--dt-color-border-default);--data-table-border-radius: var(--dt-radius-rounded-c);--data-table-text-color: var(--dt-color-content-default);background-color:var(--data-table-background-color);border:1px solid var(--data-table-border-color);border-radius:var(--data-table-border-radius);color:var(--data-table-text-color);width:100%;overflow:hidden}.c-data-table table{border-spacing:0;width:100%}.c-data-table tbody{overflow:auto}.c-data-table tbody tr:hover{background-color:var(--data-table-background-hover-or-active)}.c-data-table-header{background-color:transparent;font-weight:var(--dt-font-weight-bold);color:var(--data-table-header-color);text-align:left;padding:var(--dt-spacing-d);border-bottom:1px solid var(--data-table-border-color)}.c-data-table-header-text-align--left,.c-data-table-cell-text-align--left{text-align:left}.c-data-table-header-text-align--right,.c-data-table-cell-text-align--right{text-align:right}.c-data-table-header-text-align--center,.c-data-table-cell-text-align--center{text-align:center}.c-data-table-cell{padding:var(--dt-spacing-d);border-bottom:1px solid var(--data-table-border-color)}.c-data-table-cell--hidden,.c-data-table-row--hidden{display:none}", x = {
8
+ additionalRows: []
9
9
  };
10
- var v = Object.defineProperty, m = Object.getOwnPropertyDescriptor, b = (t, e, l, r) => {
11
- for (var a = r > 1 ? void 0 : r ? m(e, l) : e, c = t.length - 1, s; c >= 0; c--)
12
- (s = t[c]) && (a = (r ? s(e, l, a) : s(a)) || a);
13
- return r && a && v(e, l, a), a;
10
+ var y = Object.defineProperty, $ = Object.getOwnPropertyDescriptor, c = (t, e, a, o) => {
11
+ for (var r = o > 1 ? void 0 : o ? $(e, a) : e, s = t.length - 1, b; s >= 0; s--)
12
+ (b = t[s]) && (r = (o ? b(e, a, r) : b(r)) || r);
13
+ return o && r && y(e, a, r), r;
14
14
  };
15
- let o = class extends u(p) {
15
+ let d = class extends f(u) {
16
16
  constructor() {
17
- super(...arguments), this.columns = [], this.data = [];
17
+ super(...arguments), this.columns = [], this.data = [], this.additionalRows = x.additionalRows;
18
+ }
19
+ /**
20
+ * Maps text alignment values to corresponding CSS classes
21
+ *
22
+ * @param prefix - The prefix for the CSS class
23
+ * @param textAlign - The text alignment value
24
+ * @returns An object with CSS classes as keys and boolean values indicating whether the class should be applied
25
+ */
26
+ mapTextAlignClasses(t, e) {
27
+ return {
28
+ [`${t}-text-align--left`]: e === "left",
29
+ [`${t}-text-align--right`]: e === "right",
30
+ [`${t}-text-align--center`]: e === "center"
31
+ };
18
32
  }
19
33
  /**
20
34
  * Renders a header cell for the table
21
35
  * @param column - The column definition to render
22
36
  */
23
37
  renderHeaderCell(t) {
24
- const { width: e, heading: l, textAlign: r } = t, a = e ? `width: ${e}` : n;
25
- return d`
26
- <th style="${a}" class="${i({
38
+ const { width: e, heading: a, textAlign: o } = t, r = e ? `width: ${e}` : i, s = {
27
39
  "c-data-table-header": !0,
28
- "c-data-table-header-text-align--left": r === "left",
29
- "c-data-table-header-text-align--right": r === "right",
30
- "c-data-table-header-text-align--center": r === "center"
31
- })}">
32
- ${l}
40
+ ...this.mapTextAlignClasses("c-data-table-header", o)
41
+ };
42
+ return l`
43
+ <th style="${r}" class="${n(s)}">
44
+ ${a}
33
45
  </th>
34
46
  `;
35
47
  }
@@ -37,7 +49,7 @@ let o = class extends u(p) {
37
49
  * Renders the table header
38
50
  */
39
51
  renderTableHeader() {
40
- return d`
52
+ return l`
41
53
  <thead>
42
54
  <tr>
43
55
  ${this.columns.map((t) => this.renderHeaderCell(t))}
@@ -51,15 +63,13 @@ let o = class extends u(p) {
51
63
  * @param row - The data object for the current row
52
64
  */
53
65
  renderTableCell(t, e) {
54
- const l = {
66
+ const a = {
55
67
  "c-data-table-cell": !0,
56
- "c-data-table-cell-text-align--left": t.textAlign === "left",
57
- "c-data-table-cell-text-align--right": t.textAlign === "right",
58
- "c-data-table-cell-text-align--center": t.textAlign === "center"
68
+ ...this.mapTextAlignClasses("c-data-table-cell", t.textAlign)
59
69
  };
60
- return d`
61
- <td class="${i(l)}">
62
- ${t.accessor ? e[t.accessor] : ""}
70
+ return l`
71
+ <td class="${n(a)}">
72
+ ${t.accessor ? this.renderCellContent(e[t.accessor]) : ""}
63
73
  </td>
64
74
  `;
65
75
  }
@@ -67,9 +77,9 @@ let o = class extends u(p) {
67
77
  * Renders the table rows
68
78
  */
69
79
  renderTableRows() {
70
- return d`
80
+ return l`
71
81
  <tbody>
72
- ${this.data.map((t) => d`
82
+ ${this.data.map((t) => l`
73
83
  <tr class="c-data-table-row">
74
84
  ${this.columns.map((e) => this.renderTableCell(e, t))}
75
85
  </tr>
@@ -77,31 +87,83 @@ let o = class extends u(p) {
77
87
  </tbody>
78
88
  `;
79
89
  }
90
+ /**
91
+ * Renders the additional rows for the table
92
+ */
93
+ renderAdditionalRows() {
94
+ return l`
95
+ <tfoot>
96
+ ${this.additionalRows && this.additionalRows.length > 0 && this.additionalRows.map((t) => {
97
+ const e = {
98
+ "c-data-table-row": !0,
99
+ "c-data-table-row--hidden": !!t.hideRow
100
+ };
101
+ return l`
102
+ <tr class="${n(e)}">
103
+ ${t.cells.map((a) => {
104
+ const o = {
105
+ "c-data-table-cell": !0,
106
+ "c-data-table-cell--hidden": !!a.hideCell,
107
+ ...this.mapTextAlignClasses("c-data-table-cell", a.textAlign)
108
+ };
109
+ return l`
110
+ <td
111
+ class="${n(o)}"
112
+ colspan=${a.colSpan || 1}
113
+ >
114
+ ${a.content}
115
+ </td>
116
+ `;
117
+ })}
118
+ </tr>
119
+ `;
120
+ })}
121
+ </tfoot>
122
+ `;
123
+ }
124
+ /**
125
+ * Util method that checks if a string contains HTML tags
126
+ */
127
+ isHTMLString(t) {
128
+ return /<[a-z][\s\S]*>/i.test(t.trim());
129
+ }
130
+ /**
131
+ * Renders the content of a table cell, handling different types of content
132
+ *
133
+ * @param value - The content to render in the cell
134
+ */
135
+ renderCellContent(t) {
136
+ return t == null ? "" : t instanceof HTMLElement || t && typeof t == "object" ? t : typeof t == "function" ? this.renderCellContent(t()) : typeof t == "string" && this.isHTMLString(t) ? g(t) : String(t);
137
+ }
80
138
  render() {
81
- return d`
82
- <div class="${i({
139
+ return l`
140
+ <div class="${n({
83
141
  "c-data-table": !0
84
142
  })}">
85
143
  <slot name="table-header"></slot>
86
144
  <table>
87
- ${this.columns.length > 0 ? this.renderTableHeader() : n}
88
- ${this.data.length > 0 ? this.renderTableRows() : n}
145
+ ${this.columns.length > 0 ? this.renderTableHeader() : i}
146
+ ${this.data.length > 0 ? this.renderTableRows() : i}
147
+ ${this.additionalRows && this.additionalRows.length > 0 ? this.renderAdditionalRows() : i}
89
148
  </table>
90
149
  </div>
91
150
  `;
92
151
  }
93
152
  };
94
- o.styles = g(x);
95
- b([
153
+ d.styles = p(w);
154
+ c([
155
+ h({ type: Array })
156
+ ], d.prototype, "columns", 2);
157
+ c([
96
158
  h({ type: Array })
97
- ], o.prototype, "columns", 2);
98
- b([
159
+ ], d.prototype, "data", 2);
160
+ c([
99
161
  h({ type: Array })
100
- ], o.prototype, "data", 2);
101
- o = b([
102
- f("pie-data-table")
103
- ], o);
162
+ ], d.prototype, "additionalRows", 2);
163
+ d = c([
164
+ m("pie-data-table")
165
+ ], d);
104
166
  export {
105
- o as PieDataTable,
106
- T as defaultProps
167
+ d as PieDataTable,
168
+ x as defaultProps
107
169
  };
@@ -25,6 +25,10 @@ export declare class PieDataTableHeader extends PieElement implements DataTableH
25
25
  * @param event - The slot change event
26
26
  */
27
27
  private handleSlotChange;
28
+ /**
29
+ * Lit lifecycle: called after the component's DOM has been rendered the first time.
30
+ */
31
+ firstUpdated(): void;
28
32
  render(): import('lit-html').TemplateResult<1>;
29
33
  static styles: import('lit').CSSResult;
30
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pie-data-table-header/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAKrF,OAAO,EACH,KAAK,oBAAoB,EAEzB,YAAY,EACf,MAAM,QAAQ,CAAC;AAGhB,cAAc,QAAQ,CAAC;AAEvB,QAAA,MAAM,iBAAiB,0BAA0B,CAAC;AAElD;;GAEG;AACH,qBACa,kBAAmB,SAAQ,UAAW,YAAW,oBAAoB;IAC9E;;OAEG;IAEI,KAAK,EAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE7C;;OAEG;IAEI,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAElD;;OAEG;IAGI,OAAO,CAAC,EAAE,OAAO,YAAY,CAAC,OAAO,CAAC;IAG7C,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAKxB,MAAM;IA0BN,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;KAC3C;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pie-data-table-header/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yDAAyD,CAAC;AAKrF,OAAO,EACH,KAAK,oBAAoB,EAEzB,YAAY,EACf,MAAM,QAAQ,CAAC;AAGhB,cAAc,QAAQ,CAAC;AAEvB,QAAA,MAAM,iBAAiB,0BAA0B,CAAC;AAElD;;GAEG;AACH,qBACa,kBAAmB,SAAQ,UAAW,YAAW,oBAAoB;IAC9E;;OAEG;IAEI,KAAK,EAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAE7C;;OAEG;IAEI,QAAQ,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAElD;;OAEG;IAGI,OAAO,CAAC,EAAE,OAAO,YAAY,CAAC,OAAO,CAAC;IAG7C,OAAO,CAAC,gBAAgB,CAAS;IAEjC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,YAAY;IAQZ,MAAM;IA2BN,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;KAC3C;CACJ"}
@@ -6,13 +6,13 @@ import { classMap as v } from "lit/directives/class-map.js";
6
6
  const m = "*,*:after,*:before{box-sizing:inherit}:host{display:block}.c-data-table-header{--data-table-header-background: transparent;padding:var(--dt-spacing-d);background-color:var(--data-table-header-background);border-bottom:1px solid var(--data-table-border-color);display:flex;justify-content:space-between;align-items:flex-end}.c-data-table-header-title-wrapper{display:flex;flex-direction:column;gap:var(--dt-spacing-b)}.c-data-table-header-title{font-weight:var(--dt-font-weight-extrabold);font-size:calc(var(--dt-font-size-24) * 1px);line-height:calc(var(--dt-font-size-24-line-height) * 1px)}.c-data-table-header-subtitle{font-weight:var(--dt-font-weight-regular);font-size:calc(var(--dt-font-size-16) * 1px);line-height:calc(var(--dt-font-size-16-line-height) * 1px)}.c-data-table-header--strong{--data-table-header-background: var(--dt-color-support-brand-02)}.c-data-table-action-buttons-wrapper{display:flex;gap:var(--dt-spacing-d)}", y = ["subtle", "strong"], x = {
7
7
  variant: "subtle"
8
8
  };
9
- var w = Object.defineProperty, P = Object.getOwnPropertyDescriptor, l = (e, t, s, o) => {
10
- for (var a = o > 1 ? void 0 : o ? P(t, s) : t, i = e.length - 1, d; i >= 0; i--)
11
- (d = e[i]) && (a = (o ? d(t, s, a) : d(a)) || a);
12
- return o && a && w(t, s, a), a;
9
+ var w = Object.defineProperty, S = Object.getOwnPropertyDescriptor, l = (e, t, r, o) => {
10
+ for (var a = o > 1 ? void 0 : o ? S(t, r) : t, i = e.length - 1, d; i >= 0; i--)
11
+ (d = e[i]) && (a = (o ? d(t, r, a) : d(a)) || a);
12
+ return o && a && w(t, r, a), a;
13
13
  };
14
- const S = "pie-data-table-header";
15
- let r = class extends g {
14
+ const P = "pie-data-table-header";
15
+ let s = class extends g {
16
16
  constructor() {
17
17
  super(...arguments), this.hasActionButtons = !1;
18
18
  }
@@ -25,15 +25,24 @@ let r = class extends g {
25
25
  const t = e.target;
26
26
  this.hasActionButtons = t.assignedElements().length > 0;
27
27
  }
28
+ /**
29
+ * Lit lifecycle: called after the component's DOM has been rendered the first time.
30
+ */
31
+ firstUpdated() {
32
+ var t;
33
+ const e = (t = this.shadowRoot) == null ? void 0 : t.querySelector('slot[name="action-button"]');
34
+ e && (this.hasActionButtons = e.assignedElements().length > 0);
35
+ }
28
36
  render() {
29
- const { title: e, subtitle: t, variant: s } = this;
37
+ const { title: e, subtitle: t, variant: r } = this;
30
38
  return n`
31
39
  <header class="${v({
32
40
  "c-data-table-header": !0,
33
- "c-data-table-header--strong": s === "strong"
41
+ "c-data-table-header--strong": r === "strong"
34
42
  })}">
35
43
  <div class="c-data-table-header-title-wrapper">
36
- ${e ? n`<span class="c-data-table-header-title">${e}</span>` : p}
44
+ ${e ? n`<span class="c-data-table-header-title">${e}</span>` : p}
45
+
37
46
  ${t ? n`<span class="c-data-table-header-subtitle">${t}</span>` : p}
38
47
  </div>
39
48
  ${this.hasActionButtons ? n`
@@ -47,25 +56,25 @@ let r = class extends g {
47
56
  `;
48
57
  }
49
58
  };
50
- r.styles = h(m);
59
+ s.styles = h(m);
51
60
  l([
52
61
  c({ type: String })
53
- ], r.prototype, "title", 2);
62
+ ], s.prototype, "title", 2);
54
63
  l([
55
64
  c({ type: String })
56
- ], r.prototype, "subtitle", 2);
65
+ ], s.prototype, "subtitle", 2);
57
66
  l([
58
67
  c({ type: String }),
59
- u(S, y, x.variant)
60
- ], r.prototype, "variant", 2);
68
+ u(P, y, x.variant)
69
+ ], s.prototype, "variant", 2);
61
70
  l([
62
71
  b()
63
- ], r.prototype, "hasActionButtons", 2);
64
- r = l([
72
+ ], s.prototype, "hasActionButtons", 2);
73
+ s = l([
65
74
  f("pie-data-table-header")
66
- ], r);
75
+ ], s);
67
76
  export {
68
- r as PieDataTableHeader,
77
+ s as PieDataTableHeader,
69
78
  y as dataTableHeaderVariant,
70
79
  x as defaultProps
71
80
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-data-table",
3
3
  "description": "PIE Design System Data Table built using Web Components",
4
- "version": "0.0.0-snapshot-release-20250818110841",
4
+ "version": "0.0.0-snapshot-release-20250910151748",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@custom-elements-manifest/analyzer": "0.9.0",
36
36
  "@justeattakeaway/pie-components-config": "0.21.0",
37
- "@justeattakeaway/pie-css": "0.19.0",
37
+ "@justeattakeaway/pie-css": "0.21.0",
38
38
  "@justeattakeaway/pie-monorepo-utils": "0.7.0",
39
39
  "cem-plugin-module-file-extensions": "0.0.5"
40
40
  },
@@ -42,15 +42,18 @@
42
42
  border-bottom: 1px solid var(--data-table-border-color);
43
43
  }
44
44
 
45
- .c-data-table-header-text-align--left {
45
+ .c-data-table-header-text-align--left,
46
+ .c-data-table-cell-text-align--left {
46
47
  text-align: left;
47
48
  }
48
49
 
49
- .c-data-table-header-text-align--right {
50
+ .c-data-table-header-text-align--right,
51
+ .c-data-table-cell-text-align--right {
50
52
  text-align: right;
51
53
  }
52
54
 
53
- .c-data-table-header-text-align--center {
55
+ .c-data-table-header-text-align--center,
56
+ .c-data-table-cell-text-align--center {
54
57
  text-align: center;
55
58
  }
56
59
 
@@ -59,14 +62,7 @@
59
62
  border-bottom: 1px solid var(--data-table-border-color);
60
63
  }
61
64
 
62
- .c-data-table-cell-text-align--left {
63
- text-align: left;
64
- }
65
-
66
- .c-data-table-cell-text-align--right {
67
- text-align: right;
68
- }
69
-
70
- .c-data-table-cell-text-align--center {
71
- text-align: center;
65
+ .c-data-table-cell--hidden,
66
+ .c-data-table-row--hidden {
67
+ display: none;
72
68
  }
package/src/defs.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { type ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';
2
2
 
3
+ type TextAlign = 'left' | 'right' | 'center';
4
+
3
5
  export interface Column {
4
6
  /**
5
7
  * Unique identifier for the column
@@ -12,7 +14,7 @@ export interface Column {
12
14
  /**
13
15
  * Optional property to specify the text alignment of the column
14
16
  * */
15
- textAlign?: 'left' | 'right' | 'center';
17
+ textAlign?: TextAlign;
16
18
 
17
19
  /**
18
20
  * Optional property to specify the width of the column
@@ -24,6 +26,18 @@ export interface Column {
24
26
  accessor?: string;
25
27
  }
26
28
 
29
+ export type AdditionalCell = {
30
+ content: string | number;
31
+ textAlign?: TextAlign;
32
+ colSpan?: number;
33
+ hideCell?: boolean;
34
+ };
35
+
36
+ export type DataTableAdditionalRow = {
37
+ cells: AdditionalCell[];
38
+ hideRow?: boolean;
39
+ };
40
+
27
41
  export interface DataTableProps {
28
42
  /**
29
43
  * Array of column definitions
@@ -34,9 +48,13 @@ export interface DataTableProps {
34
48
  * Array of data objects to display
35
49
  */
36
50
  data: Record<string, unknown>[];
51
+
52
+ /**
53
+ * Arbitrary additional rows to display at the bottom of the table
54
+ */
55
+ additionalRows?: DataTableAdditionalRow[];
37
56
  }
38
57
 
39
- export const defaultProps: ComponentDefaultProps<DataTableProps, keyof Omit<DataTableProps, 'columns' | 'data'>> = {
40
- hasBorder: true,
41
- isStriped: false,
58
+ export const defaultProps: ComponentDefaultProps<DataTableProps, keyof Omit<DataTableProps, 'columns' | 'data' >> = {
59
+ additionalRows: [],
42
60
  };
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { html, nothing, unsafeCSS } from 'lit';
2
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
2
3
  import { property } from 'lit/decorators.js';
3
4
  import { PieElement } from '@justeattakeaway/pie-webc-core/src/internals/PieElement';
4
5
  import { RtlMixin, safeCustomElement } from '@justeattakeaway/pie-webc-core';
@@ -8,6 +9,8 @@ import styles from './data-table.scss?inline';
8
9
  import {
9
10
  type DataTableProps,
10
11
  type Column,
12
+ type DataTableAdditionalRow,
13
+ defaultProps,
11
14
  } from './defs';
12
15
 
13
16
  // Valid values available to consumers
@@ -32,6 +35,27 @@ export class PieDataTable extends RtlMixin(PieElement) implements DataTableProps
32
35
  @property({ type: Array })
33
36
  public data: Record<string, unknown>[] = [];
34
37
 
38
+ /**
39
+ * Arbitrary additional rows to display at the bottom of the table
40
+ */
41
+ @property({ type: Array })
42
+ public additionalRows?: DataTableAdditionalRow[] = defaultProps.additionalRows;
43
+
44
+ /**
45
+ * Maps text alignment values to corresponding CSS classes
46
+ *
47
+ * @param prefix - The prefix for the CSS class
48
+ * @param textAlign - The text alignment value
49
+ * @returns An object with CSS classes as keys and boolean values indicating whether the class should be applied
50
+ */
51
+ private mapTextAlignClasses (prefix: string, textAlign?: string) {
52
+ return {
53
+ [`${prefix}-text-align--left`]: textAlign === 'left',
54
+ [`${prefix}-text-align--right`]: textAlign === 'right',
55
+ [`${prefix}-text-align--center`]: textAlign === 'center',
56
+ };
57
+ }
58
+
35
59
  /**
36
60
  * Renders a header cell for the table
37
61
  * @param column - The column definition to render
@@ -41,9 +65,7 @@ export class PieDataTable extends RtlMixin(PieElement) implements DataTableProps
41
65
  const style = width ? `width: ${width}` : nothing;
42
66
  const classes = {
43
67
  'c-data-table-header': true,
44
- 'c-data-table-header-text-align--left': textAlign === 'left',
45
- 'c-data-table-header-text-align--right': textAlign === 'right',
46
- 'c-data-table-header-text-align--center': textAlign === 'center',
68
+ ...this.mapTextAlignClasses('c-data-table-header', textAlign),
47
69
  };
48
70
 
49
71
  return html`
@@ -74,14 +96,12 @@ export class PieDataTable extends RtlMixin(PieElement) implements DataTableProps
74
96
  private renderTableCell (column: Column, row: Record<string, unknown>) {
75
97
  const classes = {
76
98
  'c-data-table-cell': true,
77
- 'c-data-table-cell-text-align--left': column.textAlign === 'left',
78
- 'c-data-table-cell-text-align--right': column.textAlign === 'right',
79
- 'c-data-table-cell-text-align--center': column.textAlign === 'center',
99
+ ...this.mapTextAlignClasses('c-data-table-cell', column.textAlign),
80
100
  };
81
101
 
82
102
  return html`
83
103
  <td class="${classMap(classes)}">
84
- ${column.accessor ? row[column.accessor] : ''}
104
+ ${column.accessor ? this.renderCellContent(row[column.accessor]) : ''}
85
105
  </td>
86
106
  `;
87
107
  }
@@ -101,6 +121,76 @@ export class PieDataTable extends RtlMixin(PieElement) implements DataTableProps
101
121
  `;
102
122
  }
103
123
 
124
+ /**
125
+ * Renders the additional rows for the table
126
+ */
127
+ private renderAdditionalRows () {
128
+ /* eslint-disable indent */
129
+ return html`
130
+ <tfoot>
131
+ ${this.additionalRows && this.additionalRows.length > 0 && this.additionalRows.map((row) => {
132
+ const rowClasses = {
133
+ 'c-data-table-row': true,
134
+ 'c-data-table-row--hidden': !!row.hideRow,
135
+ };
136
+ return html`
137
+ <tr class="${classMap(rowClasses)}">
138
+ ${row.cells.map((cell) => {
139
+ const cellClasses = {
140
+ 'c-data-table-cell': true,
141
+ 'c-data-table-cell--hidden': !!cell.hideCell,
142
+ ...this.mapTextAlignClasses('c-data-table-cell', cell.textAlign),
143
+ };
144
+
145
+ return html`
146
+ <td
147
+ class="${classMap(cellClasses)}"
148
+ colspan=${cell.colSpan || 1}
149
+ >
150
+ ${cell.content}
151
+ </td>
152
+ `;
153
+ })}
154
+ </tr>
155
+ `;
156
+ })}
157
+ </tfoot>
158
+ `;
159
+ /* eslint-enable indent */
160
+ }
161
+
162
+ /**
163
+ * Util method that checks if a string contains HTML tags
164
+ */
165
+ private isHTMLString (str: string): boolean {
166
+ return /<[a-z][\s\S]*>/i.test(str.trim());
167
+ }
168
+
169
+ /**
170
+ * Renders the content of a table cell, handling different types of content
171
+ *
172
+ * @param value - The content to render in the cell
173
+ */
174
+ private renderCellContent (value: unknown): unknown {
175
+ if (value == null) {
176
+ return '';
177
+ }
178
+
179
+ if ((value instanceof HTMLElement) || (value && typeof value === 'object')) {
180
+ return value;
181
+ }
182
+
183
+ if (typeof value === 'function') {
184
+ return this.renderCellContent(value());
185
+ }
186
+
187
+ if (typeof value === 'string' && this.isHTMLString(value)) {
188
+ return unsafeHTML(value);
189
+ }
190
+
191
+ return String(value);
192
+ }
193
+
104
194
  render () {
105
195
  const classes = {
106
196
  'c-data-table': true,
@@ -112,6 +202,7 @@ export class PieDataTable extends RtlMixin(PieElement) implements DataTableProps
112
202
  <table>
113
203
  ${this.columns.length > 0 ? this.renderTableHeader() : nothing}
114
204
  ${this.data.length > 0 ? this.renderTableRows() : nothing}
205
+ ${this.additionalRows && this.additionalRows.length > 0 ? this.renderAdditionalRows() : nothing}
115
206
  </table>
116
207
  </div>
117
208
  `;
@@ -53,6 +53,17 @@ export class PieDataTableHeader extends PieElement implements DataTableHeaderPro
53
53
  this.hasActionButtons = slot.assignedElements().length > 0;
54
54
  }
55
55
 
56
+ /**
57
+ * Lit lifecycle: called after the component's DOM has been rendered the first time.
58
+ */
59
+ firstUpdated () {
60
+ // Get the named slot element after shadowRoot is ready
61
+ const slot = this.shadowRoot?.querySelector('slot[name="action-button"]') as HTMLSlotElement | null;
62
+ if (slot) {
63
+ this.hasActionButtons = slot.assignedElements().length > 0;
64
+ }
65
+ }
66
+
56
67
  render () {
57
68
  const { title, subtitle, variant } = this;
58
69
 
@@ -64,7 +75,8 @@ export class PieDataTableHeader extends PieElement implements DataTableHeaderPro
64
75
  return html`
65
76
  <header class="${classMap(classes)}">
66
77
  <div class="c-data-table-header-title-wrapper">
67
- ${title ? html`<span class="c-data-table-header-title">${title}</span>` : nothing}
78
+ ${title ? html`<span class="c-data-table-header-title">${title}</span>` : nothing}
79
+
68
80
  ${subtitle ? html`<span class="c-data-table-header-subtitle">${subtitle}</span>` : nothing}
69
81
  </div>
70
82
  ${this.hasActionButtons ? html`