jb-select 7.2.1 → 7.3.1
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/README.md +4 -4
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.br +0 -0
- package/dist/index.cjs.js.gz +0 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.br +0 -0
- package/dist/index.umd.js.gz +0 -0
- package/dist/index.umd.js.map +1 -1
- package/dist/jb-option/jb-option.d.ts +7 -0
- package/dist/jb-option/jb-option.d.ts.map +1 -1
- package/dist/jb-option-list/jb-option-list.d.ts +2 -0
- package/dist/jb-option-list/jb-option-list.d.ts.map +1 -1
- package/dist/jb-select.d.ts +5 -0
- package/dist/jb-select.d.ts.map +1 -1
- package/lib/jb-option/jb-option.css +10 -9
- package/lib/jb-option/jb-option.ts +22 -1
- package/lib/jb-option/variables.css +10 -3
- package/lib/jb-option-list/jb-option-list.ts +3 -0
- package/lib/jb-select.css +1 -0
- package/lib/jb-select.ts +101 -19
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JBSelectWebComponent } from '../jb-select';
|
|
2
2
|
import CSS from './jb-option.css';
|
|
3
|
+
import CSSVariable from './variables.css';
|
|
3
4
|
import { renderHTML } from "./render";
|
|
4
5
|
import type { JBOptionElements } from "./types";
|
|
5
6
|
import { removeCheckboxNodes } from './utils';
|
|
@@ -104,7 +105,7 @@ export class JBOptionWebComponent<TValue> extends HTMLElement {
|
|
|
104
105
|
mode: "open",
|
|
105
106
|
serializable: true
|
|
106
107
|
});
|
|
107
|
-
const html = `<style>${CSS}</style>\n${renderHTML()}`;
|
|
108
|
+
const html = `<style>${CSSVariable} \n ${CSS}</style>\n${renderHTML()}`;
|
|
108
109
|
const element = document.createElement("template");
|
|
109
110
|
element.innerHTML = html;
|
|
110
111
|
shadowRoot.appendChild(element.content.cloneNode(true));
|
|
@@ -139,6 +140,7 @@ export class JBOptionWebComponent<TValue> extends HTMLElement {
|
|
|
139
140
|
this.#value = value as TValue;
|
|
140
141
|
}
|
|
141
142
|
}
|
|
143
|
+
|
|
142
144
|
#onOptionClick() {
|
|
143
145
|
if (this.#isChangeCalled) {
|
|
144
146
|
this.#isChangeCalled = false;
|
|
@@ -158,6 +160,13 @@ export class JBOptionWebComponent<TValue> extends HTMLElement {
|
|
|
158
160
|
}
|
|
159
161
|
}
|
|
160
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* @public
|
|
165
|
+
* this function used by jb-select to toggle option when it active and user hit enter to select or deselect option
|
|
166
|
+
*/
|
|
167
|
+
toggleOption(){
|
|
168
|
+
this.#onOptionClick();
|
|
169
|
+
}
|
|
161
170
|
#dispatchSelectEvent() {
|
|
162
171
|
const event = new Event("select", { bubbles: true, cancelable: false, composed: true });
|
|
163
172
|
this.dispatchEvent(event);
|
|
@@ -183,6 +192,18 @@ export class JBOptionWebComponent<TValue> extends HTMLElement {
|
|
|
183
192
|
}
|
|
184
193
|
}
|
|
185
194
|
}
|
|
195
|
+
#active = false;
|
|
196
|
+
get active(){
|
|
197
|
+
return this.#active;
|
|
198
|
+
}
|
|
199
|
+
set active(value:boolean){
|
|
200
|
+
this.#active = value;
|
|
201
|
+
if(value){
|
|
202
|
+
this.#internals?.states.add("active");
|
|
203
|
+
}else{
|
|
204
|
+
this.#internals?.states.delete("active");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
186
207
|
|
|
187
208
|
}
|
|
188
209
|
const myElementNotExists = !customElements.get("jb-option");
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
:host{
|
|
2
|
-
|
|
3
|
-
--
|
|
4
|
-
--
|
|
2
|
+
/*Sizes*/
|
|
3
|
+
--border-radius:var(--jb-option-border-radius, 0);
|
|
4
|
+
--padding: var(--jb-option-padding, 0.5rem 1rem);
|
|
5
|
+
--font-size: var(--jb-option-font-size, 0.9rem);
|
|
6
|
+
--min-height: var(--jb-option-min-height, 2.25rem);
|
|
7
|
+
/*Colors*/
|
|
8
|
+
--color: var(--jb-option-color, inherit);
|
|
9
|
+
--color-active: var(--jb-option-color-active, var(--jb-option-color, inherit));
|
|
10
|
+
--background-color:var(--jb-option-background-color, transparent);
|
|
11
|
+
--background-color-active:var(--jb-option-background-color-active, var(--jb-primary-subtle));
|
|
5
12
|
}
|
|
@@ -23,6 +23,9 @@ export class JBOptionListWebComponent<TOption, TValue> extends HTMLElement {
|
|
|
23
23
|
this.#optionList = value;
|
|
24
24
|
this.#initOptionList(value);
|
|
25
25
|
}
|
|
26
|
+
get optionListDom(){
|
|
27
|
+
return Array.from(this.#optionPairMap.values());
|
|
28
|
+
}
|
|
26
29
|
constructor() {
|
|
27
30
|
super();
|
|
28
31
|
this.#initWebComponent();
|
package/lib/jb-select.css
CHANGED
package/lib/jb-select.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { dictionary } from "./i18n";
|
|
|
19
19
|
import { i18n } from "jb-core/i18n";
|
|
20
20
|
import type { JBButtonWebComponent } from "jb-button";
|
|
21
21
|
import { JBPopoverWebComponent } from "jb-popover";
|
|
22
|
+
import { JBOptionListWebComponent } from "./jb-option-list/jb-option-list";
|
|
22
23
|
|
|
23
24
|
//TODO: add IncludeInputInList or freeSolo so user can select item that he wrote without even it exist in select list
|
|
24
25
|
//TODO: handleHomeEndKeys to move focus inside the popup with the Home and End keys.
|
|
@@ -57,6 +58,21 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
57
58
|
if (value === undefined) return;
|
|
58
59
|
this.#popoverPosition = value;
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* this is a expensive option list please use it when you really need optionList with order
|
|
63
|
+
*/
|
|
64
|
+
get optionListWithOrder(): JBOptionWebComponent<TValue>[] {
|
|
65
|
+
const elements = this.elements.optionListSlot.assignedElements();
|
|
66
|
+
const optionList = elements.flatMap(x => {
|
|
67
|
+
// extract option list from JBOptionList to make option list flat by index
|
|
68
|
+
if (x instanceof JBOptionListWebComponent) {
|
|
69
|
+
return x.optionListDom;
|
|
70
|
+
} else {
|
|
71
|
+
return x
|
|
72
|
+
}
|
|
73
|
+
}).filter(x => (x instanceof JBOptionWebComponent && !x.hidden));
|
|
74
|
+
return optionList as JBOptionWebComponent<TValue>[];
|
|
75
|
+
}
|
|
60
76
|
get multiple() {
|
|
61
77
|
return this.hasAttribute('multiple')
|
|
62
78
|
}
|
|
@@ -379,15 +395,15 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
379
395
|
} else if (this.value) {
|
|
380
396
|
this.#setValueFromOutside(this.value);
|
|
381
397
|
}
|
|
382
|
-
if (this.multiple && Array.isArray(this.#value) && this.#selectedOptions.values.length< this.#value.length) {
|
|
398
|
+
if (this.multiple && Array.isArray(this.#value) && this.#selectedOptions.values.length < this.#value.length) {
|
|
383
399
|
//in this particular edge case our value is already set but some option maybe missing in first place and added later
|
|
384
|
-
const missing:JBOptionWebComponent<TValue>[] = [];
|
|
385
|
-
this.#optionList.forEach((op)=>{
|
|
386
|
-
if(op.selected == false && (this.#value as unknown[]).includes(op.value)){
|
|
400
|
+
const missing: JBOptionWebComponent<TValue>[] = [];
|
|
401
|
+
this.#optionList.forEach((op) => {
|
|
402
|
+
if (op.selected == false && (this.#value as unknown[]).includes(op.value)) {
|
|
387
403
|
missing.push(op);
|
|
388
404
|
}
|
|
389
405
|
});
|
|
390
|
-
if(missing.length>0){
|
|
406
|
+
if (missing.length > 0) {
|
|
391
407
|
this.#setSelectedOption(missing);
|
|
392
408
|
}
|
|
393
409
|
}
|
|
@@ -463,7 +479,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
463
479
|
this.#notFoundedValue = null;
|
|
464
480
|
this.#value = value;
|
|
465
481
|
if (value === null || value === undefined || (Array.isArray(value) && value.length === 0)) {
|
|
466
|
-
this.textValue = "";
|
|
482
|
+
if(!this.multiple){this.textValue = "";}
|
|
467
483
|
this.#updateSelectedOptionDom();
|
|
468
484
|
//will deselect all option
|
|
469
485
|
this.#setSelectedOption(null);
|
|
@@ -473,7 +489,9 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
473
489
|
this.elements.input.placeholder = this.placeholder;
|
|
474
490
|
}
|
|
475
491
|
} else {
|
|
476
|
-
|
|
492
|
+
|
|
493
|
+
if(!this.multiple){this.textValue = "";}
|
|
494
|
+
//for typescript error
|
|
477
495
|
Array.isArray(option) ? this.#setSelectedOption(option) : this.#setSelectedOption(option);
|
|
478
496
|
this.#updateSelectedOptionDom();
|
|
479
497
|
this.elements.componentWrapper.classList.add("--has-value");
|
|
@@ -483,7 +501,9 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
483
501
|
}
|
|
484
502
|
}
|
|
485
503
|
//if user select an option we rest filter so user see all option again when open a select
|
|
486
|
-
this
|
|
504
|
+
if(!this.multiple){
|
|
505
|
+
this.#updateOptionList("");
|
|
506
|
+
}
|
|
487
507
|
}
|
|
488
508
|
#onArrowKeyClick() {
|
|
489
509
|
if (this.isOpen) {
|
|
@@ -503,6 +523,8 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
503
523
|
const event = createKeyboardEvent("keypress", e, {})
|
|
504
524
|
this.dispatchEvent(event);
|
|
505
525
|
}
|
|
526
|
+
|
|
527
|
+
|
|
506
528
|
#onInputBeforeInput(_e: InputEvent) {
|
|
507
529
|
// const inputtedText = e.data || "";
|
|
508
530
|
//TODO: add cancelable event dispatch here
|
|
@@ -526,9 +548,60 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
526
548
|
//because on keypress dont receive backspace key press
|
|
527
549
|
this.#handleSelectedValueDisplay(inputText);
|
|
528
550
|
}
|
|
529
|
-
|
|
551
|
+
switch (e.key) {
|
|
552
|
+
case "ArrowUp":
|
|
553
|
+
this.#activePrevOption();
|
|
554
|
+
break;
|
|
555
|
+
case "ArrowDown":
|
|
556
|
+
this.#activeNextOption();
|
|
557
|
+
break;
|
|
558
|
+
case "Enter":
|
|
559
|
+
this.#optionList.forEach(x => {
|
|
560
|
+
if (x.active) {x.toggleOption();}
|
|
561
|
+
})
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
530
564
|
this.#triggerOnInputKeyup(e);
|
|
531
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* used when change activeItem with arrow keys
|
|
568
|
+
*/
|
|
569
|
+
#activePrevOption() {
|
|
570
|
+
const optionList = this.optionListWithOrder;
|
|
571
|
+
const activeOption = optionList.find((option, index) => {
|
|
572
|
+
if (option.active) {
|
|
573
|
+
if (optionList[index - 1]) {
|
|
574
|
+
option.active = false;
|
|
575
|
+
optionList[index - 1].active = true;
|
|
576
|
+
optionList[index - 1].scrollIntoView({ block: "nearest" });
|
|
577
|
+
}
|
|
578
|
+
return true;
|
|
579
|
+
}
|
|
580
|
+
return false
|
|
581
|
+
});
|
|
582
|
+
if (!activeOption && optionList[optionList.length - 1]) {
|
|
583
|
+
optionList[optionList.length - 1].active = true;
|
|
584
|
+
optionList[optionList.length - 1].scrollIntoView({ block: "nearest" });
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* used when change activeItem with arrow keys
|
|
589
|
+
*/
|
|
590
|
+
#activeNextOption() {
|
|
591
|
+
const optionList = this.optionListWithOrder;
|
|
592
|
+
const activeOption = optionList.find((option, index) => {
|
|
593
|
+
if (option.active) {
|
|
594
|
+
if (optionList[index + 1]) {
|
|
595
|
+
option.active = false;
|
|
596
|
+
optionList[index + 1].active = true;
|
|
597
|
+
optionList[index + 1].scrollIntoView({ block: "nearest" });
|
|
598
|
+
}
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
return false
|
|
602
|
+
});
|
|
603
|
+
if (!activeOption && optionList[0]) { optionList[0].active = true; optionList[0].scrollIntoView({ block: "nearest" }) }
|
|
604
|
+
}
|
|
532
605
|
#handleSelectedValueDisplay(inputValue: string) {
|
|
533
606
|
if (inputValue !== "") {
|
|
534
607
|
this.elements.selectedValueWrapper.classList.add("--search-typed");
|
|
@@ -599,6 +672,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
599
672
|
}
|
|
600
673
|
}
|
|
601
674
|
this.elements.input.blur();
|
|
675
|
+
this.#optionList.forEach(x => { x.active = false })
|
|
602
676
|
}
|
|
603
677
|
#showOptionList() {
|
|
604
678
|
this.#internals.states.add("open")
|
|
@@ -637,13 +711,13 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
637
711
|
target.selected = false;
|
|
638
712
|
this.#selectedOptions.delete(e.target as JBOptionWebComponent<TValue>)
|
|
639
713
|
this.#updateSelectedOptionDom();
|
|
640
|
-
if(Array.isArray(this.#value)){
|
|
714
|
+
if (Array.isArray(this.#value)) {
|
|
641
715
|
const index = this.#value.indexOf(target.value);
|
|
642
|
-
if(index !== -1) this.#value.splice(index,1);
|
|
643
|
-
}else if(this.value === target.value){
|
|
716
|
+
if (index !== -1) this.#value.splice(index, 1);
|
|
717
|
+
} else if (this.value === target.value) {
|
|
644
718
|
this.#value = null;
|
|
645
719
|
}
|
|
646
|
-
this.#value=this.#value
|
|
720
|
+
this.#value = this.#value
|
|
647
721
|
this.#checkValidity(true);
|
|
648
722
|
}
|
|
649
723
|
//called when an jb-Option connected to the dom
|
|
@@ -657,6 +731,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
657
731
|
this.#setValueOnOptionListChanged();
|
|
658
732
|
}
|
|
659
733
|
this.#updateListEmptyPlaceholder();
|
|
734
|
+
target.addEventListener("mouseenter",this.#onOptionHover)
|
|
660
735
|
}
|
|
661
736
|
#onOptionDisconnected(e: CustomEvent) {
|
|
662
737
|
e.stopPropagation();
|
|
@@ -666,14 +741,21 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
666
741
|
if (target.value == this.#value) {
|
|
667
742
|
this.#setValueOnOptionListChanged();
|
|
668
743
|
}
|
|
744
|
+
target.removeEventListener("mouseenter",this.#onOptionHover)
|
|
745
|
+
}
|
|
746
|
+
#onOptionHover = (e:MouseEvent)=>{
|
|
747
|
+
const target = e.target as JBOptionWebComponent<TValue>;
|
|
748
|
+
if(!target.active){
|
|
749
|
+
this.#optionList.forEach(x=>{x.active = false});
|
|
750
|
+
}
|
|
751
|
+
target.active = true;
|
|
669
752
|
}
|
|
670
|
-
|
|
671
753
|
#selectOption(value: TValue, optionDom: JBOptionWebComponent<TValue>) {
|
|
672
|
-
if(this.multiple){
|
|
673
|
-
if(Array.isArray(this.#value)){
|
|
674
|
-
value = [...this.#value,value] as TValue
|
|
675
|
-
}else{
|
|
676
|
-
value = [this.#value,value] as TValue
|
|
754
|
+
if (this.multiple) {
|
|
755
|
+
if (Array.isArray(this.#value)) {
|
|
756
|
+
value = [...this.#value, value] as TValue
|
|
757
|
+
} else {
|
|
758
|
+
value = [this.#value, value] as TValue
|
|
677
759
|
}
|
|
678
760
|
}
|
|
679
761
|
this.#setValue(value, optionDom);
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"web component",
|
|
17
17
|
"react component"
|
|
18
18
|
],
|
|
19
|
-
"version": "7.
|
|
19
|
+
"version": "7.3.1",
|
|
20
20
|
"bugs": "https://github.com/javadbat/jb-select/issues",
|
|
21
21
|
"homepage": "https://javadbat.github.io/design-system/?path=/story/components-form-elements-jbselect",
|
|
22
22
|
"license": "MIT",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"jb-validation": ">=0.4.0",
|
|
39
39
|
"jb-button": ">=3.9.1",
|
|
40
|
-
"jb-popover": ">=1.
|
|
40
|
+
"jb-popover": ">=1.12.0",
|
|
41
41
|
"jb-core":">=0.27.2"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|