@kubex/zinc 1.1.139 → 1.1.141

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.139",
3
+ "version": "1.1.141",
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",
@@ -47,6 +47,25 @@ export default class ZnOptGroup extends ZincElement {
47
47
  this.hidden = options.length > 0 && options.every(option => option.hidden);
48
48
  }
49
49
 
50
+ /**
51
+ * @internal - Marks the group as the first visible one so it doesn't draw a separator against the top of the
52
+ * listbox. Structural `:first-child` can't see that earlier siblings were hidden by a search filter.
53
+ */
54
+ updateSeparator() {
55
+ let previous = this.previousElementSibling;
56
+ while (previous && !ZnOptGroup.isRendered(previous)) {
57
+ previous = previous.previousElementSibling;
58
+ }
59
+ this.toggleAttribute('data-first-visible', previous === null);
60
+ }
61
+
62
+ private static isRendered(el: Element): boolean {
63
+ if (el instanceof HTMLSlotElement) {
64
+ return el.assignedElements().some(assigned => ZnOptGroup.isRendered(assigned));
65
+ }
66
+ return !(el instanceof HTMLElement) || !el.hidden;
67
+ }
68
+
50
69
  render() {
51
70
  return html`
52
71
  <div part="base" class="opt-group">
@@ -8,7 +8,7 @@
8
8
  display: none !important;
9
9
  }
10
10
 
11
- :host(:not(:first-child)) {
11
+ :host(:not(:first-child):not([data-first-visible])) {
12
12
  border-block-start: solid var(--zn-panel-border-width) var(--zn-panel-border-color);
13
13
  margin-block-start: var(--zn-spacing-2x-small);
14
14
  }
@@ -845,6 +845,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
845
845
  this.getAllOptGroups().forEach(group => {
846
846
  group.hidden = false;
847
847
  });
848
+ this.updateOptGroupSeparators();
848
849
  this._noResultsVisible = false;
849
850
  return;
850
851
  }
@@ -872,6 +873,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
872
873
 
873
874
  // Update opt-group visibility based on whether any child options are visible
874
875
  this.getAllOptGroups().forEach(group => group.updateVisibility());
876
+ this.updateOptGroupSeparators();
875
877
 
876
878
  // Show empty state when no non-selected options match (selected-but-hidden items are value anchors, not results)
877
879
  this._noResultsVisible = allOptions.filter(o => !o.selected).every(option => option.hidden);
@@ -907,6 +909,12 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
907
909
  this.getAllOptGroups().forEach(group => {
908
910
  group.hidden = false;
909
911
  });
912
+ this.updateOptGroupSeparators();
913
+ }
914
+
915
+ // Runs after every visibility change so group separators reflect which groups are actually showing
916
+ private updateOptGroupSeparators() {
917
+ this.getAllOptGroups().forEach(group => group.updateSeparator());
910
918
  }
911
919
 
912
920
  /**
@@ -1099,6 +1107,8 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
1099
1107
  // Select only the options that match the new value (re-query in case options were materialised)
1100
1108
  this.setSelectedOptions(this.getAllOptions().filter(el => value.includes(el.value)));
1101
1109
 
1110
+ this.updateOptGroupSeparators();
1111
+
1102
1112
  // of check if an option has selected attribute set initially
1103
1113
  if (!this.valueHasChanged) {
1104
1114
  const initiallySelectedOptions = allOptions.filter(el => el.hasAttribute('selected'));
@@ -1330,6 +1340,11 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
1330
1340
  this.formControlController.emitInvalidEvent(event);
1331
1341
  }
1332
1342
 
1343
+ protected updated(_changedProperties: PropertyValues) {
1344
+ super.updated(_changedProperties);
1345
+ this.updateOptGroupSeparators();
1346
+ }
1347
+
1333
1348
  protected firstUpdated(_changedProperties: PropertyValues) {
1334
1349
  super.firstUpdated(_changedProperties);
1335
1350
 
@@ -220,6 +220,16 @@ describe('<zn-select>', () => {
220
220
 
221
221
  expect(visibleValues()).to.deep.equal(['lemon']);
222
222
  });
223
+
224
+ it('drops the separator on the first visible group when earlier groups are filtered out', async () => {
225
+ const groups = el.querySelectorAll('zn-opt-group');
226
+
227
+ await type('berr');
228
+ expect(groups[1].hasAttribute('data-first-visible'), 'Berries group while alone').to.be.true;
229
+
230
+ await type('');
231
+ expect(groups[1].hasAttribute('data-first-visible'), 'Berries group with Citrus restored').to.be.false;
232
+ });
223
233
  });
224
234
 
225
235
  describe('Escape key', () => {