@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.
- package/.github/workflows/eleventy_build.yml +5 -5
- package/.github/workflows/js_build_and_deploy.yaml +1 -1
- package/dist/custom-elements.json +2636 -421
- package/dist/vscode.html-custom-data.json +96 -16
- package/dist/web-types.json +268 -31
- package/dist/zn.d.ts +517 -340
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +942 -863
- package/docs/eleventy.config.cjs +4 -2
- package/docs/pages/components/header.md +13 -0
- package/docs/pages/components/inline-edit.md +20 -0
- package/docs/pages/components/item.md +12 -1
- package/docs/pages/components/page.md +149 -0
- package/docs/pages/components/progress-bar.md +16 -0
- package/docs/pages/components/select.md +25 -0
- package/docs/pages/components/split-pane.md +6 -7
- package/docs/pages/components/tabs.md +59 -9
- package/package.json +8 -5
- package/scripts/build.js +40 -19
- package/scss/_global-spacing.scss +12 -1
- package/scss/_root.scss +34 -2
- package/scss/shared/layout.scss +15 -2
- package/scss/themes/_light.scss +1 -1
- package/src/components/absolute-container/absolute-container.component.ts +9 -25
- package/src/components/animated-button/animated-button.test.ts +8 -8
- package/src/components/button/button.component.ts +3 -1
- package/src/components/button/button.scss +5 -0
- package/src/components/button-menu/button-menu.component.ts +36 -21
- package/src/components/button-menu/button-menu.test.ts +55 -1
- package/src/components/chart/chart.component.ts +7 -7
- package/src/components/collapsible/collapsible.component.ts +7 -14
- package/src/components/cols/cols.scss +1 -1
- package/src/components/content-block/content-block.component.ts +11 -33
- package/src/components/data-select/data-select.component.ts +7 -11
- package/src/components/data-table/data-table.component.ts +10 -14
- package/src/components/editor/modules/toolbar/toolbar.component.ts +5 -9
- package/src/components/expanding-action/expanding-action.component.ts +37 -43
- package/src/components/form-group/form-group.component.ts +8 -3
- package/src/components/header/header.component.ts +6 -5
- package/src/components/header/header.scss +31 -25
- package/src/components/inline-edit/inline-edit.component.ts +13 -1
- package/src/components/inline-edit/inline-edit.test.ts +50 -0
- package/src/components/input/input.test.ts +77 -0
- package/src/components/input-group/input-group.test.ts +2 -10
- package/src/components/item/item.component.ts +12 -6
- package/src/components/item/item.scss +1 -1
- package/src/components/item/item.test.ts +8 -0
- package/src/components/navbar/navbar.component.ts +222 -48
- package/src/components/navbar/navbar.scss +134 -21
- package/src/components/navbar/navbar.test.ts +114 -9
- package/src/components/option/option.scss +5 -7
- package/src/components/option/option.test.ts +30 -0
- package/src/components/page/index.ts +13 -0
- package/src/components/page/page.component.ts +406 -0
- package/src/components/page/page.scss +325 -0
- package/src/components/page/page.test.ts +397 -0
- package/src/components/page-nav/page-nav.scss +7 -5
- package/src/components/pane/pane.component.ts +2 -2
- package/src/components/pane/pane.scss +0 -1
- package/src/components/pane/pane.test.ts +31 -0
- package/src/components/panel/panel.scss +1 -0
- package/src/components/progress-bar/progress-bar.component.ts +5 -2
- package/src/components/progress-bar/progress-bar.scss +17 -1
- package/src/components/progress-bar/progress-bar.test.ts +12 -0
- package/src/components/scroll-container/scroll-container.component.ts +22 -21
- package/src/components/select/select.component.ts +240 -38
- package/src/components/select/select.scss +15 -0
- package/src/components/select/select.test.ts +477 -0
- package/src/components/settings-container/settings-container.component.ts +15 -19
- package/src/components/settings-container/settings-container.scss +8 -8
- package/src/components/sidebar/sidebar.component.ts +11 -11
- package/src/components/simple-chart/simple-chart.component.ts +6 -7
- package/src/components/sp/sp.scss +46 -15
- package/src/components/sp/sp.test.ts +15 -0
- package/src/components/split-pane/split-pane.component.ts +153 -26
- package/src/components/split-pane/split-pane.scss +89 -13
- package/src/components/split-pane/split-pane.test.ts +187 -0
- package/src/components/style/style.component.ts +8 -0
- package/src/components/tab/index.ts +13 -0
- package/src/components/tab/tab.component.ts +25 -0
- package/src/components/tab/tab.scss +7 -0
- package/src/components/table/table.component.ts +7 -2
- package/src/components/tabs/tabs.component.ts +75 -70
- package/src/components/tabs/tabs.scss +1 -1
- package/src/components/textarea/textarea.component.ts +5 -8
- package/src/components/translation-group/translation-group.component.ts +15 -14
- package/src/components/translations/translations.component.ts +18 -17
- package/src/components/translations/translations.scss +1 -0
- package/src/components/translations/translations.test.ts +3 -2
- package/src/internal/form.ts +234 -0
- package/src/internal/theme.ts +26 -46
- package/src/internal/zinc-element.ts +12 -7
- package/src/utilities/form.ts +1 -0
- package/src/wc.scss +1 -1
- 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
|
-
|
|
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-
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
340
|
+
bottom: -2px;
|
|
254
341
|
position: absolute;
|
|
255
|
-
background-color: rgb(var(--
|
|
342
|
+
background-color: rgb(var(--navbar-active-colour));
|
|
256
343
|
transition: all 300ms ease-in-out;
|
|
257
|
-
height:
|
|
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
|
-
|
|
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:
|
|
273
|
-
right:
|
|
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:
|
|
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(--
|
|
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(--
|
|
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:
|
|
396
|
-
margin: 0
|
|
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
|
-
|
|
414
|
-
padding-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
color: var(--zn-
|
|
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
|
});
|