@kubex/zinc 1.1.129 → 1.1.130

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.
@@ -9189,6 +9189,15 @@
9189
9189
  "kind": "field",
9190
9190
  "name": "searchChangeListener"
9191
9191
  },
9192
+ {
9193
+ "kind": "field",
9194
+ "name": "isNarrowed",
9195
+ "type": {
9196
+ "text": "boolean"
9197
+ },
9198
+ "privacy": "private",
9199
+ "readonly": true
9200
+ },
9192
9201
  {
9193
9202
  "kind": "method",
9194
9203
  "name": "emptyState"
@@ -52701,7 +52710,7 @@
52701
52710
  "package": {
52702
52711
  "name": "@kubex/zinc",
52703
52712
  "description": "A collection of web components for building web applications based off of @shoelace-style/Shoelace",
52704
- "version": "1.1.129",
52713
+ "version": "1.1.130",
52705
52714
  "author": "",
52706
52715
  "license": "MIT"
52707
52716
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
3
3
  "name": "@kubex/zinc",
4
- "version": "1.1.129",
4
+ "version": "1.1.130",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
package/dist/zn.d.ts CHANGED
@@ -4177,6 +4177,7 @@ declare module "components/data-table/data-table.component" {
4177
4177
  filterClearListener: (e: Event) => void;
4178
4178
  filterChangeListener: (e: ZnFilterChangeEvent) => void;
4179
4179
  searchChangeListener: (e: ZnSearchChangeEvent) => void;
4180
+ private get isNarrowed();
4180
4181
  emptyState(): TemplateResult<1>;
4181
4182
  renderTable(data: Response): TemplateResult<1>;
4182
4183
  private renderErrorAlert;
package/dist/zn.min.js CHANGED
@@ -1227,23 +1227,21 @@ import{a as Fn,b as h3,c as _r,d as c,e as V}from"./chunks/zn.UBLZO6CI.js";var K
1227
1227
  ${t}
1228
1228
  ${this.getTableFooter()}`}
1229
1229
  </div>
1230
- `}connectedCallback(){super.connectedCallback(),this.addEventListener("zn-filter-change",this.filterChangeListener),this.addEventListener("zn-clear",this.filterClearListener),this.addEventListener("zn-search-change",this.searchChangeListener)}updated(t){super.updated(t),this.publishFilterSuggestions()}publishFilterSuggestions(){let t=this.querySelector("zn-data-table-filter");if(!t||this._rows.length===0)return;let r={};this._rows.forEach(a=>a.cells.forEach(s=>{let l=s.text?.trim();if(!l)return;let p=r[s.column]??(r[s.column]=[]);p.length<C4&&!p.includes(l)&&p.push(l)}));let n=JSON.stringify(r);n!==this._suggestionsKey&&(this._suggestionsKey=n,t.suggestions=r)}getTemplate(t){return this.displayTemplates[t]??this._formatTemplates[t]}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("zn-filter-change",this.filterChangeListener),this.removeEventListener("zn-clear",this.filterClearListener),this.removeEventListener("zn-search-change",this.searchChangeListener)}emptyState(){return this.noInitialLoad&&!this._initialLoad?this.hasSlotController.test("no-results")?u`
1231
- <div class="table--empty">
1232
- <slot name="no-results"></slot>
1233
- </div>`:u`
1230
+ `}connectedCallback(){super.connectedCallback(),this.addEventListener("zn-filter-change",this.filterChangeListener),this.addEventListener("zn-clear",this.filterClearListener),this.addEventListener("zn-search-change",this.searchChangeListener)}updated(t){super.updated(t),this.publishFilterSuggestions()}publishFilterSuggestions(){let t=this.querySelector("zn-data-table-filter");if(!t||this._rows.length===0)return;let r={};this._rows.forEach(a=>a.cells.forEach(s=>{let l=s.text?.trim();if(!l)return;let p=r[s.column]??(r[s.column]=[]);p.length<C4&&!p.includes(l)&&p.push(l)}));let n=JSON.stringify(r);n!==this._suggestionsKey&&(this._suggestionsKey=n,t.suggestions=r)}getTemplate(t){return this.displayTemplates[t]??this._formatTemplates[t]}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("zn-filter-change",this.filterChangeListener),this.removeEventListener("zn-clear",this.filterClearListener),this.removeEventListener("zn-search-change",this.searchChangeListener)}get isNarrowed(){return this.search.length>0||this.filter.length>0}emptyState(){return this.isNarrowed||this.noInitialLoad&&!this._initialLoad?u`
1234
1231
  <div class="table--empty">
1235
- <zn-empty-state caption="No Results Found" icon="search">
1236
- <p>Nothing matched your search. Try adjusting your filters.</p>
1237
- </zn-empty-state>
1238
- </div>`:this.hasSlotController.test("empty-state")?u`
1239
- <div class="table--empty">
1240
- <slot name="empty-state"></slot>
1232
+ <slot name="no-results">
1233
+ <zn-empty-state caption="No Results Found" icon="search">
1234
+ <p>Nothing matched your search. Try adjusting your filters.</p>
1235
+ </zn-empty-state>
1236
+ </slot>
1241
1237
  </div>`:u`
1242
1238
  <div class="table--empty">
1243
- <zn-empty-state
1244
- caption="${this.emptyStateCaption?this.emptyStateCaption:this.caption?"No "+this.caption.toLowerCase()+" found":"No data found"}"
1245
- icon="${this.emptyStateIcon}">
1246
- </zn-empty-state>
1239
+ <slot name="empty-state">
1240
+ <zn-empty-state
1241
+ caption="${this.emptyStateCaption?this.emptyStateCaption:this.caption?"No "+this.caption.toLowerCase()+" found":"No data found"}"
1242
+ icon="${this.emptyStateIcon}">
1243
+ </zn-empty-state>
1244
+ </slot>
1247
1245
  </div>`}renderTable(t){this.itemsPerPage=Math.max(rm,t.perPage??rm),this.page=Math.max(1,t.page??T0),this._totalRows=Math.max(0,t.total??0),this.totalPages=Math.ceil(Math.max(1,t.total)/this.itemsPerPage);let r=t?.error?.text?t.error:void 0;if(!t?.rows||t.rows.length===0)return u`${r?u`
1248
1246
  <div class="table__error">${this.renderErrorAlert(r)}</div>`:B}${this.emptyState()}`;if(this._rows=this.getRows(t),this.groupBy){let n={},a=this.groups.split(",").map(h=>h.trim()).filter(h=>h.length>0),s=a.includes("*"),l=new Set(a.filter(h=>h!=="*").map(h=>this.humanize(h)));l.forEach(h=>{n[h]||(n[h]=[])}),s&&(n["*"]=[]),this._rows.forEach(h=>{let m=h.cells.find(g=>g.column===this.groupBy),f=m?m.text:"Ungrouped",b=this.humanize(f);if(l.has(b)){n[b].push(h);return}if(s){n["*"].push(h);return}(!this.groups||b==="Ungrouped")&&(n[b]||(n[b]=[]),n[b].push(h))}),Object.keys(n).forEach(h=>{n[h].length===0&&delete n[h]});let p=Object.keys(n).map(h=>({label:h==="Ungrouped"||h==="*"?"":h,rows:n[h]}));return this.renderTableData(p,r)}return this.renderTableData([{label:"",rows:this._rows}],r)}renderErrorAlert(t){return u`
1249
1247
  <zn-alert level="${t.level??"error"}"
@@ -1439,7 +1437,7 @@ import{a as Fn,b as h3,c as _r,d as c,e as V}from"./chunks/zn.UBLZO6CI.js";var K
1439
1437
  <zn-hover-container placement="${l}" flip>
1440
1438
  ${s}
1441
1439
  <div slot="content">
1442
- ${St(t.hoverContent)}
1440
+ ${St(t.hoverContent)}
1443
1441
  </div>
1444
1442
  </zn-hover-container>`}return t.copyable&&(s=u`
1445
1443
  ${s}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubex/zinc",
3
- "version": "1.1.129",
3
+ "version": "1.1.130",
4
4
  "description": "A collection of web components for building web applications based off of @shoelace-style/Shoelace",
5
5
  "keywords": [
6
6
  "web components",
@@ -641,36 +641,32 @@ export default class ZnDataTable extends ZincElement {
641
641
  }
642
642
  }
643
643
 
644
- emptyState() {
645
- if (this.noInitialLoad && !this._initialLoad) {
646
- if (this.hasSlotController.test('no-results')) {
647
- return html`
648
- <div class="table--empty">
649
- <slot name="no-results"></slot>
650
- </div>`;
651
- }
652
-
653
- return html`
654
- <div class="table--empty">
655
- <zn-empty-state caption="No Results Found" icon="search">
656
- <p>Nothing matched your search. Try adjusting your filters.</p>
657
- </zn-empty-state>
658
- </div>`;
659
- }
644
+ // A table narrowed by a search or filter has rows, just none matching them, so
645
+ // its empty state must not claim there is nothing to create
646
+ private get isNarrowed(): boolean {
647
+ return this.search.length > 0 || this.filter.length > 0;
648
+ }
660
649
 
661
- if (this.hasSlotController.test('empty-state')) {
650
+ emptyState() {
651
+ if (this.isNarrowed || (this.noInitialLoad && !this._initialLoad)) {
662
652
  return html`
663
653
  <div class="table--empty">
664
- <slot name="empty-state"></slot>
654
+ <slot name="no-results">
655
+ <zn-empty-state caption="No Results Found" icon="search">
656
+ <p>Nothing matched your search. Try adjusting your filters.</p>
657
+ </zn-empty-state>
658
+ </slot>
665
659
  </div>`;
666
660
  }
667
661
 
668
662
  return html`
669
663
  <div class="table--empty">
670
- <zn-empty-state
671
- caption="${this.emptyStateCaption ? this.emptyStateCaption : (this.caption ? "No " + this.caption.toLowerCase() + " found" : "No data found")}"
672
- icon="${this.emptyStateIcon}">
673
- </zn-empty-state>
664
+ <slot name="empty-state">
665
+ <zn-empty-state
666
+ caption="${this.emptyStateCaption ? this.emptyStateCaption : (this.caption ? "No " + this.caption.toLowerCase() + " found" : "No data found")}"
667
+ icon="${this.emptyStateIcon}">
668
+ </zn-empty-state>
669
+ </slot>
674
670
  </div>`;
675
671
  }
676
672
 
@@ -1323,9 +1319,9 @@ export default class ZnDataTable extends ZincElement {
1323
1319
  size="${ifDefined(size)}"
1324
1320
  color="${ifDefined(color)}"
1325
1321
  ${ref(el => {
1326
- if (!el) return;
1327
- tokens.forEach(t => el.setAttribute(t, ''));
1328
- })}
1322
+ if (!el) return;
1323
+ tokens.forEach(t => el.setAttribute(t, ''));
1324
+ })}
1329
1325
  title="${ifDefined(data.title)}"
1330
1326
  ></zn-icon> ${content}`;
1331
1327
  }
@@ -1345,7 +1341,7 @@ export default class ZnDataTable extends ZincElement {
1345
1341
  <zn-hover-container placement="${placement}" flip>
1346
1342
  ${content}
1347
1343
  <div slot="content">
1348
- ${unsafeHTML(data.hoverContent)}
1344
+ ${unsafeHTML(data.hoverContent)}
1349
1345
  </div>
1350
1346
  </zn-hover-container>`;
1351
1347
  }
@@ -230,6 +230,52 @@ describe('<zn-data-table>', () => {
230
230
  }
231
231
  });
232
232
 
233
+ it('shows a no-results state when a filter empties a normally loading table', async () => {
234
+ const originalFetch = window.fetch;
235
+ window.fetch = () => Promise.resolve(new Response(JSON.stringify({rows: [], page: 1, perPage: 10, total: 0}),
236
+ {status: 200, headers: {'Content-Type': 'application/json'}}));
237
+
238
+ try {
239
+ const el = await fixture<ZnDataTable>(html`
240
+ <zn-data-table data-uri="/test-data" headers='{"name": {"key": "name", "label": "Name"}}'>
241
+ <div slot="empty-state" id="nothing-created">Nothing created yet</div>
242
+ <div slot="no-results" id="nothing-matched">Nothing matched</div>
243
+ </zn-data-table>`);
244
+
245
+ await waitUntil(() => el.shadowRoot?.querySelector('slot[name="empty-state"]'));
246
+ expect(el.shadowRoot!.querySelector('slot[name="empty-state"]')).to.exist;
247
+
248
+ el.filter = 'eyJrZXkiOiJ0eXBlIn0=';
249
+ el.refresh();
250
+ await waitUntil(() => el.shadowRoot?.querySelector('slot[name="no-results"]'));
251
+
252
+ expect(el.shadowRoot!.querySelector('slot[name="no-results"]')).to.exist;
253
+ expect(el.shadowRoot!.querySelector('slot[name="empty-state"]')).to.not.exist;
254
+ } finally {
255
+ window.fetch = originalFetch;
256
+ }
257
+ });
258
+
259
+ it('shows a no-results state when a search empties a normally loading table', async () => {
260
+ const originalFetch = window.fetch;
261
+ window.fetch = () => Promise.resolve(new Response(JSON.stringify({rows: [], page: 1, perPage: 10, total: 0}),
262
+ {status: 200, headers: {'Content-Type': 'application/json'}}));
263
+
264
+ try {
265
+ const el = await fixture<ZnDataTable>(html`
266
+ <zn-data-table data-uri="/test-data" search="nothing" headers='{"name": {"key": "name", "label": "Name"}}'>
267
+ <div slot="empty-state">Nothing created yet</div>
268
+ </zn-data-table>`);
269
+
270
+ await waitUntil(() => el.shadowRoot?.querySelector('zn-empty-state'));
271
+
272
+ expect(el.shadowRoot!.querySelector('slot[name="empty-state"]')).to.not.exist;
273
+ expect(el.shadowRoot!.querySelector('zn-empty-state')!.getAttribute('caption')).to.equal('No Results Found');
274
+ } finally {
275
+ window.fetch = originalFetch;
276
+ }
277
+ });
278
+
233
279
  it('exposes displayTemplates as an object property', async () => {
234
280
  const el = await fixture<ZnDataTable>(html` <zn-data-table></zn-data-table> `);
235
281
  const templates = (el as unknown as {displayTemplates: Record<string, unknown>}).displayTemplates;