jb-select 6.0.5 → 6.2.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.
Files changed (81) hide show
  1. package/README.md +10 -4
  2. package/dist/index.cjs.js +2 -2
  3. package/dist/index.cjs.js.br +0 -0
  4. package/dist/index.cjs.js.gz +0 -0
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.d.ts +8 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.br +0 -0
  10. package/dist/index.js.gz +0 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.umd.js +2 -2
  13. package/dist/index.umd.js.br +0 -0
  14. package/dist/index.umd.js.gz +0 -0
  15. package/dist/index.umd.js.map +1 -1
  16. package/dist/jb-option/jb-option.d.ts +22 -0
  17. package/dist/jb-option/jb-option.d.ts.map +1 -0
  18. package/dist/jb-option/render.d.ts +2 -0
  19. package/dist/jb-option/render.d.ts.map +1 -0
  20. package/dist/jb-option/types.d.ts +5 -0
  21. package/dist/jb-option/types.d.ts.map +1 -0
  22. package/dist/jb-option-list/jb-option-list.d.ts +11 -0
  23. package/dist/jb-option-list/jb-option-list.d.ts.map +1 -0
  24. package/dist/jb-option-list/types.d.ts +6 -0
  25. package/dist/jb-option-list/types.d.ts.map +1 -0
  26. package/dist/jb-select.d.ts +60 -0
  27. package/dist/jb-select.d.ts.map +1 -0
  28. package/dist/lib/index.d.ts +7 -0
  29. package/dist/lib/jb-option/jb-option.d.ts +21 -0
  30. package/dist/lib/jb-option/render.d.ts +1 -0
  31. package/dist/lib/jb-option/types.d.ts +4 -0
  32. package/dist/lib/jb-option-list/jb-option-list.d.ts +10 -0
  33. package/dist/lib/jb-option-list/types.d.ts +5 -0
  34. package/dist/lib/jb-select.d.ts +59 -0
  35. package/dist/lib/types.d.ts +27 -0
  36. package/dist/types.d.ts +28 -0
  37. package/dist/types.d.ts.map +1 -0
  38. package/dist/web-component/jb-select/lib/jb-select.d.ts +3 -0
  39. package/dist/web-component/jb-select/lib/types.d.ts +4 -1
  40. package/lib/global.d.ts +15 -0
  41. package/lib/jb-option/jb-option.ts +4 -0
  42. package/lib/jb-select.scss +30 -36
  43. package/lib/jb-select.ts +51 -34
  44. package/lib/types.ts +6 -3
  45. package/lib/variables.css +29 -0
  46. package/package.json +9 -4
  47. package/react/README.md +15 -55
  48. package/react/dist/JBOption.d.ts +19 -0
  49. package/react/dist/JBOptionList.d.ts +22 -0
  50. package/react/dist/JBSelect.d.ts +50 -0
  51. package/react/dist/events-hook.d.ts +16 -0
  52. package/react/dist/index.cjs.js +2 -122
  53. package/react/dist/index.cjs.js.map +1 -1
  54. package/react/dist/index.d.ts +3 -0
  55. package/react/dist/index.js +2 -118
  56. package/react/dist/index.js.map +1 -1
  57. package/react/dist/index.umd.js +2 -125
  58. package/react/dist/index.umd.js.map +1 -1
  59. package/react/dist/lib/JBOption.d.ts +19 -0
  60. package/react/dist/lib/JBOptionList.d.ts +22 -0
  61. package/react/dist/lib/JBSelect.d.ts +48 -0
  62. package/react/dist/lib/events-hook.d.ts +16 -0
  63. package/react/dist/lib/index.d.ts +3 -0
  64. package/react/dist/web-component/jb-select/react/lib/JBSelect.d.ts +15 -5
  65. package/react/dist/web-component/jb-select/react/lib/events-hook.d.ts +16 -0
  66. package/react/lib/JBSelect.tsx +12 -24
  67. package/react/lib/events-hook.ts +24 -0
  68. package/react/package.json +1 -1
  69. package/react/tsconfig.json +3 -4
  70. package/dist/jb-select.cjs.js +0 -2
  71. package/dist/jb-select.cjs.js.br +0 -0
  72. package/dist/jb-select.cjs.js.gz +0 -0
  73. package/dist/jb-select.cjs.js.map +0 -1
  74. package/dist/jb-select.js +0 -2
  75. package/dist/jb-select.js.br +0 -0
  76. package/dist/jb-select.js.gz +0 -0
  77. package/dist/jb-select.js.map +0 -1
  78. package/dist/jb-select.umd.js +0 -2
  79. package/dist/jb-select.umd.js.br +0 -0
  80. package/dist/jb-select.umd.js.gz +0 -0
  81. package/dist/jb-select.umd.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ import "./jb-option/jb-option.js";
2
+ import "./jb-option-list/jb-option-list.js";
3
+ import "./jb-select.js";
4
+ export * from './jb-select.js';
5
+ export * from './types.js';
6
+ export * from "./jb-option-list/jb-option-list.js";
7
+ export * from "./jb-option/jb-option.js";
@@ -0,0 +1,21 @@
1
+ import { type JBSelectWebComponent } from '../jb-select';
2
+ export declare class JBOptionWebComponent<TValue> extends HTMLElement {
3
+ #private;
4
+ get value(): TValue;
5
+ set value(value: TValue);
6
+ set selected(value: boolean);
7
+ get selected(): boolean;
8
+ get optionContent(): Node[];
9
+ get hidden(): boolean;
10
+ set hidden(value: boolean);
11
+ /**
12
+ * return text content of option (it used in search by default to filter option)
13
+ */
14
+ get optionContentText(): string;
15
+ constructor();
16
+ connectedCallback(): void;
17
+ setSelectElement(element: JBSelectWebComponent): void;
18
+ disconnectedCallback(): void;
19
+ static get observedAttributes(): string[];
20
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
21
+ }
@@ -0,0 +1 @@
1
+ export declare function renderHTML(): string;
@@ -0,0 +1,4 @@
1
+ export type JBOptionElements = {
2
+ componentWrapper: HTMLDivElement;
3
+ contentWrapper: HTMLDivElement;
4
+ };
@@ -0,0 +1,10 @@
1
+ import { type OptionListCallbacks } from "./types";
2
+ export declare class JBOptionListWebComponent<TOption, TValue> extends HTMLElement {
3
+ #private;
4
+ get callbacks(): OptionListCallbacks<TOption, TValue>;
5
+ get optionList(): TOption[];
6
+ set optionList(value: TOption[]);
7
+ constructor();
8
+ connectedCallback(): void;
9
+ setCallback<T extends keyof OptionListCallbacks<TOption, TValue>>(key: T, callbackFn: OptionListCallbacks<TOption, TValue>[T]): void;
10
+ }
@@ -0,0 +1,5 @@
1
+ export type OptionListCallbacks<TOption, TValue> = {
2
+ getTitle?: (option: TOption) => string;
3
+ getValue?: (option: TOption) => TValue;
4
+ getContentDOM?: ((option: TOption) => HTMLElement);
5
+ };
@@ -0,0 +1,59 @@
1
+ import { JBSelectCallbacks, JBSelectElements, ValidationValue } from "./types";
2
+ import { ShowValidationErrorInput, ValidationHelper, type WithValidation } from "jb-validation";
3
+ import { JBFormInputStandards } from 'jb-form';
4
+ /**
5
+ * TValue is the type of value we extract from option
6
+ */
7
+ export declare class JBSelectWebComponent<TValue = any> extends HTMLElement implements WithValidation<ValidationValue<TValue>>, JBFormInputStandards<TValue> {
8
+ #private;
9
+ static get formAssociated(): boolean;
10
+ callbacks: JBSelectCallbacks<TValue>;
11
+ elements: JBSelectElements;
12
+ get value(): TValue;
13
+ set value(value: TValue);
14
+ get textValue(): string;
15
+ set textValue(value: string);
16
+ get selectedOptionTitle(): string;
17
+ get placeholder(): string;
18
+ set placeholder(value: string);
19
+ get searchPlaceholder(): string;
20
+ set searchPlaceholder(value: string);
21
+ get isMobileDevice(): boolean;
22
+ get isOpen(): boolean;
23
+ get validation(): ValidationHelper<ValidationValue<TValue>>;
24
+ get disabled(): boolean;
25
+ set disabled(value: boolean);
26
+ set required(value: boolean);
27
+ get required(): boolean;
28
+ /**
29
+ * @description will determine if component trigger jb-validation mechanism automatically on user event or it just let user-developer handle validation mechanism by himself
30
+ */
31
+ get isAutoValidationDisabled(): boolean;
32
+ get name(): string;
33
+ initialValue: TValue | null;
34
+ get isDirty(): boolean;
35
+ constructor();
36
+ connectedCallback(): void;
37
+ static get observedAttributes(): string[];
38
+ attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
39
+ focus(): void;
40
+ blur(): void;
41
+ /**
42
+ * @description show given string as a error in message place
43
+ * @public
44
+ */
45
+ showValidationError(error: ShowValidationErrorInput | string): void;
46
+ clearValidationError(): void;
47
+ /**
48
+ * @public
49
+ * @description this method used to check for validity but doesn't show error to user and just return the result
50
+ * this method used by #internal of component
51
+ */
52
+ checkValidity(): boolean;
53
+ /**
54
+ * @public
55
+ * @description this method used to check for validity and show error to user
56
+ */
57
+ reportValidity(): boolean;
58
+ get validationMessage(): string;
59
+ }
@@ -0,0 +1,27 @@
1
+ import type { JBOptionWebComponent } from "./jb-option/jb-option";
2
+ import type { EventTypeWithTarget } from "jb-core";
3
+ import type { JBSelectWebComponent } from "./jb-select";
4
+ export type JBSelectCallbacks<TValue> = {
5
+ getSelectedValueDOM?: (value: TValue, content: HTMLElement) => HTMLElement;
6
+ };
7
+ export type JBSelectElements = {
8
+ input: HTMLInputElement;
9
+ componentWrapper: HTMLDivElement;
10
+ selectedValueWrapper: HTMLDivElement;
11
+ messageBox: HTMLDivElement;
12
+ optionList: HTMLDivElement;
13
+ optionListWrapper: HTMLDivElement;
14
+ optionListSlot: HTMLSlotElement;
15
+ arrowIcon: HTMLDivElement;
16
+ label: {
17
+ wrapper: HTMLLabelElement;
18
+ text: HTMLSpanElement;
19
+ };
20
+ emptyListPlaceholder: HTMLDivElement;
21
+ };
22
+ export type ValidationValue<TValue> = {
23
+ selectedOption: JBOptionWebComponent<TValue> | null;
24
+ value: TValue | null;
25
+ inputtedText: string;
26
+ };
27
+ export type JBSelectEventType<TEvent> = EventTypeWithTarget<TEvent, JBSelectWebComponent>;
@@ -0,0 +1,28 @@
1
+ import type { JBOptionWebComponent } from "./jb-option/jb-option";
2
+ import type { EventTypeWithTarget } from "jb-core";
3
+ import type { JBSelectWebComponent } from "./jb-select";
4
+ export type JBSelectCallbacks<TValue> = {
5
+ getSelectedValueDOM?: (value: TValue, content: HTMLElement) => HTMLElement;
6
+ };
7
+ export type JBSelectElements = {
8
+ input: HTMLInputElement;
9
+ componentWrapper: HTMLDivElement;
10
+ selectedValueWrapper: HTMLDivElement;
11
+ messageBox: HTMLDivElement;
12
+ optionList: HTMLDivElement;
13
+ optionListWrapper: HTMLDivElement;
14
+ optionListSlot: HTMLSlotElement;
15
+ arrowIcon: HTMLDivElement;
16
+ label: {
17
+ wrapper: HTMLLabelElement;
18
+ text: HTMLSpanElement;
19
+ };
20
+ emptyListPlaceholder: HTMLDivElement;
21
+ };
22
+ export type ValidationValue<TValue> = {
23
+ selectedOption: JBOptionWebComponent<TValue> | null;
24
+ value: TValue | null;
25
+ inputtedText: string;
26
+ };
27
+ export type JBSelectEventType<TEvent> = EventTypeWithTarget<TEvent, JBSelectWebComponent>;
28
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,SAAS,CAAC;AACjD,OAAO,KAAI,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvD,MAAM,MAAM,iBAAiB,CAAC,MAAM,IAAI;IACpC,mBAAmB,CAAC,EAAC,CAAC,KAAK,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,KAAK,WAAW,CAAC;CAC1E,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,gBAAgB,CAAC;IACxB,gBAAgB,EAAE,cAAc,CAAC;IACjC,oBAAoB,EAAE,cAAc,CAAC;IACrC,UAAU,EAAC,cAAc,CAAC;IAC1B,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB,EAAE,cAAc,CAAC;IAClC,cAAc,EAAC,eAAe,CAAC;IAC/B,SAAS,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAC;QACF,OAAO,EAAE,gBAAgB,CAAC;QAC1B,IAAI,EAAE,eAAe,CAAA;KACxB,CAAC;IACF,oBAAoB,EAAE,cAAc,CAAC;CACxC,CAAA;AACD,MAAM,MAAM,eAAe,CAAC,MAAM,IAAI;IAClC,cAAc,EAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACnD,KAAK,EAAC,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAC,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,MAAM,IAAI,mBAAmB,CAAC,MAAM,EAAC,oBAAoB,CAAC,CAAA"}
@@ -1,6 +1,9 @@
1
1
  import { JBSelectCallbacks, JBSelectElements, ValidationValue } from "./types";
2
2
  import { ShowValidationErrorInput, ValidationHelper, type WithValidation } from "jb-validation";
3
3
  import { JBFormInputStandards } from 'jb-form';
4
+ /**
5
+ * TValue is the type of value we extract from option
6
+ */
4
7
  export declare class JBSelectWebComponent<TValue = any> extends HTMLElement implements WithValidation<ValidationValue<TValue>>, JBFormInputStandards<TValue> {
5
8
  #private;
6
9
  static get formAssociated(): boolean;
@@ -1,4 +1,6 @@
1
- import { type JBOptionWebComponent } from "./jb-option/jb-option";
1
+ import type { JBOptionWebComponent } from "./jb-option/jb-option";
2
+ import type { EventTypeWithTarget } from "jb-core";
3
+ import type { JBSelectWebComponent } from "./jb-select";
2
4
  export type JBSelectCallbacks<TValue> = {
3
5
  getSelectedValueDOM?: (value: TValue, content: HTMLElement) => HTMLElement;
4
6
  };
@@ -22,3 +24,4 @@ export type ValidationValue<TValue> = {
22
24
  value: TValue | null;
23
25
  inputtedText: string;
24
26
  };
27
+ export type JBSelectEventType<TEvent> = EventTypeWithTarget<TEvent, JBSelectWebComponent>;
@@ -0,0 +1,15 @@
1
+ type FileStringModules = {
2
+ readonly default: string;
3
+ }
4
+ declare module '*.scss' {
5
+ const value: FileStringModules;
6
+ export default value;
7
+ }
8
+ declare module '*.html' {
9
+ const value: FileStringModules;
10
+ export default value.default;
11
+ }
12
+ declare module '*.svg' {
13
+ const value: string;
14
+ export default value;
15
+ }
@@ -4,6 +4,8 @@ import { renderHTML } from "./render";
4
4
  import { JBOptionElements } from "./types";
5
5
 
6
6
  //TODO: check for filter text to set visibility on mount
7
+ //TODO: add disable option (will be displayed but can not be select)
8
+ //TODO: add highlight to highlight the searched value
7
9
  export class JBOptionWebComponent<TValue> extends HTMLElement {
8
10
 
9
11
  #elements: JBOptionElements;
@@ -41,8 +43,10 @@ export class JBOptionWebComponent<TValue> extends HTMLElement {
41
43
  this.#hidden = value;
42
44
  if(value){
43
45
  this.#elements.componentWrapper.classList.add('--hidden');
46
+ this.setAttribute("inert","");
44
47
  }else{
45
48
  this.#elements.componentWrapper.classList.remove('--hidden');
49
+ this.removeAttribute("inert");
46
50
  }
47
51
  }
48
52
  /**
@@ -1,13 +1,8 @@
1
- @use "../../../common/scss/Medias.scss" as *;
1
+ @use "~jb-core/styles/medias.scss" as *;
2
+ @use './variables.css';
2
3
 
3
4
  :host {
4
- //define private variable here
5
- --p-middle-div-height: var(--jb-select-middle-div-height, 0px);
6
- --p-p-color: #1e2832;
7
- --p-border-bottom-width: var(--jb-select-border-bottom-width, var(--jb-select-border-width, 3px));
8
- --p-base-z-index: 1;
9
- --p-mobile-modal-z-index: 900;
10
- --p-mobile-modal-height: var(--jb-select-mobile-modal-height, 100vh);
5
+
11
6
  }
12
7
 
13
8
  .jb-select-web-component {
@@ -22,7 +17,7 @@
22
17
  bottom: 0;
23
18
  top: initial;
24
19
  left: 0;
25
- background-color: var(--jb-select-overlay-bgcolor, #0008);
20
+ background-color: var(--overlay-bg-color);
26
21
  width: 100vw;
27
22
  height: var(--p-mobile-modal-height);
28
23
  border-radius: var(--jb-select-mobile-modal-border-radius, 0) var(--jb-select-mobile-modal-border-radius, 0) 0 0;
@@ -34,12 +29,12 @@
34
29
  .select-box {
35
30
  @include mobile-tablet {
36
31
  height: var(--jb-select-mobile-search-input-height, var(--jb-select-height, 40px));
37
- background-color: var(--jb-select-mobile-input-bgcolor, #f7f6f6);
32
+ background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
38
33
  border-width: var(--jb-select-mobile-search-border-width, var(--jb-select-border-width, 1px));
39
- border-color: var(--jb-select-mobile-search-border-color, var(--jb-select-border-color, #f7f6f6));
34
+ border-color: var(--jb-select-mobile-search-border-color, var(--border-color));
40
35
  border-bottom-width: var(--jb-select-mobile-search-border-bottom-width, var(--p-border-bottom-width));
41
36
  border-bottom-color: var(--jb-select-mobile-search-border-bottom-color,
42
- var(--jb-select-border-bottom-color, var(--jb-select-border-color, #f7f6f6)));
37
+ var(--jb-select-border-bottom-color, var(--border-color)));
43
38
  border-radius: var(--jb-select-mobile-search-border-radius, var(--jb-select-border-radius, 16px));
44
39
  }
45
40
 
@@ -84,7 +79,7 @@
84
79
 
85
80
  label {
86
81
  @include mobile-tablet {
87
- color: #fff;
82
+ color: var(--modal-label-color);
88
83
  font-size: 1.5em;
89
84
  display: flex;
90
85
  align-items: center;
@@ -100,15 +95,15 @@
100
95
  height: 48px;
101
96
  justify-content: center;
102
97
  align-items: center;
103
- color: #fff;
98
+ color: var(--modal-close-color);
104
99
 
105
100
  .close-btn-svg-bg {
106
101
  opacity: var(--jb-select-close-bg-opacity, 0.4);
107
- fill: var(--jb-select-close-bg-color, #1f1735);
102
+ fill: var(--close-bg-color);
108
103
  }
109
104
 
110
105
  .close-btn-svg-path {
111
- fill: var(--jb-select-close-x-color, #fff);
106
+ fill: var(--modal-close-color);
112
107
  }
113
108
  }
114
109
  }
@@ -119,12 +114,11 @@
119
114
 
120
115
  //if user select a option and value is setted and not null
121
116
  .select-box {
122
- border-color: var(--jb-select-border-color-selected, #c3ff14);
123
- background-color: var(--jb-select-bgcolor-selected, #f7f6f6);
124
-
117
+ border-color: var(--jb-select-border-color-selected, var(--border-color));
118
+ background-color: var(--jb-select-bgcolor-selected, var(--select-box-bg-color));
125
119
  @include mobile-tablet {
126
120
  &:focus-within {
127
- background-color: var(--jb-select-mobile-input-bgcolor, #f7f6f6);
121
+ background-color: var(--jb-select-mobile-input-bgcolor, var(--select-box-bg-color));
128
122
  }
129
123
  }
130
124
  }
@@ -137,7 +131,7 @@
137
131
  display: block;
138
132
  font-size: var(--jb-select-label-font-size, 0.8em);
139
133
  font-weight: var(--jb-select-label-font-weight, normal);
140
- color: var(--jb-select-label-color, #1f1735);
134
+ color: var(--label-color);
141
135
 
142
136
  &.--hide {
143
137
  display: none;
@@ -153,10 +147,10 @@
153
147
  width: 100%;
154
148
  box-sizing: border-box;
155
149
  height: var(--jb-select-height, 2.5rem);
156
- border: solid var(--jb-select-border-width, 1px) var(--jb-select-border-color, #f7f6f6);
157
- border-bottom: solid var(--p-border-bottom-width) var(--jb-select-border-color, #f7f6f6);
150
+ border: solid var(--jb-select-border-width, 1px) var(--border-color);
151
+ border-bottom: solid var(--p-border-bottom-width) var(--border-color);
158
152
  border-radius: var(--jb-select-border-radius, 1rem);
159
- background-color: var(--jb-select-bgcolor, #f7f6f6);
153
+ background-color: var(--select-box-bg-color);
160
154
  margin: var(--jb-select-select-box-margin, 4px 0px 0px 0px);
161
155
  overflow: hidden;
162
156
  display: flex;
@@ -165,8 +159,8 @@
165
159
  align-items: center;
166
160
 
167
161
  &:focus-within {
168
- border-color: var(--jb-select-border-color, var(--p-p-color));
169
- border-bottom-color: var(--jb-select-border-color, var(--p-p-color));
162
+ border-color: var(--jb-select-border-color, var(--border-color));
163
+ border-bottom-color: var(--jb-select-border-color, var(--border-color));
170
164
  border-radius: var(--jb-select-border-radius, 1rem) var(--jb-select-border-radius, 1rem) 0 0;
171
165
 
172
166
  @include mobile-tablet {
@@ -211,7 +205,7 @@
211
205
  display: block;
212
206
  font-family: inherit;
213
207
  font-size: var(--jb-select-selected-value-font-size, 1.1em);
214
- color: var(--jb-select-selected-value-color, #1f1735);
208
+ color: var(--value-color);
215
209
  margin: 0;
216
210
  border-radius: 0;
217
211
  display: flex;
@@ -239,7 +233,7 @@
239
233
  display: block;
240
234
  font-family: inherit;
241
235
  font-size: var(--jb-select-value-font-size, 1.1rem);
242
- color: var(--jb-select-input-color, #1f1735);
236
+ color: var(--value-color);
243
237
  margin: 0;
244
238
  border-radius: 0;
245
239
 
@@ -276,7 +270,7 @@
276
270
  z-index: calc(var(--p-base-z-index) + 3);
277
271
  width: 100%;
278
272
  height: var(--p-middle-div-height);
279
- background-color: var(--jb-select-middle-div-color, var(--p-p-color));
273
+ background-color: var(--jb-select-middle-div-color, var(--border-color));
280
274
  margin: var(--jb-select-middle-div-margin, calc(-1 * var(--p-border-bottom-width)) 0);
281
275
  border-radius: var(--jb-select-middle-div-radius, 0px);
282
276
  }
@@ -285,7 +279,7 @@
285
279
  font-size: var(--jb-select-message-font-size, 0.7em);
286
280
  font-weight: var(--jb-select-message-font-weight, normal);
287
281
  padding: 4px 8px;
288
- color: var(--jb-select-message-color, #929292);
282
+ color: var(--message-color);
289
283
 
290
284
  &:empty {
291
285
  padding: 0;
@@ -303,11 +297,11 @@
303
297
  height: auto;
304
298
  overflow: hidden;
305
299
  width: 100%;
306
- background-color: var(--jb-select-bgcolor, #f7f6f6);
300
+ background-color: var(--select-box-bg-color);
307
301
  border-radius: 0 0 var(--jb-select-border-radius, 16px) var(--jb-select-border-radius, 16px);
308
- border: solid var(--jb-select-list-border-width, 1px) var(--jb-select-border-color, var(--p-p-color));
302
+ border: solid var(--jb-select-list-border-width, 1px) var(--border-color);
309
303
  border-top: none;
310
- border-bottom: solid var(--p-border-bottom-width) var(--jb-select-border-color, var(--p-p-color));
304
+ border-bottom: solid var(--p-border-bottom-width) var(--border-color);
311
305
  box-shadow: var(--jb-select-list-box-shadow);
312
306
  box-sizing: border-box;
313
307
  z-index: calc(var(--p-base-z-index) + 2);
@@ -329,7 +323,7 @@
329
323
 
330
324
 
331
325
  @include mobile-tablet {
332
- max-height: calc(var(--p-mobile-modal-height) - 240px);
326
+ max-height: calc(var(--p-mobile-modal-height) - 15rem);
333
327
  }
334
328
 
335
329
  /* option style places */
@@ -340,7 +334,7 @@
340
334
  }
341
335
 
342
336
  &::-webkit-scrollbar-thumb {
343
- background-color: var(--jb-select-list-scroll-color, #c3c3c3);
337
+ background-color: var(--list-scroll-color);
344
338
  border-radius: var(--jb-select-list-scroll-border-radius, 4px);
345
339
  }
346
340
  }
@@ -348,7 +342,7 @@
348
342
  .empty-list-placeholder {
349
343
  display: none;
350
344
  text-align: center;
351
- color: #838383;
345
+ color: var(--empty-list-placeholder-color);
352
346
  font-style: italic;
353
347
  padding: 8px 0;
354
348
 
package/lib/jb-select.ts CHANGED
@@ -5,13 +5,18 @@ import {
5
5
  JBSelectElements,
6
6
  ValidationValue,
7
7
  } from "./types";
8
- import { ShowValidationErrorInput, ValidationHelper, type ValidationItem, type ValidationResult, type WithValidation } from "jb-validation";
9
- import { isMobile } from "../../../common/scripts/device-detection";
8
+ import { ShowValidationErrorParameters, ValidationHelper, type ValidationItem, type ValidationResult, type WithValidation } from "jb-validation";
9
+ import { isMobile } from "jb-core";
10
10
  import { JBFormInputStandards } from 'jb-form';
11
11
  // eslint-disable-next-line no-duplicate-imports
12
12
  import { JBOptionWebComponent } from "./jb-option/jb-option";
13
- // eslint-disable-next-line no-duplicate-imports
14
- //TOption is the type of option, TValue is the type of value we extract from option
13
+ import { defineColors } from 'jb-core/theme';
14
+
15
+ //TODO: add IncludeInputInList or freeSolo so user can select item that he wrote without even it exist in select list
16
+ //TODO: handleHomeEndKeys to move focus inside the popup with the Home and End keys.
17
+ /**
18
+ * TValue is the type of value we extract from option
19
+ */
15
20
  export class JBSelectWebComponent<TValue = any> extends HTMLElement implements WithValidation<ValidationValue<TValue>>, JBFormInputStandards<TValue> {
16
21
  static get formAssociated() {
17
22
  return true;
@@ -160,6 +165,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
160
165
  mode: "open",
161
166
  delegatesFocus: true,
162
167
  });
168
+ defineColors();
163
169
  const html = `<style>${CSS}</style>` + "\n" + HTML;
164
170
  const element = document.createElement("template");
165
171
  element.innerHTML = html;
@@ -198,7 +204,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
198
204
  //events to work with options
199
205
  this.addEventListener("select", this.#onOptionSelect.bind(this));
200
206
  this.addEventListener("jb-option-connected", this.#onOptionConnected.bind(this));
201
- this.elements.optionListSlot.addEventListener("slotchange",this.#onOptionSlotChange.bind(this));
207
+ this.elements.optionListSlot.addEventListener("slotchange", this.#onOptionSlotChange.bind(this));
202
208
 
203
209
  }
204
210
 
@@ -214,6 +220,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
214
220
  "required",
215
221
  "placeholder",
216
222
  "search-placeholder",
223
+ "error",
217
224
  ];
218
225
  }
219
226
  attributeChangedCallback(name: string, oldValue: string, newValue: string) {
@@ -249,20 +256,23 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
249
256
  case "search-placeholder":
250
257
  this.searchPlaceholder = value;
251
258
  break;
259
+ case "error":
260
+ this.reportValidity();
261
+ break;
252
262
  }
253
263
  }
254
264
  /**
255
265
  * will check option list and if select has no option it will show empty list placeholder
256
266
  */
257
- #updateListEmptyPlaceholder(){
258
- const isAnyOptionVisible = Array.from(this.#optionList).some(x=>x.hidden==false);
259
- if(isAnyOptionVisible){
267
+ #updateListEmptyPlaceholder() {
268
+ const isAnyOptionVisible = Array.from(this.#optionList).some(x => x.hidden == false);
269
+ if (isAnyOptionVisible) {
260
270
  this.elements.emptyListPlaceholder.classList.remove("--show");
261
- }else{
271
+ } else {
262
272
  this.elements.emptyListPlaceholder.classList.add("--show");
263
273
  }
264
274
  }
265
- #onOptionSlotChange(e:Event){
275
+ #onOptionSlotChange(e: Event) {
266
276
  this.#setValueOnOptionListChanged();
267
277
  this.#updateListEmptyPlaceholder();
268
278
  }
@@ -283,11 +293,11 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
283
293
  }
284
294
  //when user set value by attribute or value prop directly we call this function
285
295
  #setValueFromOutside(value: TValue): boolean {
286
- if(value === null || value === undefined){
287
- this.#setValue(null,null);
296
+ if (value === null || value === undefined) {
297
+ this.#setValue(null, null);
288
298
  return true;
289
299
  }
290
- let matchedOption:JBOptionWebComponent<TValue>| null = null;
300
+ let matchedOption: JBOptionWebComponent<TValue> | null = null;
291
301
  this.#optionList.forEach((option) => {
292
302
  // if we have value mapper we set selected value by object that match mapper
293
303
  if (option.value == value) {
@@ -295,7 +305,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
295
305
  }
296
306
  });
297
307
  if (matchedOption) {
298
- this.#setValue(matchedOption.value,matchedOption);
308
+ this.#setValue(matchedOption.value, matchedOption);
299
309
  return true;
300
310
  } else {
301
311
  this.#notFoundedValue = value;
@@ -303,14 +313,14 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
303
313
  }
304
314
  }
305
315
  //null option mean deselect all
306
- #changeSelectedOption(option:JBOptionWebComponent<TValue>|null){
307
- this.#optionList.forEach((x)=>x.selected = false);
308
- if(option){
316
+ #changeSelectedOption(option: JBOptionWebComponent<TValue> | null) {
317
+ this.#optionList.forEach((x) => x.selected = false);
318
+ if (option) {
309
319
  option.selected = true;
310
320
  this.#selectedOption = option;
311
321
  }
312
322
  }
313
- #setValue(value: TValue,option:JBOptionWebComponent<TValue>|null) {
323
+ #setValue(value: TValue, option: JBOptionWebComponent<TValue> | null) {
314
324
  this.#notFoundedValue = null;
315
325
  this.#value = value;
316
326
  if (value === null || value === undefined) {
@@ -487,12 +497,12 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
487
497
  const target = (e.composedPath()[0] as JBOptionWebComponent<TValue>);
488
498
  if (target instanceof JBOptionWebComponent) {
489
499
  const value = target.value;
490
- this.#selectOption(value,target);
500
+ this.#selectOption(value, target);
491
501
  this.blur();
492
502
  const dispatchedEvent = this.#dispatchOnChangeEvent();
493
503
  if (dispatchedEvent.defaultPrevented) {
494
504
  e.preventDefault();
495
- this.#selectOption(prevValue,prevOption);
505
+ this.#selectOption(prevValue, prevOption);
496
506
  }
497
507
  }
498
508
 
@@ -501,33 +511,33 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
501
511
  #onOptionConnected(e: CustomEvent) {
502
512
  e.stopPropagation();
503
513
  const target = (e.composedPath()[0] as JBOptionWebComponent<TValue>);
504
- target.addEventListener("jb-option-disconnected",this.#onOptionDisconnected.bind(this),{once:true,passive:true});
514
+ target.addEventListener("jb-option-disconnected", this.#onOptionDisconnected.bind(this), { once: true, passive: true });
505
515
  target.setSelectElement(this);
506
516
  this.#optionList.add(target);
507
- if(this.#notFoundedValue){
517
+ if (this.#notFoundedValue) {
508
518
  this.#setValueOnOptionListChanged();
509
519
  }
510
520
  this.#updateListEmptyPlaceholder();
511
521
  }
512
- #onOptionDisconnected(e:CustomEvent){
522
+ #onOptionDisconnected(e: CustomEvent) {
513
523
  e.stopPropagation();
514
524
  const target = e.target as JBOptionWebComponent<TValue>;
515
525
  this.#optionList.delete(target);
516
526
  this.#updateListEmptyPlaceholder();
517
- if(target.value == this.#value){
527
+ if (target.value == this.#value) {
518
528
  this.#setValueOnOptionListChanged();
519
529
  }
520
530
  }
521
531
 
522
- #selectOption(value: TValue, optionDom:JBOptionWebComponent<TValue>) {
523
- this.#setValue(value,optionDom);
532
+ #selectOption(value: TValue, optionDom: JBOptionWebComponent<TValue>) {
533
+ this.#setValue(value, optionDom);
524
534
  this.#checkValidity(true);
525
535
  }
526
536
  /**
527
537
  * @description show given string as a error in message place
528
538
  * @public
529
539
  */
530
- showValidationError(error: ShowValidationErrorInput | string) {
540
+ showValidationError(error: ShowValidationErrorParameters | string) {
531
541
  const message = typeof error == "string" ? error : error.message;
532
542
  this.elements.messageBox.innerHTML = message;
533
543
  this.elements.messageBox.classList.add("--error");
@@ -552,28 +562,35 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
552
562
  }
553
563
  #createSelectedValueDom(value: TValue) {
554
564
  if (typeof this.callbacks.getSelectedValueDOM == "function") {
555
- return this.callbacks.getSelectedValueDOM(value,this.#selectedOption);
565
+ return this.callbacks.getSelectedValueDOM(value, this.#selectedOption);
556
566
  } else {
557
567
  return this.#createDefaultSelectedValueDom();
558
568
  }
559
569
  }
560
570
  #createDefaultSelectedValueDom() {
561
571
  //TODO: put some backup way for when we have value but no option provided
562
- let contentNodes:Node[] = [];
563
- if(this.#selectedOption){
572
+ let contentNodes: Node[] = [];
573
+ if (this.#selectedOption) {
564
574
  contentNodes = this.#selectedOption.optionContent;
565
575
  }
566
576
  const selectedOptionDom = document.createElement("div");
567
577
  selectedOptionDom.classList.add("selected-value");
568
- selectedOptionDom.append(...contentNodes.map(n=>n.cloneNode()));
578
+ selectedOptionDom.append(...contentNodes.map(n => n.cloneNode()));
569
579
  return selectedOptionDom;
570
580
  }
571
581
  #getInsideValidation() {
572
- const ValidationList: ValidationItem<ValidationValue<TValue>>[] = [];
582
+ const validationList: ValidationItem<ValidationValue<TValue>>[] = [];
583
+ if (this.getAttribute("error") !== null && this.getAttribute("error").trim().length > 0) {
584
+ validationList.push({
585
+ validator: undefined,
586
+ message: this.getAttribute("error"),
587
+ stateType: "customError"
588
+ });
589
+ }
573
590
  if (this.required) {
574
591
  const label = this.getAttribute("label") || "";
575
592
  const message = `${label} حتما باید انتخاب شود`;
576
- ValidationList.push({
593
+ validationList.push({
577
594
  validator: ({ value }) => {
578
595
  return value !== null && value !== undefined;
579
596
  },
@@ -581,7 +598,7 @@ export class JBSelectWebComponent<TValue = any> extends HTMLElement implements W
581
598
  stateType: "valueMissing"
582
599
  });
583
600
  }
584
- return ValidationList;
601
+ return validationList;
585
602
  }
586
603
  //
587
604
  #checkValidity(showError: boolean) {