jb-select 6.5.0 → 7.0.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/lib/jb-select.css CHANGED
@@ -1,122 +1,23 @@
1
1
  /* @use "~jb-core/styles/medias.scss" as *; */
2
2
 
3
3
  @custom-media --tablet-until (max-width: 768px);
4
+ @custom-media --tablet-from (min-width: 769px);
4
5
 
5
6
  .jb-select-web-component {
6
7
  width: var(--jb-select-width, 100%);
7
8
  margin: var(--jb-select-margin, 0 0);
8
- position: relative;
9
9
  box-sizing: border-box;
10
10
 
11
- &.--focused {
12
- @media(--tablet-until) {
13
- position: fixed;
14
- bottom: 0;
15
- top: initial;
16
- left: 0;
17
- background-color: var(--overlay-bg-color);
18
- width: 100vw;
19
- height: var(--mobile-modal-height);
20
- border-radius: var(--jb-select-mobile-modal-border-radius, 0) var(--jb-select-mobile-modal-border-radius, 0) 0 0;
21
- margin: 0;
22
- padding: 16px 8px;
23
- z-index: var(--mobile-modal-z-index);
24
- }
25
-
26
- .select-box {
27
- @media(--tablet-until) {
28
- height: var(--jb-select-mobile-search-input-height, var(--jb-select-height, 40px));
29
- background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
30
- border-width: var(--jb-select-mobile-search-border-width, var(--border-width));
31
- border-color: var(--jb-select-mobile-search-border-color, var(--border-color));
32
- border-bottom-width: var(--jb-select-mobile-search-border-bottom-width, var(--border-bottom-width));
33
- border-bottom-color: var(--jb-select-mobile-search-border-bottom-color, var(--jb-select-border-bottom-color, var(--border-color)));
34
- border-radius: var(--jb-select-mobile-search-border-radius, var(--border-radius));
35
- }
36
-
37
- .front-box {
38
- .arrow-icon {
39
- @media(--tablet-until) {
40
- display: none;
41
- }
42
- }
43
- }
44
-
45
- .selected-value-wrapper {
46
- @media(--tablet-until) {
47
- opacity: 0;
48
- transition: none;
49
- }
50
-
51
- .selected-value {}
52
- }
53
- }
54
-
55
- .middle-divider {
56
- display: block;
57
-
58
- @media(--tablet-until) {
59
- margin: var(--jb-select-middle-div-mobile-margin, 16px 0 0 0);
60
- }
61
- }
62
-
63
- .select-list-wrapper {
64
- @media(--tablet-until) {
65
- position: initial;
66
- margin: var(--jb-select-mobile-item-list-margin, 16px 0);
67
- border-radius: var(--jb-select-mobile-item-list-border-radius, var(--border-radius));
68
- }
69
- }
70
-
71
- .label-wrapper {
72
- @media(--tablet-until) {
73
- display: flex;
74
- }
75
-
76
- label {
77
- @media(--tablet-until) {
78
- color: var(--modal-label-color);
79
- font-size: 1.5em;
80
- display: flex;
81
- align-items: center;
82
- }
83
- }
84
-
85
- .close-button {
86
- display: none;
87
-
88
- @media(--tablet-until) {
89
- display: flex;
90
- width: 48px;
91
- height: 48px;
92
- justify-content: center;
93
- align-items: center;
94
- color: var(--modal-close-color);
95
-
96
- .close-btn-svg-bg {
97
- opacity: var(--jb-select-close-bg-opacity, 0.4);
98
- fill: var(--close-bg-color);
99
- }
100
-
101
- .close-btn-svg-path {
102
- fill: var(--modal-close-color);
103
- }
104
- }
105
- }
106
- }
107
- }
108
-
109
11
  &.--has-value {
110
12
 
111
- /*if user select a option and value is setted and not null*/
13
+ /*if user select a option and value is set and not null*/
112
14
  .select-box {
113
15
  border-color: var(--jb-select-border-color-selected, var(--border-color));
114
16
  background-color: var(--jb-select-bgcolor-selected, var(--select-box-bg-color));
115
- @media(--tablet-until) {
116
- &:focus-within {
117
- background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
118
- }
119
- }
17
+ }
18
+
19
+ .select-box .end-section .clear-button {
20
+ display: block;
120
21
  }
121
22
  }
122
23
 
@@ -133,19 +34,25 @@
133
34
  display: none;
134
35
  }
135
36
  }
37
+ }
38
+
39
+ &:focus-within .select-box {
136
40
 
137
- .close-button {
138
- display: none;
41
+ @media(--tablet-from) {
42
+ /*when there is focus on whole select means menu is open so we change select styles*/
43
+ border-color: var(--border-color);
44
+ border-bottom-color: transparent;
45
+ border-radius: var(--rounded) var(--rounded) 0 0;
139
46
  }
140
47
  }
141
48
 
142
49
  .select-box {
143
50
  width: 100%;
144
51
  box-sizing: border-box;
145
- height: var(--jb-select-height, 2.5rem);
52
+ height: var(--height);
146
53
  border: solid var(--border-width) var(--border-color);
147
54
  border-bottom: solid var(--border-bottom-width) var(--border-color);
148
- border-radius: var(--border-radius);
55
+ border-radius: var(--box-border-radius);
149
56
  background-color: var(--select-box-bg-color);
150
57
  margin: var(--jb-select-select-box-margin, 4px 0px 0px 0px);
151
58
  overflow: hidden;
@@ -154,16 +61,6 @@
154
61
  gap: 0.5rem;
155
62
  align-items: center;
156
63
 
157
- &:focus-within {
158
- border-color: var(--jb-select-border-color, var(--border-color));
159
- border-bottom-color: var(--jb-select-border-color, var(--border-color));
160
- border-radius: var(--border-radius) var(--border-radius) 0 0;
161
-
162
- @media(--tablet-until) {
163
- border-radius: var(--jb-select-mobile-search-border-radius, var(--border-radius));
164
- }
165
- }
166
-
167
64
  .start-section {
168
65
  height: 100%;
169
66
  width: auto;
@@ -219,17 +116,11 @@
219
116
  overflow: hidden;
220
117
  z-index: 2;
221
118
 
222
- input {
223
- border: none;
224
- width: 100%;
225
- box-sizing: border-box;
119
+ .search-input {
226
120
  height: 100%;
227
121
  background-color: transparent;
228
122
  padding: 2px 12px 0 12px;
229
123
  display: block;
230
- font-family: inherit;
231
- font-size: var(--jb-select-value-font-size, 1.1rem);
232
- color: var(--value-color);
233
124
  margin: 0;
234
125
  border-radius: 0;
235
126
 
@@ -246,9 +137,20 @@
246
137
  }
247
138
 
248
139
  .end-section {
140
+ display: flex;
141
+ gap: 1.5rem;
142
+ align-items: center;
143
+
249
144
  .arrow-icon {
250
145
  margin: var(--jb-select-arrow-icon-margin, 0 0 0 0);
251
146
  }
147
+
148
+ .clear-button {
149
+ /*show when there is value*/
150
+ display: none;
151
+ --jb-button-padding-xs: 0;
152
+ --jb-button-height-xs: 1rem;
153
+ }
252
154
  }
253
155
 
254
156
 
@@ -260,17 +162,6 @@
260
162
 
261
163
  }
262
164
 
263
- .middle-divider {
264
- display: none;
265
- position: relative;
266
- z-index: calc(var(--base-z-index) + 3);
267
- width: 100%;
268
- height: var(--middle-div-height);
269
- background-color: var(--jb-select-middle-div-color, var(--border-color));
270
- margin: var(--jb-select-middle-div-margin, calc(-1 * var(--border-bottom-width)) 0);
271
- border-radius: var(--jb-select-middle-div-radius, 0px);
272
- }
273
-
274
165
  .message-box {
275
166
  font-size: var(--jb-select-message-font-size, 0.7em);
276
167
  font-weight: var(--jb-select-message-font-weight, normal);
@@ -286,66 +177,103 @@
286
177
  }
287
178
  }
288
179
 
289
- .select-list-wrapper {
290
- display: none;
291
- position: absolute;
292
- margin: calc(-1 * var(--border-bottom-width)) 0;
293
- height: auto;
294
- overflow: hidden;
295
- width: 100%;
296
- background-color: var(--select-box-bg-color);
297
- border-radius: 0 0 var(--border-radius) var(--border-radius);
298
- border: solid var(--jb-select-list-border-width, 1px) var(--border-color);
299
- border-top: none;
300
- border-bottom: solid var(--border-bottom-width) var(--border-color);
301
- box-shadow: var(--jb-select-list-box-shadow);
302
- box-sizing: border-box;
303
- z-index: calc(var(--base-z-index) + 2);
180
+ .popover-wrapper {
181
+ position: relative;
182
+ .select-list-wrapper {
183
+ @media(--tablet-from) {
184
+ width: 100%;
185
+ --jb-popover-border-radius: var(--list-border-radius);
186
+ --jb-popover-bg-color: var(--select-box-bg-color);
187
+ --jb-popover-top: 0;
188
+ }
304
189
 
305
- &.--show {
306
- display: block;
307
- }
190
+ &::part(content) {
308
191
 
309
- .select-list {
310
- width: 100%;
311
- max-height: var(--jb-select-list-max-height, 400px);
312
- overflow-y: auto;
313
- slot {
314
- padding: var(--jb-select-list-padding, 16px 0);
315
- &:empty {
316
- padding: 0;
192
+ @media(--tablet-from) {
193
+ /*in desktop*/
194
+ border: solid var(--border-width) var(--border-color);
195
+ border-bottom: solid var(--border-bottom-width) var(--border-color);
196
+ border-top: none;
317
197
  }
318
198
  }
319
199
 
200
+ .mobile-search-input-wrapper {
201
+ display: none;
202
+
203
+ @media(--tablet-until) {
204
+ display: block;
205
+ margin-block-end: 1rem;
206
+ margin-inline: 0.75rem;
207
+
208
+ .search-input {
209
+ background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
210
+ border-radius: var(--box-border-radius);
211
+ width: 100%;
212
+ height: var(--height);
213
+ }
214
+ }
320
215
 
321
- @media(--tablet-until) {
322
- max-height: calc(var(--mobile-modal-height) - 15rem);
323
216
  }
324
217
 
325
- /* option style places */
326
218
 
327
- &::-webkit-scrollbar {
328
- width: 9px;
329
- background-color: transparent;
330
- }
219
+ .select-list {
220
+ width: 100%;
221
+ max-height: var(--jb-select-list-max-height, 400px);
222
+ overflow-y: auto;
223
+
224
+ slot {
225
+ padding: var(--jb-select-list-padding, 16px 0);
226
+
227
+ &:empty {
228
+ padding: 0;
229
+ }
230
+ }
231
+
232
+ /* option style places */
233
+
234
+ &::-webkit-scrollbar {
235
+ width: 9px;
236
+ background-color: transparent;
237
+ }
331
238
 
332
- &::-webkit-scrollbar-thumb {
333
- background-color: var(--list-scroll-color);
334
- border-radius: var(--jb-select-list-scroll-border-radius, 4px);
239
+ &::-webkit-scrollbar-thumb {
240
+ background-color: var(--list-scroll-color);
241
+ border-radius: var(--jb-select-list-scroll-border-radius, 4px);
242
+ }
335
243
  }
336
- }
337
244
 
338
- .empty-list-placeholder {
339
- display: none;
340
- text-align: center;
341
- color: var(--empty-list-placeholder-color);
342
- font-style: italic;
343
- padding: 8px 0;
245
+ .empty-list-placeholder {
246
+ display: none;
247
+ text-align: center;
248
+ color: var(--empty-list-placeholder-color);
249
+ font-style: italic;
250
+ padding: 8px 0;
344
251
 
345
- &.--show {
346
- display: block;
252
+ &.--show {
253
+ display: block;
254
+ }
347
255
  }
256
+
348
257
  }
258
+ }
349
259
 
260
+ .search-input {
261
+ border: none;
262
+ width: 100%;
263
+ box-sizing: border-box;
264
+ padding: 2px 12px 0 12px;
265
+ display: block;
266
+ font-family: inherit;
267
+ font-size: var(--jb-select-value-font-size, 1.1rem);
268
+ color: var(--value-color);
269
+
270
+ &:focus {
271
+ outline: none;
272
+ }
273
+
274
+ &::placeholder {
275
+ color: var(--placeholder-color);
276
+ font-size: var(--jb-select-placeholder-font-size, 1.1em);
277
+ }
350
278
  }
351
279
  }
package/lib/jb-select.ts CHANGED
@@ -1,25 +1,31 @@
1
+ import "jb-button";
2
+ import "jb-popover";
1
3
  import CSS from "./jb-select.css";
2
4
  import VariablesCSS from "./variables.css";
3
- import {
5
+ import type {
4
6
  JBSelectCallbacks,
5
7
  JBSelectElements,
6
8
  ValidationValue,
7
9
  } from "./types";
8
- import { ShowValidationErrorParameters, ValidationHelper, type ValidationItem, type ValidationResult, type WithValidation } from "jb-validation";
10
+ import { type ShowValidationErrorParameters, ValidationHelper, type ValidationItem, type ValidationResult, type WithValidation } from "jb-validation";
9
11
  import { isMobile } from "jb-core";
10
- import { JBFormInputStandards } from 'jb-form';
12
+ import type { JBFormInputStandards } from 'jb-form';
11
13
  // eslint-disable-next-line no-duplicate-imports
12
14
  import { JBOptionWebComponent } from "./jb-option/jb-option";
13
15
  import { registerDefaultVariables } from 'jb-core/theme';
14
16
  import { renderHTML } from "./render";
15
17
  import { dictionary } from "./i18n";
16
18
  import { i18n } from "jb-core/i18n";
19
+ import type { JBButtonWebComponent } from "jb-button";
17
20
 
21
+ //TODO: add clean button to empty the select box after value selection
18
22
  //TODO: add IncludeInputInList or freeSolo so user can select item that he wrote without even it exist in select list
19
23
  //TODO: handleHomeEndKeys to move focus inside the popup with the Home and End keys.
20
24
  /**
21
25
  * TValue is the type of value we extract from option
22
26
  */
27
+
28
+ // biome-ignore lint/suspicious/noExplicitAny: <we support any type of value and there is no limitation on value type>
23
29
  export class JBSelectWebComponent<TValue = any> extends HTMLElement implements WithValidation<ValidationValue<TValue>>, JBFormInputStandards<TValue> {
24
30
  static get formAssociated() {
25
31
  return true;
@@ -124,7 +130,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
124
130
  #required = false;
125
131
  set required(value: boolean) {
126
132
  this.#required = value;
127
- this.#internals.ariaRequired = value?"true":"false";
133
+ this.#internals.ariaRequired = value ? "true" : "false";
128
134
  this.#validation.checkValiditySync({ showError: false });
129
135
  }
130
136
  get required() {
@@ -150,6 +156,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
150
156
  if (typeof this.attachInternals == "function") {
151
157
  //some browser dont support attachInternals
152
158
  this.#internals = this.attachInternals();
159
+ this.#internals.role = "combobox"
153
160
  }
154
161
  this.#initWebComponent();
155
162
  this.#initProp();
@@ -173,29 +180,45 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
173
180
  delegatesFocus: true,
174
181
  });
175
182
  registerDefaultVariables();
176
- const html = `<style>${CSS} ${VariablesCSS}</style>` + "\n" + renderHTML();
183
+ const html = `<style>${CSS} ${VariablesCSS}</style>\n${renderHTML()}`;
177
184
  const element = document.createElement("template");
178
185
  element.innerHTML = html;
179
186
  shadowRoot.appendChild(element.content.cloneNode(true));
180
187
  this.elements = {
181
- input: shadowRoot.querySelector(".select-box input")!,
188
+ input: shadowRoot.querySelector(".search-input")!,
182
189
  componentWrapper: shadowRoot.querySelector(".jb-select-web-component")!,
183
- selectedValueWrapper: shadowRoot.querySelector(
184
- ".selected-value-wrapper"
185
- )!,
190
+ selectedValueWrapper: shadowRoot.querySelector(".selected-value-wrapper")!,
186
191
  messageBox: shadowRoot.querySelector(".message-box")!,
187
192
  optionList: shadowRoot.querySelector(".select-list")!,
188
193
  optionListWrapper: shadowRoot.querySelector(".select-list-wrapper")!,
189
194
  optionListSlot: shadowRoot.querySelector(".select-list-wrapper .select-list slot")!,
190
195
  arrowIcon: shadowRoot.querySelector(".arrow-icon")!,
196
+ clearButton: shadowRoot.querySelector(".clear-button") as JBButtonWebComponent,
191
197
  label: {
192
198
  wrapper: shadowRoot.querySelector("label")!,
193
199
  text: shadowRoot.querySelector("label .label-value")!,
194
200
  },
195
201
  emptyListPlaceholder: shadowRoot.querySelector(".empty-list-placeholder")!,
202
+ mobileSearchInputWrapper: shadowRoot.querySelector(".mobile-search-input-wrapper"),
203
+ frontBox: shadowRoot.querySelector(".front-box"),
196
204
  };
197
205
  this.#registerEventListener();
198
206
  this.#updateListEmptyPlaceholder();
207
+ this.#setupDeviceRelates();
208
+ }
209
+ /**
210
+ * place code that change on select resize between mobile & desktop
211
+ */
212
+ #setupDeviceRelates() {
213
+ const onResize = ()=> {
214
+ if (isMobile()) {
215
+ this.elements.mobileSearchInputWrapper.appendChild(this.elements.input)
216
+ } else {
217
+ this.elements.frontBox.appendChild(this.elements.input);
218
+ }
219
+ }
220
+ addEventListener("resize", onResize);
221
+ onResize();
199
222
  }
200
223
  #registerEventListener() {
201
224
  this.elements.input.addEventListener("change", (e: Event) => {
@@ -205,9 +228,10 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
205
228
  this.elements.input.addEventListener("keyup", this.#onInputKeyup.bind(this));
206
229
  this.elements.input.addEventListener("beforeinput", this.#onInputBeforeInput.bind(this));
207
230
  this.elements.input.addEventListener("input", (e) => { this.#onInputInput(e as unknown as InputEvent); });
208
- this.elements.input.addEventListener("focus", this.#onInputFocus.bind(this));
231
+ this.addEventListener("focus", this.#onSelectFocus.bind(this));
209
232
  this.elements.input.addEventListener("blur", this.#onInputBlur.bind(this));
210
233
  this.elements.arrowIcon.addEventListener("click", this.#onArrowKeyClick.bind(this));
234
+ this.elements.clearButton.addEventListener("click", this.#onClearButtonClick.bind(this));
211
235
  //events to work with options
212
236
  this.addEventListener("select", this.#onOptionSelect.bind(this));
213
237
  this.addEventListener("jb-option-connected", this.#onOptionConnected.bind(this));
@@ -230,7 +254,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
230
254
  "error",
231
255
  ];
232
256
  }
233
- attributeChangedCallback(name: string, oldValue: string, newValue: string) {
257
+ attributeChangedCallback(name: string, _oldValue: string, newValue: string) {
234
258
  // do something when an attribute has changed
235
259
  this.#onAttributeChange(name, newValue);
236
260
  }
@@ -288,12 +312,12 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
288
312
  }
289
313
  #setValueOnOptionListChanged() {
290
314
  //when option list changed we see if current value is valid for new optionlist we set it if not we reset value to null.
291
- //in some scenario value is setted before optionList attached so we store it on this.#notFoundedValue and after option list setted we set value from this.#notFoundedValue
315
+ //in some scenario value is set before optionList attached so we store it on this.#notFoundedValue and after option list set we set value from this.#notFoundedValue
292
316
  if (this.#notFoundedValue) {
293
317
  //if select has no prev value or pending not found value we don't set it because user may input some search terms in input box and developer-user update list base on that value
294
318
  //if we set it to null the search term and this.textValue will become null and empty too and it make impossible for user to search in dynamic back-end provided searchable list so we put this condition to prevent it
295
- const isSetted = this.#setValueFromOutside(this.#notFoundedValue);
296
- if (isSetted) {
319
+ const isSet = this.#setValueFromOutside(this.#notFoundedValue);
320
+ if (isSet) {
297
321
  //after list update and when not founded value is found in new option list we clear old not founded value
298
322
  this.#notFoundedValue = null;
299
323
  }
@@ -324,7 +348,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
324
348
  }
325
349
  //null option mean deselect all
326
350
  #changeSelectedOption(option: JBOptionWebComponent<TValue> | null) {
327
- this.#optionList.forEach((x) => x.selected = false);
351
+ this.#optionList.forEach((x) => { x.selected = false });
328
352
  if (option) {
329
353
  option.selected = true;
330
354
  this.#selectedOption = option;
@@ -363,6 +387,13 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
363
387
  this.focus();
364
388
  }
365
389
  }
390
+ #onClearButtonClick(e:MouseEvent) {
391
+ e.stopPropagation();
392
+ e.preventDefault();
393
+ this.#setValue(null,null);
394
+ this.#checkValidity(true);
395
+ this.#dispatchOnChangeEvent();
396
+ }
366
397
  #onInputKeyPress(e: KeyboardEvent) {
367
398
  const eventOptions: KeyboardEventInit = {
368
399
  altKey: e.altKey,
@@ -383,7 +414,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
383
414
  const event = new KeyboardEvent("keypress", eventOptions);
384
415
  this.dispatchEvent(event);
385
416
  }
386
- #onInputBeforeInput(e: InputEvent) {
417
+ #onInputBeforeInput(_e: InputEvent) {
387
418
  // const inputtedText = e.data || "";
388
419
  //TODO: add cancelable event dispatch here
389
420
  }
@@ -453,6 +484,9 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
453
484
  //here is the rare time we update _text_value directly because we want trigger event that may read value directly from dom
454
485
  this.#textValue = inputText;
455
486
  }
487
+ #onSelectFocus() {
488
+ this.focus();
489
+ }
456
490
  #onInputFocus() {
457
491
  this.focus();
458
492
  }
@@ -470,13 +504,14 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
470
504
  focus() {
471
505
  this.elements.input.focus();
472
506
  this.#showOptionList();
473
- this.elements.componentWrapper.classList.add("--focused");
507
+ this.elements.optionListWrapper.open();
474
508
  if (this.isMobileDevice) {
475
509
  this.elements.input.placeholder = this.#searchPlaceholder;
476
510
  }
477
511
  }
478
512
  blur() {
479
- this.elements.componentWrapper.classList.remove("--focused");
513
+ // this.elements.componentWrapper.classList.remove("--focused");
514
+ this.elements.optionListWrapper.close();
480
515
  this.textValue = "";
481
516
  this.#handleSelectedValueDisplay("");
482
517
  this.#hideOptionList();
@@ -599,7 +634,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
599
634
  }
600
635
  if (this.required) {
601
636
  const label = this.getAttribute("label") || "";
602
- const message = dictionary.get(i18n,"requireMessage")(label || null);
637
+ const message = dictionary.get(i18n, "requireMessage")(label || null);
603
638
  validationList.push({
604
639
  validator: ({ value }) => {
605
640
  return value !== null && value !== undefined;
package/lib/render.ts CHANGED
@@ -1,18 +1,8 @@
1
1
  export function renderHTML(): string {
2
- return /* html */ `
2
+ return /* html */ `
3
3
  <div class="jb-select-web-component">
4
4
  <div class="label-wrapper">
5
5
  <label class="--hide"><span class="label-value"></span></label>
6
- <!-- close button will be visible on mobile modal -->
7
- <div class="close-button">
8
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
9
- <path class="close-btn-svg-bg" opacity="0.4"
10
- d="M16.3399 1.9998H7.66988C4.27988 1.9998 1.99988 4.3798 1.99988 7.9198V16.0898C1.99988 19.6198 4.27988 21.9998 7.66988 21.9998H16.3399C19.7299 21.9998 21.9999 19.6198 21.9999 16.0898V7.9198C21.9999 4.3798 19.7299 1.9998 16.3399 1.9998Z" />
11
- <path class="close-btn-svg-path"
12
- d="M15.0156 13.7703L13.2366 11.9923L15.0146 10.2143C15.3566 9.8733 15.3566 9.3183 15.0146 8.9773C14.6726 8.6333 14.1196 8.6343 13.7776 8.9763L11.9986 10.7543L10.2196 8.9743C9.87758 8.6323 9.32358 8.6343 8.98158 8.9743C8.64058 9.3163 8.64058 9.8713 8.98158 10.2123L10.7616 11.9923L8.98558 13.7673C8.64358 14.1093 8.64358 14.6643 8.98558 15.0043C9.15658 15.1763 9.37958 15.2613 9.60358 15.2613C9.82858 15.2613 10.0516 15.1763 10.2226 15.0053L11.9986 13.2293L13.7786 15.0083C13.9496 15.1793 14.1726 15.2643 14.3966 15.2643C14.6206 15.2643 14.8446 15.1783 15.0156 15.0083C15.3576 14.6663 15.3576 14.1123 15.0156 13.7703Z"
13
- fill="#200E32" />
14
- </svg>
15
- </div>
16
6
  </div>
17
7
  <div class="select-box">
18
8
  <div class="start-section">
@@ -21,11 +11,16 @@ export function renderHTML(): string {
21
11
  <div class="middle-section">
22
12
  <div class="selected-value-wrapper"></div>
23
13
  <div class="front-box">
24
- <input class="input" />
25
-
14
+ <input class="search-input" />
26
15
  </div>
27
16
  </div>
28
17
  <div class="end-section">
18
+ <jb-button class="clear-button" color="dark" variant="ghost" size="xs">
19
+ <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
20
+ <path d="M2.11183 24C1.57504 24 1.03826 23.8023 0.614479 23.3786C-0.204826 22.5596 -0.204826 21.2039 0.614479 20.3848L20.3908 0.614298C21.2101 -0.204766 22.5662 -0.204766 23.3855 0.614298C24.2048 1.43336 24.2048 2.78905 23.3855 3.60811L3.60918 23.3786C3.1854 23.8023 2.64861 24 2.11183 24Z" fill="currentColor"/>
21
+ <path d="M21.8882 24C21.3514 24 20.8146 23.8023 20.3908 23.3786L0.614479 3.60811C-0.204826 2.78905 -0.204826 1.43336 0.614479 0.614298C1.43378 -0.204766 2.78987 -0.204766 3.60918 0.614298L23.3855 20.3848C24.2048 21.2039 24.2048 22.5596 23.3855 23.3786C22.9617 23.8023 22.425 24 21.8882 24Z" fill="currentColor"/>
22
+ </svg>
23
+ </jb-button>
29
24
  <div class="arrow-icon" tabindex="-1">
30
25
  <slot name="select-arrow-icon">
31
26
  <svg width='8' height='8' id='Layer_1' x='0px' y='0px' viewBox='0 0 494.1 371.1'
@@ -37,16 +32,18 @@ export function renderHTML(): string {
37
32
  </div>
38
33
  </div>
39
34
  </div>
40
- <div class="middle-divider">
41
- <!-- middle line between input box and list (hidden by default but user may need it sometimes) -->
42
- </div>
43
- <div class="select-list-wrapper">
44
- <div class="select-list" tabindex="-1">
45
- <slot></slot>
46
- </div>
47
- <div class="empty-list-placeholder">
48
- <slot name="empty-list-message">no item available</slot>
49
- </div>
35
+ <div class="popover-wrapper">
36
+ <jb-popover class="select-list-wrapper">
37
+ <div class="mobile-search-input-wrapper">
38
+ <!-- Here we put search input in Mobile -->
39
+ </div>
40
+ <div class="select-list" tabindex="-1" role="listbox">
41
+ <slot></slot>
42
+ </div>
43
+ <div class="empty-list-placeholder">
44
+ <slot name="empty-list-message">no item available</slot>
45
+ </div>
46
+ </jb-popover>
50
47
  </div>
51
48
  <div class="message-box"></div>
52
49
  </div>
package/lib/types.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import type { JBOptionWebComponent } from "./jb-option/jb-option";
2
2
  import type {EventTypeWithTarget} from "jb-core";
3
3
  import type{ JBSelectWebComponent } from "./jb-select";
4
+ import type {JBButtonWebComponent} from "jb-button";
5
+ import type { JBPopoverWebComponent } from "jb-popover";
4
6
  export type JBSelectCallbacks<TValue> = {
5
7
  getSelectedValueDOM?:(value:TValue,content:HTMLElement) => HTMLElement;
6
8
  }
@@ -11,14 +13,17 @@ export type JBSelectElements = {
11
13
  selectedValueWrapper: HTMLDivElement,
12
14
  messageBox:HTMLDivElement,
13
15
  optionList: HTMLDivElement,
14
- optionListWrapper: HTMLDivElement,
16
+ optionListWrapper: JBPopoverWebComponent,
15
17
  optionListSlot:HTMLSlotElement,
16
18
  arrowIcon: HTMLDivElement,
19
+ clearButton: JBButtonWebComponent,
17
20
  label:{
18
21
  wrapper: HTMLLabelElement,
19
22
  text: HTMLSpanElement
20
23
  },
21
24
  emptyListPlaceholder: HTMLDivElement,
25
+ mobileSearchInputWrapper:HTMLDivElement,
26
+ frontBox:HTMLDivElement
22
27
  }
23
28
  export type ValidationValue<TValue> = {
24
29
  selectedOption:JBOptionWebComponent<TValue> | null,