@fluid-topics/ft-filterable-table 0.3.43 → 0.3.46

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.
@@ -22,6 +22,7 @@ export declare class FtFilterableTable<T extends Record<string, any>> extends Ft
22
22
  private renderHeader;
23
23
  private renderColumnSort;
24
24
  private renderColumnFilter;
25
+ private columnPart;
25
26
  private renderCell;
26
27
  private getValue;
27
28
  private getValueAsString;
@@ -49,33 +49,26 @@ export class FtFilterableTable extends FtLitElement {
49
49
  ${repeat(data, (_, rowIndex) => "row-" + rowIndex, (row, rowIndex) => html `
50
50
  <div class="row"
51
51
  @click=${() => this.dispatchEvent(new RowClickEvent(row))}>
52
- ${repeat(this.columns, (_, columnIndex) => "cell-" + rowIndex + " " + columnIndex, (column) => this.renderCell(column, row, rowIndex))}
52
+ ${repeat(this.columns, (_, columnIndex) => "cell-" + columnIndex + "-" + rowIndex, (column, columnIndex) => this.renderCell(column, columnIndex, row, rowIndex))}
53
53
  </div>
54
54
  `)}
55
55
  </div>
56
56
  `;
57
57
  }
58
58
  filterData() {
59
- let data = [...this.data];
60
- this.filters.forEach((filter, columnIndex) => {
59
+ return this.filters.reduce((data, filter, columnIndex) => {
61
60
  var _a;
62
61
  const column = this.columns[columnIndex];
63
- if (filter) {
62
+ if (filter && filter.value) {
64
63
  switch ((_a = column.filter) !== null && _a !== void 0 ? _a : "text") {
65
64
  case "text":
66
- if (filter.value) {
67
- data = data.filter((row) => this.getValueAsString(column, row, columnIndex).toLowerCase().includes(filter.value.toLowerCase()));
68
- }
69
- break;
65
+ return data.filter((row) => this.getValueAsString(column, row, columnIndex).toLowerCase().includes(filter.value.toLowerCase()));
70
66
  case "select":
71
- if (filter.value) {
72
- data = data.filter((row) => this.getValueAsString(column, row, columnIndex) === filter.value);
73
- }
74
- break;
67
+ return data.filter((row) => this.getValueAsString(column, row, columnIndex) === filter.value);
75
68
  }
76
69
  }
77
- });
78
- return data;
70
+ return data;
71
+ }, this.data);
79
72
  }
80
73
  sortData(data) {
81
74
  var _a;
@@ -115,9 +108,13 @@ export class FtFilterableTable extends FtLitElement {
115
108
  "header-cell--sticky": this.stickyHeaders
116
109
  };
117
110
  return html `
118
- <div class="${classMap(classes)}">
111
+ <div class="${classMap(classes)}"
112
+ part="${this.columnPart("header-cell", index)}">
119
113
  <div class="column-title-container">
120
- <span class="column-title">${column.title}</span>
114
+ <span class="column-title"
115
+ part="${this.columnPart("title", index)}">
116
+ ${column.title}
117
+ </span>
121
118
  ${this.renderColumnSort(column, index)}
122
119
  </div>
123
120
  ${this.renderColumnFilter(column, index)}
@@ -156,6 +153,7 @@ export class FtFilterableTable extends FtLitElement {
156
153
  icon="${sortIcon}"
157
154
  label="Sort ${column.title}"
158
155
  @click=${sort}
156
+ part="${this.columnPart("sort-button", index)}"
159
157
  ></ft-button>
160
158
  `;
161
159
  }
@@ -168,18 +166,21 @@ export class FtFilterableTable extends FtLitElement {
168
166
  switch ((_a = column.filter) !== null && _a !== void 0 ? _a : "text") {
169
167
  case "text":
170
168
  return html `
171
- <div class="column-filter">
169
+ <div class="column-filter" part="${this.columnPart("filter-container", index)}">
172
170
  <ft-text-field
173
171
  label="Search ${column.title}"
174
172
  @live-change="${onChange}"
173
+ part="${this.columnPart("filter", index)}"
175
174
  ></ft-text-field>
176
175
  </div>
177
176
  `;
178
177
  case "select":
179
178
  const values = (_b = this.selectData[index]) !== null && _b !== void 0 ? _b : [];
180
179
  return values.length ? html `
181
- <div class="column-filter">
182
- <ft-select label="Filter ${column.title}" @change=${onChange}>
180
+ <div class="column-filter" part="${this.columnPart("filter-container", index)}">
181
+ <ft-select label="Filter ${column.title}"
182
+ @change=${onChange}
183
+ part="${this.columnPart("filter", index)}">
183
184
  <ft-select-option></ft-select-option>
184
185
  ${values.map(v => html `
185
186
  <ft-select-option value="${v}" label="${v}"></ft-select-option>
@@ -192,7 +193,10 @@ export class FtFilterableTable extends FtLitElement {
192
193
  }
193
194
  return nothing;
194
195
  }
195
- renderCell(column, row, rowIndex) {
196
+ columnPart(prefix, index) {
197
+ return `${prefix} ${prefix}-column-${index}`;
198
+ }
199
+ renderCell(column, columnIndex, row, rowIndex) {
196
200
  var _a;
197
201
  const renderer = (_a = column.render) !== null && _a !== void 0 ? _a : DEFAULT_RENDER;
198
202
  const render = (value) => {
@@ -200,7 +204,10 @@ export class FtFilterableTable extends FtLitElement {
200
204
  return typeof rendered === "string" ? unsafeHTML(rendered) : rendered;
201
205
  };
202
206
  return html `
203
- <div class="cell">${render(this.getValue(column, row))}</div>
207
+ <div class="cell"
208
+ part="${this.columnPart("cell", columnIndex)} cell-row-${rowIndex} cell-column-${columnIndex}-row-${rowIndex}">
209
+ ${render(this.getValue(column, row))}
210
+ </div>
204
211
  `;
205
212
  }
206
213
  getValue(column, row) {
@@ -1211,14 +1211,18 @@ const H=Symbol.for(""),W=t=>{if((null==t?void 0:t.r)===H)return null==t?void 0:t
1211
1211
  ${s.repeat(t,((t,e)=>"row-"+e),((t,e)=>i.html`
1212
1212
  <div class="row"
1213
1213
  @click=${()=>this.dispatchEvent(new ii(t))}>
1214
- ${s.repeat(this.columns,((t,i)=>"cell-"+e+" "+i),(i=>this.renderCell(i,t,e)))}
1214
+ ${s.repeat(this.columns,((t,i)=>"cell-"+i+"-"+e),((i,o)=>this.renderCell(i,o,t,e)))}
1215
1215
  </div>
1216
1216
  `))}
1217
1217
  </div>
1218
- `}filterData(){let t=[...this.data];return this.filters.forEach(((e,i)=>{var o;const s=this.columns[i];if(e)switch(null!==(o=s.filter)&&void 0!==o?o:"text"){case"text":e.value&&(t=t.filter((t=>this.getValueAsString(s,t,i).toLowerCase().includes(e.value.toLowerCase()))));break;case"select":e.value&&(t=t.filter((t=>this.getValueAsString(s,t,i)===e.value)))}})),t}sortData(t){var e;if(this.currentSort){const i=this.columns[this.currentSort.column],o=null!==(e=i.comparator)&&void 0!==e?e:ri,s="asc"===this.currentSort.order?o:(t,e)=>-o(t,e);return t.sort(((t,e)=>s(this.getValue(i,t),this.getValue(i,e))))}return t}update(t){super.update(t),t.has("sort")&&(this.currentSort=this.sort),(t.has("data")||t.has("columns"))&&this.updateSelectData()}updateSelectData(){this.selectData=[];const t=this.data,e=this.columns;for(let i in e){const o=e[i];"select"===o.filter&&(this.selectData[i]=[...new Set(t.map(((t,e)=>this.getValueAsString(o,t,e))))].sort(((t,e)=>t.localeCompare(e))))}this.requestUpdate()}renderHeader(t,e){const o={"header-cell":!0,"header-cell--sticky":this.stickyHeaders};return i.html`
1219
- <div class="${l.classMap(o)}">
1218
+ `}filterData(){return this.filters.reduce(((t,e,i)=>{var o;const s=this.columns[i];if(e&&e.value)switch(null!==(o=s.filter)&&void 0!==o?o:"text"){case"text":return t.filter((t=>this.getValueAsString(s,t,i).toLowerCase().includes(e.value.toLowerCase())));case"select":return t.filter((t=>this.getValueAsString(s,t,i)===e.value))}return t}),this.data)}sortData(t){var e;if(this.currentSort){const i=this.columns[this.currentSort.column],o=null!==(e=i.comparator)&&void 0!==e?e:ri,s="asc"===this.currentSort.order?o:(t,e)=>-o(t,e);return t.sort(((t,e)=>s(this.getValue(i,t),this.getValue(i,e))))}return t}update(t){super.update(t),t.has("sort")&&(this.currentSort=this.sort),(t.has("data")||t.has("columns"))&&this.updateSelectData()}updateSelectData(){this.selectData=[];const t=this.data,e=this.columns;for(let i in e){const o=e[i];"select"===o.filter&&(this.selectData[i]=[...new Set(t.map(((t,e)=>this.getValueAsString(o,t,e))))].sort(((t,e)=>t.localeCompare(e))))}this.requestUpdate()}renderHeader(t,e){const o={"header-cell":!0,"header-cell--sticky":this.stickyHeaders};return i.html`
1219
+ <div class="${l.classMap(o)}"
1220
+ part="${this.columnPart("header-cell",e)}">
1220
1221
  <div class="column-title-container">
1221
- <span class="column-title">${t.title}</span>
1222
+ <span class="column-title"
1223
+ part="${this.columnPart("title",e)}">
1224
+ ${t.title}
1225
+ </span>
1222
1226
  ${this.renderColumnSort(t,e)}
1223
1227
  </div>
1224
1228
  ${this.renderColumnFilter(t,e)}
@@ -1231,23 +1235,30 @@ const H=Symbol.for(""),W=t=>{if((null==t?void 0:t.r)===H)return null==t?void 0:t
1231
1235
  icon="${n}"
1232
1236
  label="Sort ${t.title}"
1233
1237
  @click=${()=>{var t;s?"asc"===(null===(t=this.currentSort)||void 0===t?void 0:t.order)?this.currentSort={column:e,order:"desc"}:this.currentSort=void 0:this.currentSort={column:e,order:"asc"}}}
1238
+ part="${this.columnPart("sort-button",e)}"
1234
1239
  ></ft-button>
1235
1240
  `}renderColumnFilter(t,e){var o,s;const n=t=>{this.filters[e]={value:t.detail},this.requestUpdate()};switch(null!==(o=t.filter)&&void 0!==o?o:"text"){case"text":return i.html`
1236
- <div class="column-filter">
1241
+ <div class="column-filter" part="${this.columnPart("filter-container",e)}">
1237
1242
  <ft-text-field
1238
1243
  label="Search ${t.title}"
1239
1244
  @live-change="${n}"
1245
+ part="${this.columnPart("filter",e)}"
1240
1246
  ></ft-text-field>
1241
1247
  </div>
1242
1248
  `;case"select":const o=null!==(s=this.selectData[e])&&void 0!==s?s:[];return o.length?i.html`
1243
- <div class="column-filter">
1244
- <ft-select label="Filter ${t.title}" @change=${n}>
1249
+ <div class="column-filter" part="${this.columnPart("filter-container",e)}">
1250
+ <ft-select label="Filter ${t.title}"
1251
+ @change=${n}
1252
+ part="${this.columnPart("filter",e)}">
1245
1253
  <ft-select-option></ft-select-option>
1246
1254
  ${o.map((t=>i.html`
1247
1255
  <ft-select-option value="${t}" label="${t}"></ft-select-option>
1248
1256
  `))}
1249
1257
  </ft-select>
1250
1258
  </div>
1251
- `:i.nothing}return i.nothing}renderCell(t,e,o){var s;const l=null!==(s=t.render)&&void 0!==s?s:li;return i.html`
1252
- <div class="cell">${(t=>{const e=l(t,o);return"string"==typeof e?n.unsafeHTML(e):e})(this.getValue(t,e))}</div>
1259
+ `:i.nothing}return i.nothing}columnPart(t,e){return`${t} ${t}-column-${e}`}renderCell(t,e,o,s){var l;const r=null!==(l=t.render)&&void 0!==l?l:li;return i.html`
1260
+ <div class="cell"
1261
+ part="${this.columnPart("cell",e)} cell-row-${s} cell-column-${e}-row-${s}">
1262
+ ${(t=>{const e=r(t,s);return"string"==typeof e?n.unsafeHTML(e):e})(this.getValue(t,o))}
1263
+ </div>
1253
1264
  `}getValue(t,e){return"string"==typeof t.getter?e[t.getter]:t.getter(e)}getValueAsString(t,e,i){const o=this.getValue(t,e);return"function"==typeof t.stringify?t.stringify(o,i):(t=>""+t)(o)}}ai.styles=si,ni([o.property({attribute:!1})],ai.prototype,"data",void 0),ni([o.property({attribute:!1})],ai.prototype,"columns",void 0),ni([o.property({attribute:!1})],ai.prototype,"sort",void 0),ni([o.property()],ai.prototype,"stickyHeaders",void 0),ni([o.state()],ai.prototype,"currentSort",void 0),e.customElement("ft-filterable-table")(ai),t.FtFilterableTable=ai,t.FtFilterableTableCssVariables=oi,t.RowClickEvent=ii,t.styles=si,Object.defineProperty(t,"t",{value:!0})}({},ftGlobals.wcUtils,ftGlobals.lit,ftGlobals.litDecorators,ftGlobals.litRepeat,ftGlobals.litUnsafeHTML,ftGlobals.litClassMap);
@@ -1324,14 +1324,18 @@ class Lt extends Mt{constructor(t){if(super(t),this.it=G,t.type!==Rt)throw Error
1324
1324
  ${Tt(t,((t,e)=>"row-"+e),((t,e)=>X`
1325
1325
  <div class="row"
1326
1326
  @click=${()=>this.dispatchEvent(new oo(t))}>
1327
- ${Tt(this.columns,((t,i)=>"cell-"+e+" "+i),(i=>this.renderCell(i,t,e)))}
1327
+ ${Tt(this.columns,((t,i)=>"cell-"+i+"-"+e),((i,o)=>this.renderCell(i,o,t,e)))}
1328
1328
  </div>
1329
1329
  `))}
1330
1330
  </div>
1331
- `}filterData(){let t=[...this.data];return this.filters.forEach(((e,i)=>{var o;const n=this.columns[i];if(e)switch(null!==(o=n.filter)&&void 0!==o?o:"text"){case"text":e.value&&(t=t.filter((t=>this.getValueAsString(n,t,i).toLowerCase().includes(e.value.toLowerCase()))));break;case"select":e.value&&(t=t.filter((t=>this.getValueAsString(n,t,i)===e.value)))}})),t}sortData(t){var e;if(this.currentSort){const i=this.columns[this.currentSort.column],o=null!==(e=i.comparator)&&void 0!==e?e:ao,n="asc"===this.currentSort.order?o:(t,e)=>-o(t,e);return t.sort(((t,e)=>n(this.getValue(i,t),this.getValue(i,e))))}return t}update(t){super.update(t),t.has("sort")&&(this.currentSort=this.sort),(t.has("data")||t.has("columns"))&&this.updateSelectData()}updateSelectData(){this.selectData=[];const t=this.data,e=this.columns;for(let i in e){const o=e[i];"select"===o.filter&&(this.selectData[i]=[...new Set(t.map(((t,e)=>this.getValueAsString(o,t,e))))].sort(((t,e)=>t.localeCompare(e))))}this.requestUpdate()}renderHeader(t,e){const i={"header-cell":!0,"header-cell--sticky":this.stickyHeaders};return X`
1332
- <div class="${_t(i)}">
1331
+ `}filterData(){return this.filters.reduce(((t,e,i)=>{var o;const n=this.columns[i];if(e&&e.value)switch(null!==(o=n.filter)&&void 0!==o?o:"text"){case"text":return t.filter((t=>this.getValueAsString(n,t,i).toLowerCase().includes(e.value.toLowerCase())));case"select":return t.filter((t=>this.getValueAsString(n,t,i)===e.value))}return t}),this.data)}sortData(t){var e;if(this.currentSort){const i=this.columns[this.currentSort.column],o=null!==(e=i.comparator)&&void 0!==e?e:ao,n="asc"===this.currentSort.order?o:(t,e)=>-o(t,e);return t.sort(((t,e)=>n(this.getValue(i,t),this.getValue(i,e))))}return t}update(t){super.update(t),t.has("sort")&&(this.currentSort=this.sort),(t.has("data")||t.has("columns"))&&this.updateSelectData()}updateSelectData(){this.selectData=[];const t=this.data,e=this.columns;for(let i in e){const o=e[i];"select"===o.filter&&(this.selectData[i]=[...new Set(t.map(((t,e)=>this.getValueAsString(o,t,e))))].sort(((t,e)=>t.localeCompare(e))))}this.requestUpdate()}renderHeader(t,e){const i={"header-cell":!0,"header-cell--sticky":this.stickyHeaders};return X`
1332
+ <div class="${_t(i)}"
1333
+ part="${this.columnPart("header-cell",e)}">
1333
1334
  <div class="column-title-container">
1334
- <span class="column-title">${t.title}</span>
1335
+ <span class="column-title"
1336
+ part="${this.columnPart("title",e)}">
1337
+ ${t.title}
1338
+ </span>
1335
1339
  ${this.renderColumnSort(t,e)}
1336
1340
  </div>
1337
1341
  ${this.renderColumnFilter(t,e)}
@@ -1344,23 +1348,30 @@ class Lt extends Mt{constructor(t){if(super(t),this.it=G,t.type!==Rt)throw Error
1344
1348
  icon="${n}"
1345
1349
  label="Sort ${t.title}"
1346
1350
  @click=${()=>{var t;o?"asc"===(null===(t=this.currentSort)||void 0===t?void 0:t.order)?this.currentSort={column:e,order:"desc"}:this.currentSort=void 0:this.currentSort={column:e,order:"asc"}}}
1351
+ part="${this.columnPart("sort-button",e)}"
1347
1352
  ></ft-button>
1348
1353
  `}renderColumnFilter(t,e){var i,o;const n=t=>{this.filters[e]={value:t.detail},this.requestUpdate()};switch(null!==(i=t.filter)&&void 0!==i?i:"text"){case"text":return X`
1349
- <div class="column-filter">
1354
+ <div class="column-filter" part="${this.columnPart("filter-container",e)}">
1350
1355
  <ft-text-field
1351
1356
  label="Search ${t.title}"
1352
1357
  @live-change="${n}"
1358
+ part="${this.columnPart("filter",e)}"
1353
1359
  ></ft-text-field>
1354
1360
  </div>
1355
1361
  `;case"select":const i=null!==(o=this.selectData[e])&&void 0!==o?o:[];return i.length?X`
1356
- <div class="column-filter">
1357
- <ft-select label="Filter ${t.title}" @change=${n}>
1362
+ <div class="column-filter" part="${this.columnPart("filter-container",e)}">
1363
+ <ft-select label="Filter ${t.title}"
1364
+ @change=${n}
1365
+ part="${this.columnPart("filter",e)}">
1358
1366
  <ft-select-option></ft-select-option>
1359
1367
  ${i.map((t=>X`
1360
1368
  <ft-select-option value="${t}" label="${t}"></ft-select-option>
1361
1369
  `))}
1362
1370
  </ft-select>
1363
1371
  </div>
1364
- `:G}return G}renderCell(t,e,i){var o;const n=null!==(o=t.render)&&void 0!==o?o:lo;return X`
1365
- <div class="cell">${(t=>{const e=n(t,i);return"string"==typeof e?Pt(e):e})(this.getValue(t,e))}</div>
1372
+ `:G}return G}columnPart(t,e){return`${t} ${t}-column-${e}`}renderCell(t,e,i,o){var n;const s=null!==(n=t.render)&&void 0!==n?n:lo;return X`
1373
+ <div class="cell"
1374
+ part="${this.columnPart("cell",e)} cell-row-${o} cell-column-${e}-row-${o}">
1375
+ ${(t=>{const e=s(t,o);return"string"==typeof e?Pt(e):e})(this.getValue(t,i))}
1376
+ </div>
1366
1377
  `}getValue(t,e){return"string"==typeof t.getter?e[t.getter]:t.getter(e)}getValueAsString(t,e,i){const o=this.getValue(t,e);return"function"==typeof t.stringify?t.stringify(o,i):(t=>""+t)(o)}}po.styles=so,ro([o({attribute:!1})],po.prototype,"data",void 0),ro([o({attribute:!1})],po.prototype,"columns",void 0),ro([o({attribute:!1})],po.prototype,"sort",void 0),ro([o()],po.prototype,"stickyHeaders",void 0),ro([n()],po.prototype,"currentSort",void 0),d("ft-filterable-table")(po),t.FtFilterableTable=po,t.FtFilterableTableCssVariables=no,t.RowClickEvent=oo,t.styles=so,Object.defineProperty(t,"i",{value:!0})}({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-topics/ft-filterable-table",
3
- "version": "0.3.43",
3
+ "version": "0.3.46",
4
4
  "description": "A dynamic table with filters",
5
5
  "keywords": [
6
6
  "Lit"
@@ -22,11 +22,11 @@
22
22
  "test": "echo \"Error: run tests from root\" && exit 1"
23
23
  },
24
24
  "dependencies": {
25
- "@fluid-topics/ft-button": "0.3.43",
26
- "@fluid-topics/ft-select": "0.3.43",
27
- "@fluid-topics/ft-text-field": "0.3.43",
28
- "@fluid-topics/ft-wc-utils": "0.3.43",
25
+ "@fluid-topics/ft-button": "0.3.46",
26
+ "@fluid-topics/ft-select": "0.3.46",
27
+ "@fluid-topics/ft-text-field": "0.3.46",
28
+ "@fluid-topics/ft-wc-utils": "0.3.46",
29
29
  "lit": "2.2.8"
30
30
  },
31
- "gitHead": "42962910ff06ebfa42e961d1567ee771c517ccb7"
31
+ "gitHead": "de9703e114f8104f705c56d7793f03bfb5faae06"
32
32
  }