jb-select 7.2.0 → 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 -10
- 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 +100 -8
- 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")
|
|
@@ -636,7 +706,14 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
636
706
|
//this only works on multi mode
|
|
637
707
|
target.selected = false;
|
|
638
708
|
this.#selectedOptions.delete(e.target as JBOptionWebComponent<TValue>)
|
|
639
|
-
this.#updateSelectedOptionDom()
|
|
709
|
+
this.#updateSelectedOptionDom();
|
|
710
|
+
if (Array.isArray(this.#value)) {
|
|
711
|
+
const index = this.#value.indexOf(target.value);
|
|
712
|
+
if (index !== -1) this.#value.splice(index, 1);
|
|
713
|
+
} else if (this.value === target.value) {
|
|
714
|
+
this.#value = null;
|
|
715
|
+
}
|
|
716
|
+
this.#value = this.#value
|
|
640
717
|
this.#checkValidity(true);
|
|
641
718
|
}
|
|
642
719
|
//called when an jb-Option connected to the dom
|
|
@@ -650,6 +727,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
650
727
|
this.#setValueOnOptionListChanged();
|
|
651
728
|
}
|
|
652
729
|
this.#updateListEmptyPlaceholder();
|
|
730
|
+
target.addEventListener("mouseenter",this.#onOptionHover)
|
|
653
731
|
}
|
|
654
732
|
#onOptionDisconnected(e: CustomEvent) {
|
|
655
733
|
e.stopPropagation();
|
|
@@ -659,9 +737,23 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
|
|
|
659
737
|
if (target.value == this.#value) {
|
|
660
738
|
this.#setValueOnOptionListChanged();
|
|
661
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;
|
|
662
748
|
}
|
|
663
|
-
|
|
664
749
|
#selectOption(value: TValue, optionDom: JBOptionWebComponent<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
|
|
755
|
+
}
|
|
756
|
+
}
|
|
665
757
|
this.#setValue(value, optionDom);
|
|
666
758
|
this.#checkValidity(true);
|
|
667
759
|
}
|
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": {
|