jb-select 7.2.1 → 7.3.0
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 +94 -16
- 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
|
}
|
|
@@ -503,6 +519,8 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
503
519
|
const event = createKeyboardEvent("keypress", e, {})
|
|
504
520
|
this.dispatchEvent(event);
|
|
505
521
|
}
|
|
522
|
+
|
|
523
|
+
|
|
506
524
|
#onInputBeforeInput(_e: InputEvent) {
|
|
507
525
|
// const inputtedText = e.data || "";
|
|
508
526
|
//TODO: add cancelable event dispatch here
|
|
@@ -526,9 +544,60 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
526
544
|
//because on keypress dont receive backspace key press
|
|
527
545
|
this.#handleSelectedValueDisplay(inputText);
|
|
528
546
|
}
|
|
529
|
-
|
|
547
|
+
switch (e.key) {
|
|
548
|
+
case "ArrowUp":
|
|
549
|
+
this.#activePrevOption();
|
|
550
|
+
break;
|
|
551
|
+
case "ArrowDown":
|
|
552
|
+
this.#activeNextOption();
|
|
553
|
+
break;
|
|
554
|
+
case "Enter":
|
|
555
|
+
this.#optionList.forEach(x => {
|
|
556
|
+
if (x.active) {x.toggleOption();}
|
|
557
|
+
})
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
530
560
|
this.#triggerOnInputKeyup(e);
|
|
531
561
|
}
|
|
562
|
+
/**
|
|
563
|
+
* used when change activeItem with arrow keys
|
|
564
|
+
*/
|
|
565
|
+
#activePrevOption() {
|
|
566
|
+
const optionList = this.optionListWithOrder;
|
|
567
|
+
const activeOption = optionList.find((option, index) => {
|
|
568
|
+
if (option.active) {
|
|
569
|
+
if (optionList[index - 1]) {
|
|
570
|
+
option.active = false;
|
|
571
|
+
optionList[index - 1].active = true;
|
|
572
|
+
optionList[index - 1].scrollIntoView({ block: "nearest" });
|
|
573
|
+
}
|
|
574
|
+
return true;
|
|
575
|
+
}
|
|
576
|
+
return false
|
|
577
|
+
});
|
|
578
|
+
if (!activeOption && optionList[optionList.length - 1]) {
|
|
579
|
+
optionList[optionList.length - 1].active = true;
|
|
580
|
+
optionList[optionList.length - 1].scrollIntoView({ block: "nearest" });
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* used when change activeItem with arrow keys
|
|
585
|
+
*/
|
|
586
|
+
#activeNextOption() {
|
|
587
|
+
const optionList = this.optionListWithOrder;
|
|
588
|
+
const activeOption = optionList.find((option, index) => {
|
|
589
|
+
if (option.active) {
|
|
590
|
+
if (optionList[index + 1]) {
|
|
591
|
+
option.active = false;
|
|
592
|
+
optionList[index + 1].active = true;
|
|
593
|
+
optionList[index + 1].scrollIntoView({ block: "nearest" });
|
|
594
|
+
}
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
return false
|
|
598
|
+
});
|
|
599
|
+
if (!activeOption && optionList[0]) { optionList[0].active = true; optionList[0].scrollIntoView({ block: "nearest" }) }
|
|
600
|
+
}
|
|
532
601
|
#handleSelectedValueDisplay(inputValue: string) {
|
|
533
602
|
if (inputValue !== "") {
|
|
534
603
|
this.elements.selectedValueWrapper.classList.add("--search-typed");
|
|
@@ -599,6 +668,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
599
668
|
}
|
|
600
669
|
}
|
|
601
670
|
this.elements.input.blur();
|
|
671
|
+
this.#optionList.forEach(x => { x.active = false })
|
|
602
672
|
}
|
|
603
673
|
#showOptionList() {
|
|
604
674
|
this.#internals.states.add("open")
|
|
@@ -637,13 +707,13 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
637
707
|
target.selected = false;
|
|
638
708
|
this.#selectedOptions.delete(e.target as JBOptionWebComponent<TValue>)
|
|
639
709
|
this.#updateSelectedOptionDom();
|
|
640
|
-
if(Array.isArray(this.#value)){
|
|
710
|
+
if (Array.isArray(this.#value)) {
|
|
641
711
|
const index = this.#value.indexOf(target.value);
|
|
642
|
-
if(index !== -1) this.#value.splice(index,1);
|
|
643
|
-
}else if(this.value === target.value){
|
|
712
|
+
if (index !== -1) this.#value.splice(index, 1);
|
|
713
|
+
} else if (this.value === target.value) {
|
|
644
714
|
this.#value = null;
|
|
645
715
|
}
|
|
646
|
-
this.#value=this.#value
|
|
716
|
+
this.#value = this.#value
|
|
647
717
|
this.#checkValidity(true);
|
|
648
718
|
}
|
|
649
719
|
//called when an jb-Option connected to the dom
|
|
@@ -657,6 +727,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
657
727
|
this.#setValueOnOptionListChanged();
|
|
658
728
|
}
|
|
659
729
|
this.#updateListEmptyPlaceholder();
|
|
730
|
+
target.addEventListener("mouseenter",this.#onOptionHover)
|
|
660
731
|
}
|
|
661
732
|
#onOptionDisconnected(e: CustomEvent) {
|
|
662
733
|
e.stopPropagation();
|
|
@@ -666,14 +737,21 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
666
737
|
if (target.value == this.#value) {
|
|
667
738
|
this.#setValueOnOptionListChanged();
|
|
668
739
|
}
|
|
740
|
+
target.removeEventListener("mouseenter",this.#onOptionHover)
|
|
741
|
+
}
|
|
742
|
+
#onOptionHover = (e:MouseEvent)=>{
|
|
743
|
+
const target = e.target as JBOptionWebComponent<TValue>;
|
|
744
|
+
if(!target.active){
|
|
745
|
+
this.#optionList.forEach(x=>{x.active = false});
|
|
746
|
+
}
|
|
747
|
+
target.active = true;
|
|
669
748
|
}
|
|
670
|
-
|
|
671
749
|
#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
|
|
750
|
+
if (this.multiple) {
|
|
751
|
+
if (Array.isArray(this.#value)) {
|
|
752
|
+
value = [...this.#value, value] as TValue
|
|
753
|
+
} else {
|
|
754
|
+
value = [this.#value, value] as TValue
|
|
677
755
|
}
|
|
678
756
|
}
|
|
679
757
|
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.0",
|
|
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": {
|