@kubex/zinc 1.0.113 → 1.0.114

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.
Files changed (95) hide show
  1. package/.github/workflows/eleventy_build.yml +5 -5
  2. package/.github/workflows/js_build_and_deploy.yaml +1 -1
  3. package/dist/custom-elements.json +2636 -421
  4. package/dist/vscode.html-custom-data.json +96 -16
  5. package/dist/web-types.json +268 -31
  6. package/dist/zn.d.ts +517 -340
  7. package/dist/zn.min.css +1 -1
  8. package/dist/zn.min.js +942 -863
  9. package/docs/eleventy.config.cjs +4 -2
  10. package/docs/pages/components/header.md +13 -0
  11. package/docs/pages/components/inline-edit.md +20 -0
  12. package/docs/pages/components/item.md +12 -1
  13. package/docs/pages/components/page.md +149 -0
  14. package/docs/pages/components/progress-bar.md +16 -0
  15. package/docs/pages/components/select.md +25 -0
  16. package/docs/pages/components/split-pane.md +6 -7
  17. package/docs/pages/components/tabs.md +59 -9
  18. package/package.json +8 -5
  19. package/scripts/build.js +40 -19
  20. package/scss/_global-spacing.scss +12 -1
  21. package/scss/_root.scss +34 -2
  22. package/scss/shared/layout.scss +15 -2
  23. package/scss/themes/_light.scss +1 -1
  24. package/src/components/absolute-container/absolute-container.component.ts +9 -25
  25. package/src/components/animated-button/animated-button.test.ts +8 -8
  26. package/src/components/button/button.component.ts +3 -1
  27. package/src/components/button/button.scss +5 -0
  28. package/src/components/button-menu/button-menu.component.ts +36 -21
  29. package/src/components/button-menu/button-menu.test.ts +55 -1
  30. package/src/components/chart/chart.component.ts +7 -7
  31. package/src/components/collapsible/collapsible.component.ts +7 -14
  32. package/src/components/cols/cols.scss +1 -1
  33. package/src/components/content-block/content-block.component.ts +11 -33
  34. package/src/components/data-select/data-select.component.ts +7 -11
  35. package/src/components/data-table/data-table.component.ts +10 -14
  36. package/src/components/editor/modules/toolbar/toolbar.component.ts +5 -9
  37. package/src/components/expanding-action/expanding-action.component.ts +37 -43
  38. package/src/components/form-group/form-group.component.ts +8 -3
  39. package/src/components/header/header.component.ts +6 -5
  40. package/src/components/header/header.scss +31 -25
  41. package/src/components/inline-edit/inline-edit.component.ts +13 -1
  42. package/src/components/inline-edit/inline-edit.test.ts +50 -0
  43. package/src/components/input/input.test.ts +77 -0
  44. package/src/components/input-group/input-group.test.ts +2 -10
  45. package/src/components/item/item.component.ts +12 -6
  46. package/src/components/item/item.scss +1 -1
  47. package/src/components/item/item.test.ts +8 -0
  48. package/src/components/navbar/navbar.component.ts +222 -48
  49. package/src/components/navbar/navbar.scss +134 -21
  50. package/src/components/navbar/navbar.test.ts +114 -9
  51. package/src/components/option/option.scss +5 -7
  52. package/src/components/option/option.test.ts +30 -0
  53. package/src/components/page/index.ts +13 -0
  54. package/src/components/page/page.component.ts +406 -0
  55. package/src/components/page/page.scss +325 -0
  56. package/src/components/page/page.test.ts +397 -0
  57. package/src/components/page-nav/page-nav.scss +7 -5
  58. package/src/components/pane/pane.component.ts +2 -2
  59. package/src/components/pane/pane.scss +0 -1
  60. package/src/components/pane/pane.test.ts +31 -0
  61. package/src/components/panel/panel.scss +1 -0
  62. package/src/components/progress-bar/progress-bar.component.ts +5 -2
  63. package/src/components/progress-bar/progress-bar.scss +17 -1
  64. package/src/components/progress-bar/progress-bar.test.ts +12 -0
  65. package/src/components/scroll-container/scroll-container.component.ts +22 -21
  66. package/src/components/select/select.component.ts +240 -38
  67. package/src/components/select/select.scss +15 -0
  68. package/src/components/select/select.test.ts +477 -0
  69. package/src/components/settings-container/settings-container.component.ts +15 -19
  70. package/src/components/settings-container/settings-container.scss +8 -8
  71. package/src/components/sidebar/sidebar.component.ts +11 -11
  72. package/src/components/simple-chart/simple-chart.component.ts +6 -7
  73. package/src/components/sp/sp.scss +46 -15
  74. package/src/components/sp/sp.test.ts +15 -0
  75. package/src/components/split-pane/split-pane.component.ts +153 -26
  76. package/src/components/split-pane/split-pane.scss +89 -13
  77. package/src/components/split-pane/split-pane.test.ts +187 -0
  78. package/src/components/style/style.component.ts +8 -0
  79. package/src/components/tab/index.ts +13 -0
  80. package/src/components/tab/tab.component.ts +25 -0
  81. package/src/components/tab/tab.scss +7 -0
  82. package/src/components/table/table.component.ts +7 -2
  83. package/src/components/tabs/tabs.component.ts +75 -70
  84. package/src/components/tabs/tabs.scss +1 -1
  85. package/src/components/textarea/textarea.component.ts +5 -8
  86. package/src/components/translation-group/translation-group.component.ts +15 -14
  87. package/src/components/translations/translations.component.ts +18 -17
  88. package/src/components/translations/translations.scss +1 -0
  89. package/src/components/translations/translations.test.ts +3 -2
  90. package/src/internal/form.ts +234 -0
  91. package/src/internal/theme.ts +26 -46
  92. package/src/internal/zinc-element.ts +12 -7
  93. package/src/utilities/form.ts +1 -0
  94. package/src/wc.scss +1 -1
  95. package/src/zinc.ts +3 -0
@@ -2,6 +2,58 @@
2
2
 
3
3
  :host {
4
4
  display: block;
5
+ --navbar-active-colour: var(--zn-active-nav-background, var(--zn-page-content-background, var(--zn-page-surface-background, var(--zn-body))));
6
+
7
+ ul.navbar {
8
+ padding: 0;
9
+ margin: 0 calc(var(--zn-base-gap) + var(--zn-gutter));
10
+ }
11
+ }
12
+
13
+ :host([hover]) {
14
+ position: absolute;
15
+ transform: translateY(-100%);
16
+
17
+ ul.navbar {
18
+ background-color: rgb(var(--zn-body));
19
+
20
+ li {
21
+ z-index: 2;
22
+ }
23
+
24
+ position: relative;
25
+
26
+ &::after {
27
+ z-index: 1;
28
+ content: "";
29
+ position: absolute;
30
+ inset: 0;
31
+ background-color: rgb(var(--zn-body));
32
+ }
33
+
34
+ &::before {
35
+ z-index: 1;
36
+ content: "";
37
+ position: absolute;
38
+ top: -2px;
39
+ right: -2px;
40
+ left: -2px;
41
+ bottom: 0;
42
+ border-radius: 3px;
43
+ backdrop-filter: blur(2px) opacity(0.8);
44
+ }
45
+ }
46
+ }
47
+
48
+ :host([icon-only]) {
49
+ ul.navbar {
50
+ li {
51
+ padding: var(--zn-spacing-small);
52
+ width: fit-content;
53
+ max-width: 50px;
54
+ justify-content: center;
55
+ }
56
+ }
5
57
  }
6
58
 
7
59
  .navbar__container {
@@ -13,7 +65,11 @@
13
65
 
14
66
  .navbar {
15
67
  margin: 0;
16
- padding-left: var(--zn-spacing-medium);
68
+ }
69
+
70
+ :host:not([stacked]) .navbar {
71
+ margin: 0 0 0 var(--zn-spacing-medium);
72
+ padding-left: 0;
17
73
 
18
74
  &--flush {
19
75
  padding: 0;
@@ -55,6 +111,7 @@ ul.navbar {
55
111
 
56
112
  ul.navbar {
57
113
  padding: 0;
114
+ margin: 0;
58
115
  flex-direction: column;
59
116
  gap: 0;
60
117
 
@@ -67,7 +124,7 @@ ul.navbar {
67
124
  }
68
125
 
69
126
  &.zn-tb-active {
70
- background-color: rgb(var(--zn-panel));
127
+ background-color: rgb(var(--zn-body));
71
128
  }
72
129
 
73
130
  &:hover:before {
@@ -170,17 +227,41 @@ ul.navbar.navbar--stacked.navbar--icon-bar {
170
227
 
171
228
  :host(:not([stacked]):not([icon-bar])) {
172
229
  ul.navbar {
173
- height: 35px;
230
+ height: 40px;
174
231
  align-self: end;
175
232
  }
176
233
  }
177
234
 
235
+ :host(:not([stacked]):not([icon-bar]):not([icon-only])) {
236
+ ul.navbar {
237
+ min-width: 180px;
238
+ }
239
+ }
240
+
241
+
178
242
  :host([pad]) {
179
243
  ul.navbar {
180
244
  padding: var(--zn-spacing-medium) var(--zn-spacing-medium) 0;
181
245
  }
182
246
  }
183
247
 
248
+ :host(:not([stacked])) {
249
+ ul.navbar {
250
+ > li {
251
+ border-right-width: 1px;
252
+ border-top-width: 1px;
253
+
254
+ &:first-of-type {
255
+ border-left-width: 1px;
256
+ }
257
+
258
+ &.active, &.zn-tb-active {
259
+ border-bottom: 1px solid rgb(var(--navbar-active-colour));
260
+ }
261
+ }
262
+ }
263
+ }
264
+
184
265
  :host {
185
266
  display: block;
186
267
  width: 100%;
@@ -192,7 +273,7 @@ ul.navbar.navbar--stacked.navbar--icon-bar {
192
273
  ul.navbar {
193
274
  display: flex;
194
275
  flex-basis: fit-content;
195
- gap: 30px;
276
+ gap: 0;
196
277
  list-style: none;
197
278
 
198
279
  li.more {
@@ -218,9 +299,15 @@ ul.navbar.navbar--stacked.navbar--icon-bar {
218
299
 
219
300
  user-select: none;
220
301
  font-weight: 500;
221
- padding: 0 0 var(--zn-spacing-small);
302
+ padding: 0 calc(var(--zn-base-gap, 8px));
303
+ background: rgba(0, 0, 0, 0.05);
304
+ transition: background-color 100ms ease-in-out;
222
305
  position: relative;
223
306
 
307
+ &:hover {
308
+ background: rgba(0, 0, 0, 0.03);
309
+ }
310
+
224
311
  display: flex;
225
312
  align-items: center;
226
313
  justify-content: center;
@@ -250,11 +337,11 @@ ul.navbar.navbar--stacked.navbar--icon-bar {
250
337
  content: '';
251
338
  left: 50%;
252
339
  right: 50%;
253
- bottom: 0;
340
+ bottom: -2px;
254
341
  position: absolute;
255
- background-color: rgb(var(--zn-primary));
342
+ background-color: rgb(var(--navbar-active-colour));
256
343
  transition: all 300ms ease-in-out;
257
- height: 2px;
344
+ height: 1px;
258
345
  }
259
346
 
260
347
  &:hover:before:not(#dropdown-item) {
@@ -264,13 +351,12 @@ ul.navbar.navbar--stacked.navbar--icon-bar {
264
351
  }
265
352
 
266
353
  &.active, &.zn-tb-active {
267
- color: rgb(var(--zn-primary));
268
- font-weight: var(--zn-font-weight-semibold);
354
+ background: rgb(var(--navbar-active-colour));
269
355
  }
270
356
 
271
357
  &.active::before, &.zn-tb-active::before {
272
- left: calc(var(--zn-spacing-medium) * -1);
273
- right: calc(var(--zn-spacing-medium) * -1);
358
+ left: 0;
359
+ right: 0;
274
360
  }
275
361
  }
276
362
 
@@ -324,7 +410,7 @@ button[popovertarget] {
324
410
  border-bottom-width: 1px;
325
411
  border-bottom-style: solid;
326
412
  border-bottom-color: rgb(var(--zn-border-color));
327
- height: 35px;
413
+ height: 40px;
328
414
  }
329
415
 
330
416
  &:host([dropdown]) li {
@@ -356,14 +442,14 @@ button[popovertarget] {
356
442
  right: 0;
357
443
  bottom: -1px;
358
444
  height: 1px;
359
- background-color: rgb(var(--zn-panel));
445
+ background-color: rgb(var(--navbar-active-colour));
360
446
  }
361
447
  }
362
448
  }
363
449
  }
364
450
 
365
451
  .active {
366
- background-color: rgb(var(--zn-panel));
452
+ background-color: rgb(var(--navbar-active-colour));
367
453
  }
368
454
  }
369
455
 
@@ -392,13 +478,14 @@ button[popovertarget] {
392
478
 
393
479
  .expandables {
394
480
  flex-grow: 0;
395
- flex-shrink: 1;
396
- margin: 0 var(--zn-spacing-medium);
481
+ flex-shrink: 0;
482
+ margin: 0;
397
483
  display: flex;
398
484
  align-items: center;
399
485
  width: fit-content;
400
486
  height: 100%;
401
487
  gap: var(--zn-spacing-2x-small);
488
+ padding-right: calc(var(--zn-gutter, 0) + var(--zn-base-gap, 0));
402
489
  }
403
490
 
404
491
  .expandables:empty {
@@ -409,9 +496,27 @@ button[popovertarget] {
409
496
  :host {
410
497
  ul.navbar {
411
498
  li.more {
499
+ // Let the trigger fill the whole cell so clicking anywhere in the
500
+ // "more" item opens the dropdown, not just the icon itself.
501
+ padding: 0;
502
+
503
+ zn-dropdown,
504
+ zn-button[slot="trigger"] {
505
+ height: 100%;
506
+ }
507
+
508
+ zn-button[slot="trigger"] zn-icon {
509
+ transition: transform 200ms ease-in-out;
510
+ }
511
+
512
+ zn-dropdown[open] zn-button[slot="trigger"] zn-icon {
513
+ transform: rotate(90deg);
514
+ }
515
+
412
516
  zn-button::part(base) {
413
- padding-left: 0;
414
- padding-right: 0;
517
+ height: 100%;
518
+ padding-left: calc(var(--zn-base-gap, 8px));
519
+ padding-right: calc(var(--zn-base-gap, 8px));
415
520
 
416
521
  &:hover {
417
522
  background-color: transparent;
@@ -420,12 +525,12 @@ button[popovertarget] {
420
525
 
421
526
  ul#extended-menu {
422
527
  box-shadow: var(--zn-shadow-medium);
423
- background: rgb(var(--zn-border-color));
528
+ background: rgb(var(--zn-panel));
424
529
  display: flex;
425
530
  flex-direction: column;
426
- gap: 1px;
427
531
  height: auto;
428
532
  width: fit-content;
533
+ min-width: var(--zn-size-spanel);
429
534
  margin: 0;
430
535
  padding: 1px;
431
536
 
@@ -435,6 +540,14 @@ button[popovertarget] {
435
540
  color: rgb(var(--zn-text));
436
541
  padding: var(--zn-spacing-small);
437
542
 
543
+ &:hover {
544
+ background: linear-gradient(rgba(0, 0, 0, 0.06), rgba(0, 0, 0, 0.06)), rgb(var(--zn-panel));
545
+ }
546
+
547
+ &.active, &.zn-tb-active {
548
+ font-weight: 700;
549
+ }
550
+
438
551
  &.active::before, &.zn-tb-active::before {
439
552
  left: 0;
440
553
  right: 0;
@@ -1,5 +1,5 @@
1
1
  import '../../../dist/zn.min.js';
2
- import {aTimeout, expect, fixture, html} from '@open-wc/testing';
2
+ import {aTimeout, expect, fixture, html, waitUntil} from '@open-wc/testing';
3
3
  import type ZnNavbar from './navbar.component';
4
4
 
5
5
  describe('<zn-navbar>', () => {
@@ -9,6 +9,116 @@ describe('<zn-navbar>', () => {
9
9
  expect(el).to.exist;
10
10
  });
11
11
 
12
+ it('reserves at least 200px for visible nav items when expandables need space', async () => {
13
+ const el = await fixture<ZnNavbar>(html`
14
+ <zn-navbar>
15
+ <li>One</li>
16
+ <li>Two</li>
17
+ <li>Three</li>
18
+ <li>Four</li>
19
+ <zn-expanding-action></zn-expanding-action>
20
+ </zn-navbar>
21
+ `);
22
+ await aTimeout(150);
23
+
24
+ const nav = el.shadowRoot!.querySelector<HTMLElement>('ul.navbar')!;
25
+ const expandable = el.shadowRoot!.querySelector<HTMLElement>('.expandables')!;
26
+ const items = Array.from(nav.querySelectorAll<HTMLElement>(':scope > li:not(.more)'));
27
+
28
+ Object.defineProperty(el, 'offsetWidth', {configurable: true, get: () => 500});
29
+ Object.defineProperty(expandable, 'offsetWidth', {configurable: true, get: () => 400});
30
+ Object.defineProperty(expandable, 'getBoundingClientRect', {
31
+ configurable: true,
32
+ value: () => ({width: 400})
33
+ });
34
+ items.forEach(item => {
35
+ Object.defineProperty(item, 'offsetWidth', {configurable: true, get: () => 120});
36
+ Object.defineProperty(item, 'getBoundingClientRect', {
37
+ configurable: true,
38
+ value: () => ({width: 120})
39
+ });
40
+ });
41
+
42
+ el.handleResize();
43
+
44
+ expect(getComputedStyle(nav).minWidth).to.equal('200px');
45
+ expect(items[0].classList.contains('hidden')).to.equal(false);
46
+ expect(items[1].classList.contains('hidden')).to.equal(true);
47
+ });
48
+
49
+ it('accounts for open fill expandables when collapsing nav items', async () => {
50
+ const el = await fixture<ZnNavbar>(html`
51
+ <zn-navbar>
52
+ <li>One</li>
53
+ <li>Two</li>
54
+ <li>Three</li>
55
+ <li>Four</li>
56
+ <zn-expanding-action method="fill" open></zn-expanding-action>
57
+ </zn-navbar>
58
+ `);
59
+ await aTimeout(150);
60
+
61
+ const nav = el.shadowRoot!.querySelector<HTMLElement>('ul.navbar')!;
62
+ const expandable = el.shadowRoot!.querySelector<HTMLElement>('.expandables')!;
63
+ const items = Array.from(nav.querySelectorAll<HTMLElement>(':scope > li:not(.more)'));
64
+
65
+ Object.defineProperty(el, 'offsetWidth', {configurable: true, get: () => 1000});
66
+ Object.defineProperty(expandable, 'offsetWidth', {configurable: true, get: () => 40});
67
+ Object.defineProperty(expandable, 'getBoundingClientRect', {
68
+ configurable: true,
69
+ value: () => ({width: 40})
70
+ });
71
+ items.forEach(item => {
72
+ Object.defineProperty(item, 'offsetWidth', {configurable: true, get: () => 120});
73
+ Object.defineProperty(item, 'getBoundingClientRect', {
74
+ configurable: true,
75
+ value: () => ({width: 120})
76
+ });
77
+ });
78
+
79
+ el.handleResize();
80
+
81
+ expect(items[0].classList.contains('hidden')).to.equal(false);
82
+ expect(items[1].classList.contains('hidden')).to.equal(true);
83
+ });
84
+
85
+ it('reserves nav padding and the more button before leaving items visible', async () => {
86
+ const el = await fixture<ZnNavbar>(html`
87
+ <zn-navbar>
88
+ <li>One</li>
89
+ <li>Two</li>
90
+ <li>Three</li>
91
+ </zn-navbar>
92
+ `);
93
+ await aTimeout(150);
94
+
95
+ const nav = el.shadowRoot!.querySelector<HTMLElement>('ul.navbar')!;
96
+ const more = nav.querySelector<HTMLElement>(':scope > li.more')!;
97
+ const items = Array.from(nav.querySelectorAll<HTMLElement>(':scope > li:not(.more)'));
98
+ nav.style.paddingLeft = '20px';
99
+ nav.style.paddingRight = '20px';
100
+
101
+ Object.defineProperty(el, 'offsetWidth', {configurable: true, get: () => 290});
102
+ Object.defineProperty(more, 'offsetWidth', {configurable: true, get: () => 60});
103
+ Object.defineProperty(more, 'getBoundingClientRect', {
104
+ configurable: true,
105
+ value: () => ({width: 60})
106
+ });
107
+ items.forEach(item => {
108
+ Object.defineProperty(item, 'offsetWidth', {configurable: true, get: () => 120});
109
+ Object.defineProperty(item, 'getBoundingClientRect', {
110
+ configurable: true,
111
+ value: () => ({width: 120})
112
+ });
113
+ });
114
+
115
+ el.handleResize();
116
+
117
+ expect(items[0].classList.contains('hidden')).to.equal(false);
118
+ expect(items[1].classList.contains('hidden')).to.equal(true);
119
+ expect(nav.classList.contains('has-hidden')).to.equal(true);
120
+ });
121
+
12
122
  describe('hide-one', () => {
13
123
  it('hides when only one item is present', async () => {
14
124
  const el = await fixture<ZnNavbar>(html`
@@ -34,9 +144,7 @@ describe('<zn-navbar>', () => {
34
144
  li.setAttribute('tab-uri', '/two');
35
145
  li.textContent = 'Second';
36
146
  el.addItem(li, false);
37
- await aTimeout(0);
38
-
39
- expect(getComputedStyle(el).display).to.not.equal('none');
147
+ await waitUntil(() => getComputedStyle(el).display !== 'none', 'navbar should become visible after second item added');
40
148
  });
41
149
 
42
150
  it('hides again when items drop back to one', async () => {
@@ -49,13 +157,10 @@ describe('<zn-navbar>', () => {
49
157
  second.setAttribute('tab-uri', '/two');
50
158
  second.textContent = 'Second';
51
159
  el.addItem(second, false);
52
- await aTimeout(0);
53
- expect(getComputedStyle(el).display).to.not.equal('none');
160
+ await waitUntil(() => getComputedStyle(el).display !== 'none', 'navbar should become visible after second item added');
54
161
 
55
162
  second.remove();
56
- await aTimeout(0);
57
-
58
- expect(getComputedStyle(el).display).to.equal('none');
163
+ await waitUntil(() => getComputedStyle(el).display === 'none', 'navbar should hide after dropping back to one item');
59
164
  });
60
165
  });
61
166
  });
@@ -30,11 +30,13 @@
30
30
  }
31
31
 
32
32
 
33
- .option--hover:not(.option--current):not(.option--disabled) {
34
- background-color: var(--zn-color-primary-100);
35
- color: var(--zn-input-color);
33
+ /* Selected is the base highlight; hover/current below take priority over it. */
34
+ .option--selected {
35
+ background-color: var(--zn-color-primary-200);
36
36
  }
37
37
 
38
+ /* Mouse-hover and keyboard-current take priority over the selected background. */
39
+ .option--hover:not(.option--disabled),
38
40
  .option--current,
39
41
  .option--current.option--disabled {
40
42
  background-color: var(--zn-color-primary-100);
@@ -69,10 +71,6 @@
69
71
  visibility: visible;
70
72
  }
71
73
 
72
- .option--selected {
73
- background-color: var(--zn-color-primary-200);
74
- }
75
-
76
74
  .option__prefix,
77
75
  .option__suffix {
78
76
  flex: 0 0 auto;
@@ -1,5 +1,6 @@
1
1
  import '../../../dist/zn.min.js';
2
2
  import { expect, fixture, html } from '@open-wc/testing';
3
+ import type ZnOption from './option.component';
3
4
 
4
5
  describe('<zn-option>', () => {
5
6
  it('should render a component', async () => {
@@ -7,4 +8,33 @@ describe('<zn-option>', () => {
7
8
 
8
9
  expect(el).to.exist;
9
10
  });
11
+
12
+ it('prioritises the hover/current highlight over the selected background', async () => {
13
+ // Inject the palette so the computed colors resolve deterministically in the test environment.
14
+ const el = await fixture<ZnOption>(html`
15
+ <zn-option
16
+ value="a"
17
+ selected
18
+ style="--zn-color-primary-100: rgb(10, 20, 30); --zn-color-primary-200: rgb(40, 50, 60);">
19
+ A
20
+ </zn-option>
21
+ `);
22
+ await el.updateComplete;
23
+
24
+ const base = el.shadowRoot!.querySelector<HTMLElement>('.option')!;
25
+
26
+ // Selected only → the selected background
27
+ expect(getComputedStyle(base).backgroundColor).to.equal('rgb(40, 50, 60)');
28
+
29
+ // Keyboard-current + selected → the highlight must win over selected
30
+ el.current = true;
31
+ await el.updateComplete;
32
+ expect(getComputedStyle(base).backgroundColor, 'current should win over selected').to.equal('rgb(10, 20, 30)');
33
+
34
+ // Mouse-hover + selected → the highlight must win over selected
35
+ el.current = false;
36
+ el.hasHover = true;
37
+ await el.updateComplete;
38
+ expect(getComputedStyle(base).backgroundColor, 'hover should win over selected').to.equal('rgb(10, 20, 30)');
39
+ });
10
40
  });
@@ -0,0 +1,13 @@
1
+ import ZnPage from './page.component';
2
+
3
+ export * from './page.component';
4
+ export default ZnPage;
5
+
6
+ ZnPage.define('zn-page');
7
+
8
+ declare global {
9
+ interface HTMLElementTagNameMap {
10
+ 'zn-page': ZnPage;
11
+ }
12
+ }
13
+