@kubex/zinc 1.1.128 → 1.1.129

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubex/zinc",
3
- "version": "1.1.128",
3
+ "version": "1.1.129",
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",
@@ -666,6 +666,19 @@ export default class ZnPageBuilder extends ZincElement {
666
666
  this._commit({ sections: this._patchSection(id, s => ({ ...s, columns: next })) });
667
667
  }
668
668
 
669
+ /**
670
+ * Snaps the field back to the width the container will use. A re-render alone
671
+ * would not: once the state already sits at a bound, an out-of-range entry
672
+ * changes nothing to re-render from.
673
+ */
674
+ private _onColumnsEntered(section: PageSection, input: ZnInput) {
675
+ const type = this.registry.get(section.type);
676
+ if (type?.slotsMax === undefined) return;
677
+ const next = slotColumns({...section, columns: Number(input.value)}, type);
678
+ input.value = String(next);
679
+ this.setSectionColumns(section.id, next);
680
+ }
681
+
669
682
  private _removeSection(id: string) {
670
683
  if (this._isPinned(id)) return;
671
684
  const [removed, sections] = this._extract(id);
@@ -1229,9 +1242,9 @@ export default class ZnPageBuilder extends ZincElement {
1229
1242
  label="Slots per row"
1230
1243
  min="${type.slotsMin ?? 1}"
1231
1244
  max="${type.slotsMax}"
1232
- help-text="A new row is added as the last one fills."
1245
+ help-text="Between ${type.slotsMin ?? 1} and ${type.slotsMax}. A new row is added as the last one fills."
1233
1246
  .value="${String(slotColumns(section, type))}"
1234
- @zn-change="${(e: Event) => this.setSectionColumns(section.id, Number((e.target as ZnInput).value))}"></zn-input>`}
1247
+ @zn-change="${(e: Event) => this._onColumnsEntered(section, e.target as ZnInput)}"></zn-input>`}
1235
1248
  ${type?.renderConfig
1236
1249
  ? type.renderConfig(section, data => this._updateSectionData(section.id, data))
1237
1250
  : this._form}
@@ -476,6 +476,38 @@ describe('<zn-page-builder>', () => {
476
476
  .to.have.length(6);
477
477
  });
478
478
 
479
+ it('should snap an out-of-range width back on every entry and state the range', async () => {
480
+ const el = await fixture<ZnPageBuilder>(html`
481
+ <zn-page-builder config='{"sections":[{"id":"row","type":"category-row","data":{}}]}'>
482
+ <template type="category-row" slot="config" label="Category Row" slots="3" slots-max="4"></template>
483
+ </zn-page-builder>`);
484
+ await el.updateComplete;
485
+
486
+ el.shadowRoot?.querySelector('.canvas zn-page-section-card')?.dispatchEvent(new Event('click'));
487
+ await el.updateComplete;
488
+
489
+ const width = el.shadowRoot!.querySelector<HTMLInputElement>('.inspector__slots')!;
490
+ expect(width.getAttribute('help-text'), 'the control names its range').to.contain('1 and 4');
491
+
492
+ const enter = async (value: string) => {
493
+ width.value = value;
494
+ width.dispatchEvent(new Event('zn-change', {bubbles: true}));
495
+ await el.updateComplete;
496
+ };
497
+
498
+ await enter('9');
499
+ expect(el.state.sections[0].columns, 'clamped to the max').to.equal(4);
500
+ expect(width.value, 'and shown clamped').to.equal('4');
501
+
502
+ await enter('9');
503
+ expect(width.value, 'a second over-max entry snaps back too').to.equal('4');
504
+ expect(el.state.sections[0].columns).to.equal(4);
505
+
506
+ await enter('0');
507
+ expect(el.state.sections[0].columns, 'clamped to the min').to.equal(1);
508
+ expect(width.value).to.equal('1');
509
+ });
510
+
479
511
  it('should clamp a container width to the declared bounds', async () => {
480
512
  const el = await fixture<ZnPageBuilder>(html`
481
513
  <zn-page-builder config='{"sections":[{"id":"row","type":"category-row","data":{},"columns":99}]}'>
@@ -64,7 +64,8 @@ export const MAX_SLOTS = 24;
64
64
  export function slotColumns(section: PageSection, type: PageSectionType): number {
65
65
  const columns = type.slots ?? 0;
66
66
  if (type.slotsMax === undefined) return columns;
67
- return Math.min(Math.max(section.columns ?? columns, type.slotsMin ?? 1), type.slotsMax);
67
+ const chosen = Math.round(Number(section.columns ?? NaN));
68
+ return Math.min(Math.max(Number.isFinite(chosen) ? chosen : columns, type.slotsMin ?? 1), type.slotsMax);
68
69
  }
69
70
 
70
71
  /**