jb-select 6.5.0 → 7.0.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/lib/jb-select.css CHANGED
@@ -1,151 +1,61 @@
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
 
123
24
  .label-wrapper {
124
25
  label {
26
+
27
+
125
28
  width: 100%;
126
- margin: 4px 0px;
29
+ margin: var(--label-margin);
127
30
  display: block;
128
- font-size: var(--jb-select-label-font-size, 0.8em);
129
- font-weight: var(--jb-select-label-font-weight, normal);
31
+ font-size: var(--label-font-size);
130
32
  color: var(--label-color);
33
+
34
+ font-weight: var(--jb-input-label-font-weight, 300);
131
35
 
132
36
  &.--hide {
133
37
  display: none;
134
38
  }
135
39
  }
40
+ }
136
41
 
137
- .close-button {
138
- display: none;
42
+ &:focus-within .select-box {
43
+
44
+ @media(--tablet-from) {
45
+ /*when there is focus on whole select means menu is open so we change select styles*/
46
+ border-color: var(--border-color);
47
+ border-bottom-color: transparent;
48
+ border-radius: var(--rounded) var(--rounded) 0 0;
139
49
  }
140
50
  }
141
51
 
142
52
  .select-box {
143
53
  width: 100%;
144
54
  box-sizing: border-box;
145
- height: var(--jb-select-height, 2.5rem);
55
+ height: var(--height);
146
56
  border: solid var(--border-width) var(--border-color);
147
57
  border-bottom: solid var(--border-bottom-width) var(--border-color);
148
- border-radius: var(--border-radius);
58
+ border-radius: var(--box-border-radius);
149
59
  background-color: var(--select-box-bg-color);
150
60
  margin: var(--jb-select-select-box-margin, 4px 0px 0px 0px);
151
61
  overflow: hidden;
@@ -154,16 +64,6 @@
154
64
  gap: 0.5rem;
155
65
  align-items: center;
156
66
 
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
67
  .start-section {
168
68
  height: 100%;
169
69
  width: auto;
@@ -219,17 +119,11 @@
219
119
  overflow: hidden;
220
120
  z-index: 2;
221
121
 
222
- input {
223
- border: none;
224
- width: 100%;
225
- box-sizing: border-box;
122
+ .search-input {
226
123
  height: 100%;
227
124
  background-color: transparent;
228
125
  padding: 2px 12px 0 12px;
229
126
  display: block;
230
- font-family: inherit;
231
- font-size: var(--jb-select-value-font-size, 1.1rem);
232
- color: var(--value-color);
233
127
  margin: 0;
234
128
  border-radius: 0;
235
129
 
@@ -246,9 +140,20 @@
246
140
  }
247
141
 
248
142
  .end-section {
143
+ display: flex;
144
+ gap: 1.5rem;
145
+ align-items: center;
146
+
249
147
  .arrow-icon {
250
148
  margin: var(--jb-select-arrow-icon-margin, 0 0 0 0);
251
149
  }
150
+
151
+ .clear-button {
152
+ /*show when there is value*/
153
+ display: none;
154
+ --jb-button-padding-xs: 0;
155
+ --jb-button-height-xs: 1rem;
156
+ }
252
157
  }
253
158
 
254
159
 
@@ -260,92 +165,114 @@
260
165
 
261
166
  }
262
167
 
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
168
  .message-box {
275
- font-size: var(--jb-select-message-font-size, 0.7em);
276
- font-weight: var(--jb-select-message-font-weight, normal);
277
- padding: 4px 8px;
169
+ font-size: var(--message-font-size);
170
+ padding: 0.125rem var(--inline-space);
278
171
  color: var(--message-color);
279
-
172
+ display: var(--jb-select-message-box-display, block);
280
173
  &:empty {
281
174
  padding: 0;
282
175
  }
283
-
284
- &.--error {
285
- color: red;
286
- }
287
176
  }
288
177
 
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);
178
+ .popover-wrapper {
179
+ position: relative;
304
180
 
305
- &.--show {
306
- display: block;
307
- }
181
+ .select-list-wrapper {
182
+ @media(--tablet-from) {
183
+ width: 100%;
184
+ --jb-popover-border-radius: var(--list-border-radius);
185
+ --jb-popover-bg-color: var(--select-box-bg-color);
186
+ --jb-popover-top: 0;
187
+ }
308
188
 
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;
189
+ &::part(content) {
190
+
191
+ @media(--tablet-from) {
192
+ /*in desktop*/
193
+ border: solid var(--border-width) var(--border-color);
194
+ border-bottom: solid var(--border-bottom-width) var(--border-color);
195
+ border-top: none;
317
196
  }
318
197
  }
319
198
 
199
+ .mobile-search-input-wrapper {
200
+ display: none;
201
+
202
+ @media(--tablet-until) {
203
+ display: block;
204
+ margin-block-end: 1rem;
205
+ margin-inline: 0.75rem;
206
+
207
+ .search-input {
208
+ background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
209
+ border-radius: var(--box-border-radius);
210
+ width: 100%;
211
+ height: var(--height);
212
+ }
213
+ }
320
214
 
321
- @media(--tablet-until) {
322
- max-height: calc(var(--mobile-modal-height) - 15rem);
323
215
  }
324
216
 
325
- /* option style places */
326
217
 
327
- &::-webkit-scrollbar {
328
- width: 9px;
329
- background-color: transparent;
330
- }
218
+ .select-list {
219
+ width: 100%;
220
+ max-height: var(--jb-select-list-max-height, 400px);
221
+ overflow-y: auto;
222
+
223
+ slot {
224
+ padding: var(--jb-select-list-padding, 16px 0);
225
+
226
+ &:empty {
227
+ padding: 0;
228
+ }
229
+ }
230
+
231
+ /* option style places */
331
232
 
332
- &::-webkit-scrollbar-thumb {
333
- background-color: var(--list-scroll-color);
334
- border-radius: var(--jb-select-list-scroll-border-radius, 4px);
233
+ &::-webkit-scrollbar {
234
+ width: 9px;
235
+ background-color: transparent;
236
+ }
237
+
238
+ &::-webkit-scrollbar-thumb {
239
+ background-color: var(--list-scroll-color);
240
+ border-radius: var(--jb-select-list-scroll-border-radius, 4px);
241
+ }
335
242
  }
336
- }
337
243
 
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;
244
+ .empty-list-placeholder {
245
+ display: none;
246
+ text-align: center;
247
+ color: var(--empty-list-placeholder-color);
248
+ font-style: italic;
249
+ padding: 8px 0;
344
250
 
345
- &.--show {
346
- display: block;
251
+ &.--show {
252
+ display: block;
253
+ }
347
254
  }
255
+
348
256
  }
257
+ }
349
258
 
259
+ .search-input {
260
+ border: none;
261
+ width: 100%;
262
+ box-sizing: border-box;
263
+ padding: 2px 12px 0 12px;
264
+ display: block;
265
+ font-family: inherit;
266
+ font-size: var(--jb-select-value-font-size, 1.1rem);
267
+ color: var(--value-color);
268
+
269
+ &:focus {
270
+ outline: none;
271
+ }
272
+
273
+ &::placeholder {
274
+ color: var(--placeholder-color);
275
+ font-size: var(--jb-select-placeholder-font-size, 1.1em);
276
+ }
350
277
  }
351
278
  }
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>