@kubex/zinc 1.0.17 → 1.0.19
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 +308 -6
- package/dist/vscode.html-custom-data.json +43 -2
- package/dist/web-types.json +88 -5
- package/dist/zn.d.ts +69 -4
- package/dist/zn.min.js +568 -530
- package/docs/pages/components/select.md +23 -2
- package/package.json +1 -1
- package/src/components/audio-select/audio-select.component.ts +128 -0
- package/src/components/audio-select/audio-select.scss +4 -0
- package/src/components/audio-select/audio-select.test.ts +10 -0
- package/src/components/audio-select/index.ts +12 -0
- package/src/components/checkbox/checkbox.component.ts +53 -4
- package/src/components/checkbox/checkbox.scss +145 -11
- package/src/components/data-table/data-table.component.ts +35 -9
- package/src/components/select/select.component.ts +81 -53
- package/src/components/select/select.scss +21 -0
- package/src/components/style/style.component.ts +1 -1
- package/src/zinc.ts +1 -0
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { type CSSResultGroup, html, nothing, PropertyValues, type TemplateResult, unsafeCSS } from 'lit';
|
|
1
|
+
import {animateTo, stopAnimations} from '../../internal/animate.js';
|
|
2
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
4
3
|
import {deepQuerySelectorAll} from "../../utilities/query";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
4
|
+
import {FormControlController} from "../../internal/form";
|
|
5
|
+
import {getAnimation, setDefaultAnimation} from "../../utilities/animation-registry";
|
|
6
|
+
import {HasSlotController} from "../../internal/slot";
|
|
7
|
+
import {html, nothing, unsafeCSS} from 'lit';
|
|
8
|
+
import {LocalizeController} from "../../utilities/localize";
|
|
9
|
+
import {property, query, state} from 'lit/decorators.js';
|
|
10
|
+
import {scrollIntoView} from "../../internal/scroll";
|
|
11
|
+
import {unsafeHTML} from "lit/directives/unsafe-html.js";
|
|
12
|
+
import {waitForEvent} from "../../internal/event";
|
|
13
|
+
import {watch} from '../../internal/watch';
|
|
14
14
|
import ZincElement from '../../internal/zinc-element';
|
|
15
15
|
import ZnChip from "../chip";
|
|
16
16
|
import ZnIcon from "../icon";
|
|
17
17
|
import ZnPopup from "../popup";
|
|
18
|
-
import type {
|
|
19
|
-
import type {
|
|
18
|
+
import type {CSSResultGroup, PropertyValues, TemplateResult} from 'lit';
|
|
19
|
+
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
20
|
+
import type {ZnRemoveEvent} from "../../events/zn-remove";
|
|
20
21
|
import type ZnOption from "../option";
|
|
21
22
|
|
|
22
23
|
import styles from './select.scss';
|
|
@@ -90,12 +91,14 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
90
91
|
@query('.select__display-input') displayInput: HTMLInputElement;
|
|
91
92
|
@query('.select__value-input') valueInput: HTMLInputElement;
|
|
92
93
|
@query('.select__listbox') listbox: HTMLSlotElement;
|
|
94
|
+
@query('slot[name="prefix"]') prefixSlot: HTMLSlotElement;
|
|
93
95
|
|
|
94
96
|
@state() private hasFocus = false;
|
|
95
97
|
@state() displayLabel = '';
|
|
96
98
|
@state() currentOption: ZnOption;
|
|
97
99
|
@state() selectedOptions: ZnOption[] = [];
|
|
98
100
|
@state() private valueHasChanged: boolean = false;
|
|
101
|
+
@state() private inputPrefix: boolean = false;
|
|
99
102
|
|
|
100
103
|
/** The name of the select, submitted as a name/value pair with form data. */
|
|
101
104
|
@property() name = '';
|
|
@@ -142,73 +145,75 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
142
145
|
}) defaultValue: string | string[] = '';
|
|
143
146
|
|
|
144
147
|
/** The select's size. */
|
|
145
|
-
@property({
|
|
148
|
+
@property({reflect: true}) size: 'small' | 'medium' | 'large' = 'medium';
|
|
146
149
|
|
|
147
150
|
/** Placeholder text to show as a hint when the select is empty. */
|
|
148
151
|
@property() placeholder = '';
|
|
149
152
|
|
|
150
153
|
/** Allows more than one option to be selected. */
|
|
151
|
-
@property({
|
|
154
|
+
@property({type: Boolean, reflect: true}) multiple = false;
|
|
152
155
|
|
|
153
156
|
/** Max number of options that can be selected when `multiple` is true. Set to 0 to allow unlimited selections. */
|
|
154
|
-
@property({
|
|
157
|
+
@property({attribute: 'max-options', type: Number}) maxOptions = 0;
|
|
155
158
|
|
|
156
159
|
/**
|
|
157
160
|
* The maximum number of selected options to show when `multiple` is true. After the maximum, "+n" will be shown to
|
|
158
161
|
* indicate the number of additional items that are selected. Set to 0 to remove the limit.
|
|
159
162
|
*/
|
|
160
|
-
@property({
|
|
163
|
+
@property({attribute: 'max-options-visible', type: Number}) maxOptionsVisible = 3;
|
|
161
164
|
|
|
162
165
|
/** Disables the select control. */
|
|
163
|
-
@property({
|
|
166
|
+
@property({type: Boolean, reflect: true}) disabled = false;
|
|
164
167
|
|
|
165
168
|
/** Adds a clear button when the select is not empty. */
|
|
166
|
-
@property({
|
|
169
|
+
@property({type: Boolean}) clearable = false;
|
|
167
170
|
|
|
168
171
|
/**
|
|
169
172
|
* Indicates whether or not the select is open. You can toggle this attribute to show and hide the menu, or you can
|
|
170
173
|
* use the `show()` and `hide()` methods and this attribute will reflect the select's open state.
|
|
171
174
|
*/
|
|
172
|
-
@property({
|
|
175
|
+
@property({type: Boolean, reflect: true}) open = false;
|
|
173
176
|
|
|
174
177
|
/**
|
|
175
178
|
* Enable this option to prevent the listbox from being clipped when the component is placed inside a container with
|
|
176
179
|
* `overflow: auto|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all, scenarios.
|
|
177
180
|
*/
|
|
178
|
-
@property({
|
|
181
|
+
@property({type: Boolean}) hoist = false;
|
|
179
182
|
|
|
180
183
|
/** Draws a pill-style select with rounded edges. */
|
|
181
|
-
@property({
|
|
184
|
+
@property({type: Boolean, reflect: true}) pill = false;
|
|
182
185
|
|
|
183
186
|
/** The select's label. If you need to display HTML, use the `label` slot instead. */
|
|
184
187
|
@property() label = '';
|
|
185
188
|
|
|
186
189
|
/** Text that appears in a tooltip next to the label. If you need to display HTML in the tooltip, use the `label-tooltip` slot instead. */
|
|
187
|
-
@property({
|
|
190
|
+
@property({attribute: 'label-tooltip'}) labelTooltip = '';
|
|
188
191
|
|
|
189
192
|
/** Text that appears above the input, on the right, to add additional context. If you need to display HTML in this text, use the `context-note` slot instead. */
|
|
190
|
-
@property({
|
|
193
|
+
@property({attribute: 'context-note'}) contextNote = '';
|
|
191
194
|
|
|
192
195
|
/**
|
|
193
196
|
* The preferred placement of the selects menu. Note that the actual placement may vary as needed to keep the listbox
|
|
194
197
|
* inside the viewport.
|
|
195
198
|
*/
|
|
196
|
-
@property({
|
|
199
|
+
@property({reflect: true}) placement: 'top' | 'bottom' = 'bottom';
|
|
197
200
|
|
|
198
201
|
/** The select's help text. If you need to display HTML, use the `help-text` slot instead. */
|
|
199
|
-
@property({
|
|
202
|
+
@property({attribute: 'help-text'}) helpText = '';
|
|
200
203
|
|
|
201
204
|
/**
|
|
202
205
|
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
|
|
203
206
|
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
|
|
204
207
|
* the same document or shadow root for this to work.
|
|
205
208
|
*/
|
|
206
|
-
@property({
|
|
209
|
+
@property({reflect: true}) form: string;
|
|
207
210
|
|
|
208
211
|
/** The select's required attribute. */
|
|
209
|
-
@property({
|
|
212
|
+
@property({type: Boolean, reflect: true}) required = false;
|
|
210
213
|
|
|
211
|
-
@property({
|
|
214
|
+
@property({attribute: 'cache-key'}) cacheKey: string = "";
|
|
215
|
+
|
|
216
|
+
@property({type: Boolean, attribute: 'trigger-submit'}) triggerSubmit = false;
|
|
212
217
|
|
|
213
218
|
/**
|
|
214
219
|
* A function that customizes the tags to be rendered when multiple=true. The first argument is the option, the second
|
|
@@ -266,6 +271,11 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
266
271
|
}
|
|
267
272
|
}
|
|
268
273
|
|
|
274
|
+
private updateHasInputPrefix() {
|
|
275
|
+
const assigned = this.prefixSlot?.assignedElements({flatten: true}) || [];
|
|
276
|
+
this.inputPrefix = assigned.length > 0;
|
|
277
|
+
}
|
|
278
|
+
|
|
269
279
|
private addOpenListeners() {
|
|
270
280
|
const root = this.getRootNode();
|
|
271
281
|
root.addEventListener('focusin', this.handleDocumentFocusIn);
|
|
@@ -278,7 +288,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
278
288
|
this.closeWatcher.onclose = () => {
|
|
279
289
|
if (this.open) {
|
|
280
290
|
this.hide();
|
|
281
|
-
this.displayInput.focus({
|
|
291
|
+
this.displayInput.focus({preventScroll: true});
|
|
282
292
|
}
|
|
283
293
|
};
|
|
284
294
|
}
|
|
@@ -330,7 +340,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
330
340
|
event.preventDefault();
|
|
331
341
|
event.stopPropagation();
|
|
332
342
|
this.hide();
|
|
333
|
-
this.displayInput.focus({
|
|
343
|
+
this.displayInput.focus({preventScroll: true});
|
|
334
344
|
}
|
|
335
345
|
|
|
336
346
|
// Handle enter and space. When pressing space, we allow for type to select behaviors so if there's anything in the
|
|
@@ -362,7 +372,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
362
372
|
|
|
363
373
|
if (!this.multiple) {
|
|
364
374
|
this.hide();
|
|
365
|
-
this.displayInput.focus({
|
|
375
|
+
this.displayInput.focus({preventScroll: true});
|
|
366
376
|
}
|
|
367
377
|
}
|
|
368
378
|
|
|
@@ -463,13 +473,15 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
463
473
|
|
|
464
474
|
// not the keyboard_arrow_down icon
|
|
465
475
|
const isExpandIcon = path.some(el => el instanceof Element && el.classList.contains('select__expand-icon'));
|
|
476
|
+
// if click is inside the prefix area (e.g. checkbox), don't toggle the select
|
|
477
|
+
const inPrefix = path.some(el => el instanceof Element && el.classList.contains('select__prefix'));
|
|
466
478
|
// Ignore disabled controls and clicks on tags (remove buttons)
|
|
467
|
-
if ((this.disabled || isIcon) && !isExpandIcon) {
|
|
479
|
+
if (((this.disabled || isIcon) && !isExpandIcon) || inPrefix) {
|
|
468
480
|
return;
|
|
469
481
|
}
|
|
470
482
|
|
|
471
483
|
event.preventDefault();
|
|
472
|
-
this.displayInput.focus({
|
|
484
|
+
this.displayInput.focus({preventScroll: true});
|
|
473
485
|
this.open = !this.open;
|
|
474
486
|
}
|
|
475
487
|
|
|
@@ -478,8 +490,14 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
478
490
|
return;
|
|
479
491
|
}
|
|
480
492
|
|
|
481
|
-
|
|
482
|
-
|
|
493
|
+
// If keydown originated from within the prefix (e.g. checkbox)
|
|
494
|
+
const path = event.composedPath();
|
|
495
|
+
const inPrefix = path.some(el => el instanceof Element && (el as Element).classList?.contains('select__prefix'));
|
|
496
|
+
|
|
497
|
+
if (!inPrefix) {
|
|
498
|
+
event.stopPropagation();
|
|
499
|
+
this.handleDocumentKeyDown(event);
|
|
500
|
+
}
|
|
483
501
|
}
|
|
484
502
|
|
|
485
503
|
private handleClearClick(event: MouseEvent) {
|
|
@@ -487,7 +505,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
487
505
|
|
|
488
506
|
if (this.value !== '') {
|
|
489
507
|
this.setSelectedOptions([]);
|
|
490
|
-
this.displayInput.focus({
|
|
508
|
+
this.displayInput.focus({preventScroll: true});
|
|
491
509
|
|
|
492
510
|
// Emit after update
|
|
493
511
|
this.updateComplete.then(() => {
|
|
@@ -526,7 +544,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
526
544
|
}
|
|
527
545
|
|
|
528
546
|
// Set focus after updating so the value is announced by screen readers
|
|
529
|
-
this.updateComplete.then(() => this.displayInput.focus({
|
|
547
|
+
this.updateComplete.then(() => this.displayInput.focus({preventScroll: true}));
|
|
530
548
|
|
|
531
549
|
if (this.value !== oldValue) {
|
|
532
550
|
// Emit after updating
|
|
@@ -538,7 +556,11 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
538
556
|
|
|
539
557
|
if (!this.multiple) {
|
|
540
558
|
this.hide();
|
|
541
|
-
this.displayInput.focus({
|
|
559
|
+
this.displayInput.focus({preventScroll: true});
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (this.triggerSubmit) {
|
|
563
|
+
this.formControlController.submit();
|
|
542
564
|
}
|
|
543
565
|
}
|
|
544
566
|
}
|
|
@@ -745,9 +767,11 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
745
767
|
conditionalSelect.dispatchEvent(new Event('zn-input'));
|
|
746
768
|
});
|
|
747
769
|
}
|
|
770
|
+
|
|
771
|
+
this.updateHasInputPrefix();
|
|
748
772
|
}
|
|
749
773
|
|
|
750
|
-
@watch('disabled', {
|
|
774
|
+
@watch('disabled', {waitUntilFirstUpdate: true})
|
|
751
775
|
handleDisabledChange() {
|
|
752
776
|
// Close the listbox when the control is disabled
|
|
753
777
|
if (this.disabled) {
|
|
@@ -768,7 +792,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
768
792
|
}
|
|
769
793
|
}
|
|
770
794
|
|
|
771
|
-
@watch(['defaultValue', 'value'], {
|
|
795
|
+
@watch(['defaultValue', 'value'], {waitUntilFirstUpdate: true})
|
|
772
796
|
handleValueChange() {
|
|
773
797
|
if (!this.valueHasChanged) {
|
|
774
798
|
const cachedValueHasChanged = this.valueHasChanged;
|
|
@@ -784,7 +808,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
784
808
|
this.setSelectedOptions(allOptions.filter(el => value.includes(el.value)));
|
|
785
809
|
}
|
|
786
810
|
|
|
787
|
-
@watch('open', {
|
|
811
|
+
@watch('open', {waitUntilFirstUpdate: true})
|
|
788
812
|
async handleOpenChange() {
|
|
789
813
|
if (this.open && !this.disabled) {
|
|
790
814
|
// Reset the current option
|
|
@@ -803,7 +827,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
803
827
|
this.setCurrentOption(this.currentOption);
|
|
804
828
|
});
|
|
805
829
|
|
|
806
|
-
const {
|
|
830
|
+
const {keyframes, options} = getAnimation(this, 'select.show', {dir: this.localize.dir()});
|
|
807
831
|
await animateTo(this.popup.popup, keyframes, options);
|
|
808
832
|
|
|
809
833
|
// Make sure the current option is scrolled into view (required for Safari)
|
|
@@ -818,7 +842,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
818
842
|
this.removeOpenListeners();
|
|
819
843
|
|
|
820
844
|
await stopAnimations(this);
|
|
821
|
-
const {
|
|
845
|
+
const {keyframes, options} = getAnimation(this, 'select.hide', {dir: this.localize.dir()});
|
|
822
846
|
await animateTo(this.popup.popup, keyframes, options);
|
|
823
847
|
this.listbox.hidden = true;
|
|
824
848
|
this.popup.active = false;
|
|
@@ -942,7 +966,8 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
942
966
|
'select--bottom': this.placement === 'bottom',
|
|
943
967
|
'select--small': this.size === 'small',
|
|
944
968
|
'select--medium': this.size === 'medium',
|
|
945
|
-
'select--large': this.size === 'large'
|
|
969
|
+
'select--large': this.size === 'large',
|
|
970
|
+
'select--has-input-prefix': this.inputPrefix
|
|
946
971
|
})}
|
|
947
972
|
placement=${this.placement}
|
|
948
973
|
strategy=${this.hoist ? 'fixed' : 'absolute'}
|
|
@@ -957,7 +982,10 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
957
982
|
slot="anchor"
|
|
958
983
|
@keydown=${this.handleComboboxKeyDown}
|
|
959
984
|
@mousedown=${this.handleComboboxMouseDown}>
|
|
960
|
-
<slot part="prefix"
|
|
985
|
+
<slot part="prefix"
|
|
986
|
+
name="prefix"
|
|
987
|
+
class="select__prefix"
|
|
988
|
+
@slotchange=${() => this.updateHasInputPrefix()}></slot>
|
|
961
989
|
|
|
962
990
|
<input
|
|
963
991
|
part="display-input"
|
|
@@ -1049,16 +1077,16 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
1049
1077
|
|
|
1050
1078
|
setDefaultAnimation('select.show', {
|
|
1051
1079
|
keyframes: [
|
|
1052
|
-
{
|
|
1053
|
-
{
|
|
1080
|
+
{opacity: 0, scale: 0.9},
|
|
1081
|
+
{opacity: 1, scale: 1}
|
|
1054
1082
|
],
|
|
1055
|
-
options: {
|
|
1083
|
+
options: {duration: 100, easing: 'ease'}
|
|
1056
1084
|
});
|
|
1057
1085
|
|
|
1058
1086
|
setDefaultAnimation('select.hide', {
|
|
1059
1087
|
keyframes: [
|
|
1060
|
-
{
|
|
1061
|
-
{
|
|
1088
|
+
{opacity: 1, scale: 1},
|
|
1089
|
+
{opacity: 0, scale: 0.9}
|
|
1062
1090
|
],
|
|
1063
|
-
options: {
|
|
1091
|
+
options: {duration: 100, easing: 'ease'}
|
|
1064
1092
|
});
|
|
@@ -48,6 +48,14 @@
|
|
|
48
48
|
var(--zn-transition-fast) background-color;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
/* Prefix area: allow a leading control (e.g., checkbox) full-height */
|
|
52
|
+
.select__prefix {
|
|
53
|
+
display: flex;
|
|
54
|
+
align-items: center;
|
|
55
|
+
align-self: stretch;
|
|
56
|
+
height: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
.select__display-input {
|
|
52
60
|
position: relative;
|
|
53
61
|
width: 100%;
|
|
@@ -175,6 +183,10 @@
|
|
|
175
183
|
padding-inline: var(--zn-input-spacing-medium);
|
|
176
184
|
}
|
|
177
185
|
|
|
186
|
+
.select--has-input-prefix.select--medium .select__combobox {
|
|
187
|
+
padding-inline-start: 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
178
190
|
.select--medium .select__clear {
|
|
179
191
|
margin-inline-start: var(--zn-input-spacing-medium);
|
|
180
192
|
}
|
|
@@ -200,6 +212,10 @@
|
|
|
200
212
|
padding-inline: var(--zn-input-spacing-large);
|
|
201
213
|
}
|
|
202
214
|
|
|
215
|
+
.select--has-input-prefix.select--large .select__combobox {
|
|
216
|
+
padding-inline-start: 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
203
219
|
.select--large .select__clear {
|
|
204
220
|
margin-inline-start: var(--zn-input-spacing-large);
|
|
205
221
|
}
|
|
@@ -241,6 +257,11 @@
|
|
|
241
257
|
color: var(--zn-input-icon-color);
|
|
242
258
|
}
|
|
243
259
|
|
|
260
|
+
/* When a checkbox is used in the prefix, remove left padding so the prefix joins flush */
|
|
261
|
+
.select--has-input-prefix.select--standard .select__combobox {
|
|
262
|
+
padding-inline-start: 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
244
265
|
/* Clear button */
|
|
245
266
|
.select__clear {
|
|
246
267
|
display: inline-flex;
|
|
@@ -20,7 +20,7 @@ export default class ZnStyle extends ZincElement {
|
|
|
20
20
|
@property({type: Boolean}) primary = false;
|
|
21
21
|
@property({type: Boolean}) accent = false;
|
|
22
22
|
@property({type: Boolean}) center = false;
|
|
23
|
-
@property({type: String}) display =
|
|
23
|
+
@property({type: String}) display = null;
|
|
24
24
|
@property() font = '';
|
|
25
25
|
@property() width = '';
|
|
26
26
|
@property() height = '';
|
package/src/zinc.ts
CHANGED
|
@@ -82,6 +82,7 @@ export {default as FilterWrapper} from './components/filter-wrapper';
|
|
|
82
82
|
export {default as SettingsContainer} from './components/settings-container';
|
|
83
83
|
export { default as FilterContainer } from './components/filter-container';
|
|
84
84
|
export { default as Reveal } from './components/reveal';
|
|
85
|
+
export { default as AudioSelect } from './components/audio-select';
|
|
85
86
|
/* plop:component */
|
|
86
87
|
|
|
87
88
|
// Base Component
|