@kubex/zinc 1.0.114 → 1.0.115
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/dist/custom-elements.json +91 -74
- package/dist/vscode.html-custom-data.json +13 -12
- package/dist/web-types.json +29 -24
- package/dist/zn.d.ts +1 -0
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +82 -83
- package/package.json +1 -1
- package/scss/_root.scss +3 -3
- package/scss/mixins/_spacing-mixins.scss +1 -1
- package/src/components/cols/cols.scss +1 -1
- package/src/components/data-select/data-select.scss +1 -0
- package/src/components/dialog/dialog.scss +4 -0
- package/src/components/form-group/form-group.component.ts +28 -28
- package/src/components/form-group/form-group.scss +1 -0
- package/src/components/header/header.scss +1 -5
- package/src/components/panel/panel.scss +4 -16
- package/src/components/select/select.component.ts +3 -1
- package/src/components/select/select.scss +21 -5
- package/src/components/select/select.test.ts +56 -0
- package/src/components/table/table.scss +1 -0
- package/src/components/tile/tile.scss +2 -2
package/package.json
CHANGED
package/scss/_root.scss
CHANGED
|
@@ -52,21 +52,21 @@
|
|
|
52
52
|
|
|
53
53
|
@media (min-width: 1024px) {
|
|
54
54
|
:root {
|
|
55
|
-
--zn-base-gap:
|
|
55
|
+
--zn-base-gap: 16px;
|
|
56
56
|
--zn-gutter: 6px;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
@media (min-width: 1600px) {
|
|
61
61
|
:root {
|
|
62
|
-
--zn-base-gap:
|
|
62
|
+
--zn-base-gap: 20px;
|
|
63
63
|
--zn-gutter: 8px;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
@media (min-width: 2000px) {
|
|
68
68
|
:root {
|
|
69
|
-
--zn-base-gap:
|
|
69
|
+
--zn-base-gap: 24px;
|
|
70
70
|
--zn-gutter: 10px;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -35,6 +35,7 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
35
35
|
/** The form groups help text. If you need to display HTML, use the `help-text` slot instead. */
|
|
36
36
|
@property({attribute: 'help-text'}) helpText = '';
|
|
37
37
|
@property({attribute: 'cols', type: Boolean}) forceCols = false;
|
|
38
|
+
@property({attribute: 'layout', type: String}) layout = "1,2";
|
|
38
39
|
|
|
39
40
|
render() {
|
|
40
41
|
const hasLabelSlot = this.hasSlotController.test('label');
|
|
@@ -56,38 +57,37 @@ export default class ZnFormGroup extends ZincElement {
|
|
|
56
57
|
aria-labelledby="label"
|
|
57
58
|
aria-describedby="help-text">
|
|
58
59
|
|
|
59
|
-
<zn-cols layout="
|
|
60
|
+
<zn-cols layout="${this.layout}" part="form-control-container" class="form-control__container">
|
|
60
61
|
${hasLabel || hasHelpText || this.forceCols ? html`
|
|
61
|
-
<div>` : html``}
|
|
62
|
-
${hasLabel ? html`
|
|
63
62
|
<div>
|
|
64
|
-
<label
|
|
65
|
-
part="form-control-label"
|
|
66
|
-
id="label"
|
|
67
|
-
class="form-control__label"
|
|
68
|
-
aria-hidden="${hasLabel ? 'false' : 'true'}">
|
|
69
|
-
<slot name="label">${this.label}</slot>
|
|
70
|
-
${hasLabelTooltip
|
|
71
|
-
? html`
|
|
72
|
-
<zn-tooltip class="form-control--label-tooltip">
|
|
73
|
-
<div slot="content">
|
|
74
|
-
<slot name="label-tooltip">${this.labelTooltip}</slot>
|
|
75
|
-
</div>
|
|
76
|
-
<zn-icon src="info"></zn-icon>
|
|
77
|
-
</zn-tooltip>`
|
|
78
|
-
: ''}
|
|
79
|
-
</label>
|
|
80
|
-
</div>` : html``}
|
|
81
63
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
64
|
+
${hasLabel ? html`
|
|
65
|
+
<label
|
|
66
|
+
part="form-control-label"
|
|
67
|
+
id="label"
|
|
68
|
+
class="form-control__label"
|
|
69
|
+
aria-hidden="${hasLabel ? 'false' : 'true'}">
|
|
70
|
+
<slot name="label">${this.label}</slot>
|
|
71
|
+
${hasLabelTooltip
|
|
72
|
+
? html`
|
|
73
|
+
<zn-tooltip class="form-control--label-tooltip">
|
|
74
|
+
<div slot="content">
|
|
75
|
+
<slot name="label-tooltip">${this.labelTooltip}</slot>
|
|
76
|
+
</div>
|
|
77
|
+
<zn-icon src="info"></zn-icon>
|
|
78
|
+
</zn-tooltip>`
|
|
79
|
+
: ''}
|
|
80
|
+
</label>` : html``}
|
|
89
81
|
|
|
90
|
-
|
|
82
|
+
${hasHelpText ? html`
|
|
83
|
+
<div
|
|
84
|
+
part="form-control-help-text"
|
|
85
|
+
id="help-text"
|
|
86
|
+
class="form-control__help-text">
|
|
87
|
+
<slot name="help-text">${this.helpText}</slot>
|
|
88
|
+
</div>` : html``}
|
|
89
|
+
|
|
90
|
+
</div>` : html``}
|
|
91
91
|
|
|
92
92
|
<div part="form-control-input" class="form-control-input">
|
|
93
93
|
<slot></slot>
|
|
@@ -109,10 +109,6 @@
|
|
|
109
109
|
&__caption {
|
|
110
110
|
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
.caption {
|
|
114
|
-
min-height: initial;
|
|
115
|
-
}
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
114
|
|
|
@@ -139,7 +135,7 @@
|
|
|
139
135
|
justify-content: center;
|
|
140
136
|
flex-direction: column;
|
|
141
137
|
gap: 1px;
|
|
142
|
-
min-height:
|
|
138
|
+
min-height: 24px;
|
|
143
139
|
flex-shrink: 1;
|
|
144
140
|
max-width: 100%;
|
|
145
141
|
}
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
&__header {
|
|
46
|
-
padding: var(--zn-
|
|
46
|
+
padding: var(--zn-base-gap);
|
|
47
47
|
|
|
48
48
|
// background-color: rgba(var(--zn-panel-highlight), 0.6);
|
|
49
49
|
// border-bottom: 1px solid rgb(var(--zn-border-color));
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
flex-direction: column;
|
|
75
75
|
overflow-y: auto;
|
|
76
76
|
flex-grow: 1;
|
|
77
|
-
padding: 0 var(--zn-
|
|
77
|
+
padding: 0 var(--zn-base-gap) var(--zn-base-gap) var(--zn-base-gap);
|
|
78
78
|
|
|
79
79
|
> :not([hidden]) ~ :not([hidden]) {
|
|
80
80
|
border: 1px solid rgb(var(--zn-border-color));
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
&__footer {
|
|
85
85
|
font-size: var(--zn-font-size-small);
|
|
86
86
|
display: block;
|
|
87
|
-
padding: var(--zn-spacing-small) var(--zn-
|
|
87
|
+
padding: var(--zn-spacing-small) var(--zn-base-gap);
|
|
88
88
|
background: rgb(var(--zn-panel-secondary));
|
|
89
89
|
border-bottom-left-radius: var(--zn-border-radius-large);
|
|
90
90
|
border-bottom-right-radius: var(--zn-border-radius-large);
|
|
@@ -109,21 +109,9 @@
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
&:before {
|
|
113
|
-
position: absolute;
|
|
114
|
-
content: '';
|
|
115
|
-
bottom: -3px;
|
|
116
|
-
left: 0;
|
|
117
|
-
right: 0;
|
|
118
|
-
height: 20px;
|
|
119
|
-
background-color: rgb(var(--zn-shadow));
|
|
120
|
-
border-radius: var(--zn-border-radius-large);
|
|
121
|
-
z-index: -1;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
112
|
|
|
125
113
|
&:not(.panel--has-header):not(.panel--flush, .panel--flush-y) &__body {
|
|
126
|
-
padding-top: var(--zn-
|
|
114
|
+
padding-top: var(--zn-base-gap);
|
|
127
115
|
}
|
|
128
116
|
|
|
129
117
|
&--flush {
|
|
@@ -722,7 +722,9 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
722
722
|
private handleClearClick(event: MouseEvent) {
|
|
723
723
|
event.stopPropagation();
|
|
724
724
|
|
|
725
|
-
if (this.value
|
|
725
|
+
if (this.value.length > 0) {
|
|
726
|
+
this.valueHasChanged = true;
|
|
727
|
+
|
|
726
728
|
if (this._isTypeable) {
|
|
727
729
|
this.clearSearch();
|
|
728
730
|
this.displayInput.value = '';
|
|
@@ -127,6 +127,15 @@
|
|
|
127
127
|
flex-wrap: wrap;
|
|
128
128
|
gap: var(--zn-spacing-2x-small);
|
|
129
129
|
padding-inline-start: 0;
|
|
130
|
+
/* Allow the control to grow with the wrapped tag rows instead of clipping them, and pack the rows
|
|
131
|
+
from the top with a little vertical padding. align-self stops the popup from stretching the
|
|
132
|
+
combobox to a fixed height, so it sizes to its (wrapped) content. */
|
|
133
|
+
overflow: visible;
|
|
134
|
+
align-content: flex-start;
|
|
135
|
+
align-items: center;
|
|
136
|
+
align-self: flex-start;
|
|
137
|
+
height: auto;
|
|
138
|
+
padding-block: var(--zn-spacing-2x-small);
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
.select__value-input {
|
|
@@ -149,13 +158,21 @@
|
|
|
149
158
|
margin-inline-start: var(--zn-spacing-2x-small);
|
|
150
159
|
}
|
|
151
160
|
|
|
152
|
-
|
|
153
|
-
|
|
161
|
+
/* The tags are rendered into the shadow (not slotted), so target them as descendants. Only the remove
|
|
162
|
+
"X" is clickable (pointer); the chip body isn't, so give it a default cursor rather than letting it
|
|
163
|
+
inherit the combobox's text cursor in search/free-text mode. */
|
|
164
|
+
.select__tags zn-chip {
|
|
165
|
+
cursor: default;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.select__tags zn-icon[slot="action"] {
|
|
169
|
+
cursor: pointer;
|
|
154
170
|
}
|
|
155
171
|
|
|
156
172
|
.select--disabled .select__tags,
|
|
157
|
-
.select--disabled .select__tags
|
|
158
|
-
|
|
173
|
+
.select--disabled .select__tags zn-chip,
|
|
174
|
+
.select--disabled .select__tags zn-icon[slot="action"] {
|
|
175
|
+
cursor: not-allowed;
|
|
159
176
|
}
|
|
160
177
|
|
|
161
178
|
/* Standard selects */
|
|
@@ -374,7 +391,6 @@
|
|
|
374
391
|
border: solid var(--zn-panel-border-width) var(--zn-panel-border-color);
|
|
375
392
|
border-radius: var(--zn-border-radius-medium);
|
|
376
393
|
margin: var(--zn-spacing-x-small) 0;
|
|
377
|
-
padding-block: var(--zn-spacing-x-small);
|
|
378
394
|
padding-inline: 0;
|
|
379
395
|
overflow: auto;
|
|
380
396
|
overscroll-behavior: none;
|
|
@@ -3,6 +3,16 @@ import {expect, fixture, html} from '@open-wc/testing';
|
|
|
3
3
|
import type ZnOption from '../option/option.component';
|
|
4
4
|
import type ZnSelect from './select.component';
|
|
5
5
|
|
|
6
|
+
// The popup's ResizeObserver can emit a benign "loop completed with undelivered notifications"
|
|
7
|
+
// warning when the dropdown opens during layout-measuring tests. It's not a real error — ignore it
|
|
8
|
+
// so the test runner doesn't treat it as an uncaught exception (capture phase runs before the runner's).
|
|
9
|
+
window.addEventListener('error', (e: ErrorEvent) => {
|
|
10
|
+
if (typeof e.message === 'string' && e.message.includes('ResizeObserver loop')) {
|
|
11
|
+
e.stopImmediatePropagation();
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
}
|
|
14
|
+
}, true);
|
|
15
|
+
|
|
6
16
|
describe('<zn-select>', () => {
|
|
7
17
|
it('should render a component', async () => {
|
|
8
18
|
const el = await fixture(html`
|
|
@@ -177,6 +187,52 @@ describe('<zn-select>', () => {
|
|
|
177
187
|
|
|
178
188
|
});
|
|
179
189
|
|
|
190
|
+
describe('multiple + search layout', () => {
|
|
191
|
+
const openWithTags = async (width: number) => {
|
|
192
|
+
const el = await fixture<ZnSelect>(html`
|
|
193
|
+
<zn-select search multiple max-options-visible="0" style="width: ${width}px;">
|
|
194
|
+
<zn-option value="a" selected>Urgent</zn-option>
|
|
195
|
+
<zn-option value="b" selected>Backend</zn-option>
|
|
196
|
+
<zn-option value="c" selected>Frontend</zn-option>
|
|
197
|
+
<zn-option value="d" selected>stetset</zn-option>
|
|
198
|
+
<zn-option value="e" selected>another</zn-option>
|
|
199
|
+
</zn-select>
|
|
200
|
+
`);
|
|
201
|
+
await el.updateComplete;
|
|
202
|
+
await el.show();
|
|
203
|
+
await el.updateComplete;
|
|
204
|
+
return el.shadowRoot!.querySelector<HTMLElement>('.select__combobox')!;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
it('grows to show all tags instead of clipping them when they wrap', async () => {
|
|
208
|
+
const cb = await openWithTags(360);
|
|
209
|
+
// scrollHeight > clientHeight would mean wrapped rows are clipped by the box.
|
|
210
|
+
expect(cb.scrollHeight).to.equal(cb.clientHeight);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('does not clip tags at very narrow widths', async () => {
|
|
214
|
+
const cb = await openWithTags(180);
|
|
215
|
+
expect(cb.scrollHeight).to.equal(cb.clientHeight);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('shows a pointer cursor on a tag remove icon (even in search mode)', async () => {
|
|
219
|
+
// In search/free-text mode the combobox uses cursor:text, which the chips would otherwise inherit.
|
|
220
|
+
const el = await fixture<ZnSelect>(html`
|
|
221
|
+
<zn-select multiple search>
|
|
222
|
+
<zn-option value="a" selected>Apple</zn-option>
|
|
223
|
+
</zn-select>
|
|
224
|
+
`);
|
|
225
|
+
await el.updateComplete;
|
|
226
|
+
const removeIcon = el.shadowRoot!.querySelector<HTMLElement>('.select__tags zn-icon[slot="action"]');
|
|
227
|
+
expect(removeIcon, 'remove icon should exist').to.exist;
|
|
228
|
+
// Only the remove X is clickable, so only it gets a pointer cursor...
|
|
229
|
+
expect(getComputedStyle(removeIcon!).cursor).to.equal('pointer');
|
|
230
|
+
// ...the chip body is not clickable, so it should not show a pointer.
|
|
231
|
+
const chip = el.shadowRoot!.querySelector<HTMLElement>('.select__tags zn-chip')!;
|
|
232
|
+
expect(getComputedStyle(chip).cursor).to.equal('default');
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
180
236
|
describe('free-text', () => {
|
|
181
237
|
const type = (el: ZnSelect, text: string) => {
|
|
182
238
|
const displayInput = el.shadowRoot!.querySelector<HTMLInputElement>('.select__display-input')!;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
&--has-properties,
|
|
13
13
|
&--has-actions,
|
|
14
14
|
&--has-image {
|
|
15
|
-
padding: var(--zn-spacing-
|
|
15
|
+
padding: var(--zn-spacing-medium);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
justify-content: flex-end;
|
|
63
63
|
width: 50%;
|
|
64
64
|
flex-grow: 1;
|
|
65
|
-
column-gap: var(--zn-spacing-
|
|
65
|
+
column-gap: var(--zn-spacing-medium);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
.tile__properties {
|