@bosonprotocol/react-kit 0.36.3-alpha.3 → 0.36.3-alpha.5

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 (62) hide show
  1. package/dist/cjs/components/form/BaseSelect.d.ts.map +1 -1
  2. package/dist/cjs/components/form/BaseSelect.js +2 -1
  3. package/dist/cjs/components/form/BaseSelect.js.map +1 -1
  4. package/dist/cjs/components/form/CountrySelect.d.ts.map +1 -1
  5. package/dist/cjs/components/form/CountrySelect.js +2 -1
  6. package/dist/cjs/components/form/CountrySelect.js.map +1 -1
  7. package/dist/cjs/components/form/Phone.d.ts.map +1 -1
  8. package/dist/cjs/components/form/Phone.js +2 -1
  9. package/dist/cjs/components/form/Phone.js.map +1 -1
  10. package/dist/cjs/components/form/Select.d.ts +48 -3
  11. package/dist/cjs/components/form/Select.d.ts.map +1 -1
  12. package/dist/cjs/components/form/Select.js +14 -14
  13. package/dist/cjs/components/form/Select.js.map +1 -1
  14. package/dist/cjs/components/form/Upload/BaseUpload.d.ts.map +1 -1
  15. package/dist/cjs/components/form/index.d.ts +1 -1
  16. package/dist/cjs/components/form/index.d.ts.map +1 -1
  17. package/dist/cjs/components/form/index.js +2 -3
  18. package/dist/cjs/components/form/index.js.map +1 -1
  19. package/dist/cjs/components/form/types.d.ts +3 -38
  20. package/dist/cjs/components/form/types.d.ts.map +1 -1
  21. package/dist/cjs/components/modal/components/common/VariationSelects.js +2 -2
  22. package/dist/cjs/components/modal/components/common/VariationSelects.js.map +1 -1
  23. package/dist/cjs/hooks/form/useFixSelectFont.d.ts +2 -1
  24. package/dist/cjs/hooks/form/useFixSelectFont.d.ts.map +1 -1
  25. package/dist/cjs/hooks/form/useFixSelectFont.js +7 -2
  26. package/dist/cjs/hooks/form/useFixSelectFont.js.map +1 -1
  27. package/dist/esm/components/form/BaseSelect.d.ts.map +1 -1
  28. package/dist/esm/components/form/BaseSelect.js +2 -1
  29. package/dist/esm/components/form/BaseSelect.js.map +1 -1
  30. package/dist/esm/components/form/CountrySelect.d.ts.map +1 -1
  31. package/dist/esm/components/form/CountrySelect.js +2 -1
  32. package/dist/esm/components/form/CountrySelect.js.map +1 -1
  33. package/dist/esm/components/form/Phone.d.ts.map +1 -1
  34. package/dist/esm/components/form/Phone.js +2 -1
  35. package/dist/esm/components/form/Phone.js.map +1 -1
  36. package/dist/esm/components/form/Select.d.ts +48 -3
  37. package/dist/esm/components/form/Select.d.ts.map +1 -1
  38. package/dist/esm/components/form/Select.js +13 -13
  39. package/dist/esm/components/form/Select.js.map +1 -1
  40. package/dist/esm/components/form/Upload/BaseUpload.d.ts.map +1 -1
  41. package/dist/esm/components/form/index.d.ts +1 -1
  42. package/dist/esm/components/form/index.d.ts.map +1 -1
  43. package/dist/esm/components/form/index.js +1 -1
  44. package/dist/esm/components/form/index.js.map +1 -1
  45. package/dist/esm/components/form/types.d.ts +3 -38
  46. package/dist/esm/components/form/types.d.ts.map +1 -1
  47. package/dist/esm/components/modal/components/common/VariationSelects.js +2 -2
  48. package/dist/esm/components/modal/components/common/VariationSelects.js.map +1 -1
  49. package/dist/esm/hooks/form/useFixSelectFont.d.ts +2 -1
  50. package/dist/esm/hooks/form/useFixSelectFont.d.ts.map +1 -1
  51. package/dist/esm/hooks/form/useFixSelectFont.js +7 -2
  52. package/dist/esm/hooks/form/useFixSelectFont.js.map +1 -1
  53. package/package.json +2 -2
  54. package/src/components/form/BaseSelect.tsx +2 -1
  55. package/src/components/form/CountrySelect.tsx +2 -1
  56. package/src/components/form/Phone.tsx +2 -1
  57. package/src/components/form/Select.tsx +118 -43
  58. package/src/components/form/index.ts +1 -1
  59. package/src/components/form/types.ts +5 -46
  60. package/src/components/modal/components/common/VariationSelects.tsx +2 -2
  61. package/src/hooks/form/useFixSelectFont.tsx +11 -2
  62. package/src/stories/selects/Select.stories.tsx +50 -1
@@ -1,30 +1,90 @@
1
- /* eslint @typescript-eslint/no-explicit-any: "off" */
2
1
  import React from "react";
3
2
  import { useField } from "formik";
4
- import Select, { GroupBase, StylesConfig } from "react-select";
3
+ import ReactSelect, {
4
+ GroupBase,
5
+ StylesConfig,
6
+ MultiValue,
7
+ SingleValue,
8
+ ActionMeta,
9
+ Props as ReactSelectProps,
10
+ PropsValue,
11
+ CSSObjectWithLabel
12
+ } from "react-select";
13
+ import { CSSProperties } from "react";
5
14
  import { checkIfValueIsEmpty } from "../../lib/object/checkIfValueIsEmpty";
6
15
  import { colors, getCssVar } from "../../theme";
7
16
  import { zIndex } from "../ui/zIndex";
8
-
9
17
  import Error from "./Error";
10
- import type { SelectDataProps, SelectProps } from "./types";
11
18
  import { useFixSelectFont } from "../../hooks/form/useFixSelectFont";
12
- export type { SelectProps } from "./types";
19
+ export { GroupBase } from "react-select";
20
+
21
+ // Base theme type with proper CSS types
22
+ type SelectTheme = Partial<{
23
+ control: Partial<CSSProperties> &
24
+ Partial<{
25
+ disabled: Partial<CSSProperties>;
26
+ hover: Partial<CSSProperties>;
27
+ focus: Partial<CSSProperties>;
28
+ error: Partial<CSSProperties>;
29
+ }>;
30
+ option: Partial<CSSProperties> &
31
+ Partial<{
32
+ selected: Partial<CSSProperties>;
33
+ disabled: Partial<CSSProperties>;
34
+ focus: Partial<CSSProperties>;
35
+ error: Partial<CSSObjectWithLabel>;
36
+ }>;
37
+ placeholder: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
38
+ input: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
39
+ singleValue: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
40
+ multiValue: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
41
+ }>;
42
+ export type DefaultSelectOption = {
43
+ label: string;
44
+ value: string | number;
45
+ disabled?: boolean;
46
+ };
47
+
48
+ // Base option type that all options must extend
49
+ export interface SelectOption extends Record<string, unknown> {
50
+ label: string;
51
+ value: string | number;
52
+ disabled?: boolean;
53
+ }
54
+
55
+ // Type-safe props with conditional types based on IsMulti
56
+ export type SelectProps<
57
+ Option extends SelectOption = DefaultSelectOption,
58
+ IsMulti extends boolean = false,
59
+ Group extends GroupBase<Option> = GroupBase<Option>
60
+ > = Omit<ReactSelectProps<Option, IsMulti, Group>, "styles" | "theme"> & {
61
+ name: string;
62
+ errorMessage?: string;
63
+ label?: string;
64
+ theme?: Partial<SelectTheme>;
65
+ reactSelectTheme?: ReactSelectProps<Option, IsMulti, Group>["theme"];
66
+ };
13
67
 
14
- const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
68
+ // Custom styles function with proper typing
69
+ const customStyles = <
70
+ Option extends SelectOption,
71
+ IsMulti extends boolean,
72
+ Group extends GroupBase<Option>
73
+ >(
15
74
  error: unknown,
16
- customTheme: SelectProps["theme"]
17
- ): StylesConfig<Option, boolean, GroupBase<Option>> => ({
18
- control: (provided, state: any) => {
19
- const before = state.selectProps.label
20
- ? {
21
- ":before": {
22
- content: `"${state.selectProps.label}"`,
23
- fontWeight: "600",
24
- paddingLeft: "1rem"
75
+ customTheme?: Partial<SelectTheme>
76
+ ): StylesConfig<Option, IsMulti, Group> => ({
77
+ control: (provided, state) => {
78
+ const before =
79
+ "label" in state.selectProps && state.selectProps.label
80
+ ? {
81
+ ":before": {
82
+ content: `"${state.selectProps.label}"`,
83
+ fontWeight: "600",
84
+ paddingLeft: "1rem"
85
+ }
25
86
  }
26
- }
27
- : null;
87
+ : null;
28
88
  const defaultBorderColor =
29
89
  customTheme?.control?.borderColor || colors.border;
30
90
  return {
@@ -64,14 +124,14 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
64
124
  ...before
65
125
  };
66
126
  },
67
- container: (provided, state: any) => ({
127
+ container: (provided, state) => ({
68
128
  ...provided,
69
129
  pointerEvents: "initial",
70
130
  zIndex: state.isFocused ? zIndex.Select + 1 : zIndex.Select,
71
131
  position: "relative",
72
132
  width: "100%"
73
133
  }),
74
- option: (provided, state: any) => {
134
+ option: (provided, state) => {
75
135
  return {
76
136
  ...provided,
77
137
  cursor: state.isDisabled ? "not-allowed" : "default",
@@ -79,21 +139,19 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
79
139
  ? (customTheme?.option?.disabled?.opacity ?? "0.5")
80
140
  : (customTheme?.option?.opacity ?? "1"),
81
141
  background:
82
- state.isOptionSelected || state.isSelected || state.isFocused
142
+ state.isSelected || state.isFocused
83
143
  ? (customTheme?.option?.selected?.background ?? colors.greyLight)
84
144
  : (customTheme?.option?.background ?? colors.white),
85
- color:
86
- state.isOptionSelected || state.isSelected
87
- ? (customTheme?.option?.selected?.color ?? colors.violet)
88
- : (customTheme?.option?.color ?? colors.black),
145
+ color: state.isSelected
146
+ ? (customTheme?.option?.selected?.color ?? colors.violet)
147
+ : (customTheme?.option?.color ?? colors.black),
89
148
  ...(state.isDisabled && customTheme?.option?.disabled),
90
- ...((state.isOptionSelected || state.isSelected) &&
91
- customTheme?.option?.selected),
149
+ ...(state.isSelected && customTheme?.option?.selected),
92
150
  ...(state.isFocused && customTheme?.option?.focus),
93
151
  ...(!checkIfValueIsEmpty(error) && customTheme?.option?.error)
94
152
  };
95
153
  },
96
- indicatorsContainer: (provided, state: any) => {
154
+ indicatorsContainer: (provided, state) => {
97
155
  return {
98
156
  ...provided,
99
157
  ...(state.isDisabled && {
@@ -123,7 +181,7 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
123
181
  ...(!checkIfValueIsEmpty(error) && customTheme?.singleValue?.error)
124
182
  };
125
183
  },
126
- multiValue: (provided, state: any) => {
184
+ multiValue: (provided, state) => {
127
185
  return {
128
186
  ...provided,
129
187
  ...customTheme?.multiValue,
@@ -134,24 +192,32 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
134
192
  };
135
193
  }
136
194
  });
137
-
138
- export default function SelectComponent<
139
- M extends boolean,
140
- Option extends Record<string, unknown> = SelectDataProps
195
+ export type DefaultSelectProps<IsMulti extends boolean = false> = SelectProps<
196
+ DefaultSelectOption,
197
+ IsMulti,
198
+ GroupBase<DefaultSelectOption>
199
+ >;
200
+ export function Select<
201
+ Option extends SelectOption = DefaultSelectOption,
202
+ IsMulti extends boolean = false,
203
+ Group extends GroupBase<Option> = GroupBase<Option>
141
204
  >({
142
205
  name,
143
206
  options,
144
207
  placeholder = "Choose...",
145
208
  isClearable = false,
146
209
  isSearchable = true,
147
- disabled = false,
210
+ isDisabled = false,
148
211
  errorMessage,
149
212
  onChange,
213
+ onBlur,
150
214
  theme,
215
+ reactSelectTheme,
151
216
  isMulti,
152
217
  ...props
153
- }: SelectProps<M, Option>) {
218
+ }: SelectProps<Option, IsMulti, Group>) {
154
219
  const [field, meta, helpers] = useField(name);
220
+
155
221
  const displayErrorMessage =
156
222
  meta.error && meta.touched && !errorMessage
157
223
  ? meta.error
@@ -163,10 +229,10 @@ export default function SelectComponent<
163
229
  typeof displayErrorMessage === "string" && displayErrorMessage !== "";
164
230
 
165
231
  const handleChange = (
166
- option: Parameters<NonNullable<typeof onChange>>[0],
167
- actionMeta: Parameters<NonNullable<typeof onChange>>[1]
232
+ option: IsMulti extends true ? MultiValue<Option> : SingleValue<Option>,
233
+ actionMeta: ActionMeta<Option>
168
234
  ) => {
169
- if (disabled) {
235
+ if (isDisabled) {
170
236
  return;
171
237
  }
172
238
  if (!meta.touched) {
@@ -175,34 +241,43 @@ export default function SelectComponent<
175
241
  helpers.setValue(option);
176
242
  onChange?.(option, actionMeta);
177
243
  };
178
- const handleBlur = () => {
244
+
245
+ const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
179
246
  if (!meta.touched) {
180
247
  helpers.setTouched(true);
181
248
  }
249
+ field.onBlur(event);
250
+ onBlur?.(event);
182
251
  };
252
+
183
253
  const { jsx, selectClassName } = useFixSelectFont({
184
254
  selectClassName: "boson-select"
185
255
  });
256
+
186
257
  return (
187
258
  <>
188
259
  {jsx}
189
- <Select
190
- styles={customStyles<Option>(displayErrorMessage, theme)}
260
+ <ReactSelect<Option, IsMulti, Group>
261
+ styles={customStyles<Option, IsMulti, Group>(
262
+ displayErrorMessage,
263
+ theme
264
+ )}
191
265
  {...field}
192
266
  {...props}
267
+ theme={reactSelectTheme}
193
268
  className={selectClassName}
194
269
  isMulti={isMulti}
195
270
  placeholder={placeholder}
196
271
  options={options}
197
- value={field.value}
272
+ value={field.value as PropsValue<Option>}
198
273
  onChange={handleChange}
199
274
  onBlur={handleBlur}
200
275
  isSearchable={isSearchable}
201
276
  isClearable={isClearable}
202
- isDisabled={disabled}
277
+ isDisabled={isDisabled}
203
278
  isOptionDisabled={(option) => !!option.disabled}
204
279
  />
205
- <Error display={displayError} message={displayErrorMessage} />{" "}
280
+ <Error display={displayError} message={displayErrorMessage} />
206
281
  </>
207
282
  );
208
283
  }
@@ -6,7 +6,7 @@ export { FormField, FormFieldProps } from "./FormField";
6
6
  export * from "./BaseInput";
7
7
  export { default as Input, InputProps } from "./Input";
8
8
  export { default as Phone, PhoneProps } from "./Phone";
9
- export { default as Select, SelectProps } from "./Select";
9
+ export * from "./Select";
10
10
  export * from "./CountrySelect";
11
11
  export * from "./BaseTagsInput";
12
12
  export * from "./BaseTextArea";
@@ -1,10 +1,5 @@
1
1
  import { ReactNode } from "react";
2
- import {
3
- ActionMeta,
4
- CSSObjectWithLabel,
5
- MultiValue,
6
- SingleValue
7
- } from "react-select";
2
+ import { SingleValue } from "react-select";
8
3
  import { CSSProperties } from "styled-components";
9
4
  import { ImageEditorModalProps } from "./Upload/ImageEditorModal/ImageEditorModal";
10
5
  import type {
@@ -100,14 +95,14 @@ export interface BaseSelectProps<Value = string> {
100
95
  placeholder?: string;
101
96
  defaultValue?: SelectDataProps<Value> | null;
102
97
  onChange?: OnChange<Value>;
98
+ hasError?: boolean;
103
99
  }
104
100
  export type SupportedReactSelectProps<
105
101
  M extends boolean | undefined = false,
106
102
  Option extends Record<string, unknown> = SelectDataProps
107
103
  > = Pick<
108
104
  StateManagerProps<Option, M extends undefined ? false : boolean>,
109
- | "formatGroupLabel"
110
- | "formatOptionLabel"
105
+ // | "formatOptionLabel"
111
106
  | "menuPlacement"
112
107
  | "menuPosition"
113
108
  | "menuIsOpen"
@@ -126,45 +121,9 @@ export type SupportedReactSelectProps<
126
121
  | "closeMenuOnSelect"
127
122
  | "captureMenuScroll"
128
123
  | "defaultMenuIsOpen"
124
+ | "placeholder"
125
+ | "hideSelectedOptions"
129
126
  >;
130
- export type SelectProps<
131
- M extends boolean | undefined = false,
132
- Option extends Record<string, unknown> = SelectDataProps
133
- > = BaseProps & {
134
- isMulti?: M;
135
- disabled?: boolean;
136
- isClearable?: boolean;
137
- isSearchable?: boolean;
138
- options: Array<Option> | Readonly<Array<Option>>;
139
- errorMessage?: string;
140
- onChange?: (
141
- option: M extends true ? MultiValue<Option> : SingleValue<Option>,
142
- actionMeta?: ActionMeta<Option>
143
- ) => void;
144
- label?: string;
145
- theme?: Partial<{
146
- control: Partial<CSSProperties> &
147
- Partial<{
148
- disabled: Partial<CSSProperties>;
149
- hover: Partial<CSSProperties>;
150
- focus: Partial<CSSProperties>;
151
- error: Partial<CSSProperties>;
152
- }>;
153
- option: Partial<CSSProperties> &
154
- Partial<{
155
- selected: Partial<CSSProperties>;
156
- disabled: Partial<CSSProperties>;
157
- focus: Partial<CSSProperties>;
158
- error: Partial<CSSObjectWithLabel>;
159
- }>;
160
- placeholder: Partial<CSSProperties> &
161
- Partial<{ error: CSSObjectWithLabel }>;
162
- input: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
163
- singleValue: Partial<CSSProperties> &
164
- Partial<{ error: CSSObjectWithLabel }>;
165
- multiValue: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
166
- }>;
167
- } & SupportedReactSelectProps<M, Option>;
168
127
 
169
128
  export type UploadProps = BaseProps & {
170
129
  accept?: string;
@@ -354,7 +354,7 @@ export default function VariationSelects({
354
354
  setLastChangedVariation("color");
355
355
  submitForm();
356
356
  }}
357
- disabled={disabled}
357
+ isDisabled={disabled}
358
358
  />
359
359
  </>
360
360
  )}
@@ -373,7 +373,7 @@ export default function VariationSelects({
373
373
  setLastChangedVariation("size");
374
374
  submitForm();
375
375
  }}
376
- disabled={disabled}
376
+ isDisabled={disabled}
377
377
  />
378
378
  </>
379
379
  )}
@@ -2,9 +2,11 @@ import React, { useEffect, useRef } from "react";
2
2
  import { inputStyles } from "../../components/form/styles";
3
3
 
4
4
  export const useFixSelectFont = ({
5
- selectClassName
5
+ selectClassName,
6
+ hasError
6
7
  }: {
7
8
  selectClassName: string;
9
+ hasError?: boolean;
8
10
  }) => {
9
11
  const inputFontSize = useRef<string>();
10
12
  useEffect(() => {
@@ -22,14 +24,21 @@ export const useFixSelectFont = ({
22
24
  jsx: (
23
25
  <style>{`.${selectClassName}{
24
26
  [class*="-placeholder"],[class*="-singleValue"],[class*="-option"]{
25
- font-size: ${inputFontSize.current || "13.3333px"};
27
+ font-size: ${inputFontSize.current || "0.875rem"};
26
28
  }
29
+ ${
30
+ hasError
31
+ ? ""
32
+ : `
27
33
  [class*="-singleValue"]{
28
34
  color: ${inputStyles.color};
29
35
  }
30
36
  [class*="-placeholder"]{
31
37
  color: ${inputStyles.placeholder.color};
32
38
  }
39
+ `
40
+ }
41
+
33
42
  }`}</style>
34
43
  ),
35
44
  selectClassName
@@ -29,7 +29,7 @@ export default {
29
29
  disable: true // remove name input in controls
30
30
  }
31
31
  },
32
- disabled: { control: "boolean" },
32
+ isDisabled: { control: "boolean" },
33
33
  isMulti: { control: "boolean" },
34
34
  isClearable: { control: "boolean" },
35
35
  isSearchable: { control: "boolean" },
@@ -117,3 +117,52 @@ export const WithError = {
117
117
  placeholder: "this is a placeholder"
118
118
  } satisfies SelectProps
119
119
  };
120
+
121
+ export const WithLabel = {
122
+ args: { ...BASE_ARGS, label: "my label" } satisfies SelectProps
123
+ };
124
+
125
+ export const WithGroups = {
126
+ args: {
127
+ ...BASE_ARGS,
128
+ options: [
129
+ {
130
+ label: "first group",
131
+ options: [
132
+ { label: "first group - first option", value: "1-first-group" },
133
+ {
134
+ label: "first group - second option",
135
+ value: "2-first-group",
136
+ disabled: true
137
+ },
138
+ { label: "first group - third option", value: "3-first-group" }
139
+ ]
140
+ },
141
+ {
142
+ label: "second group",
143
+ options: [
144
+ { label: "second group - first option", value: "1-second-group" },
145
+ {
146
+ label: "second group - second option",
147
+ value: "2-second-group",
148
+ disabled: true
149
+ },
150
+ { label: "second group - third option", value: "3-second-group" }
151
+ ],
152
+ disabled: true
153
+ },
154
+ {
155
+ label: "third group",
156
+ options: [
157
+ { label: "third group - first option", value: "1-third-group" },
158
+ {
159
+ label: "third group - second option",
160
+ value: "2-third-group",
161
+ disabled: true
162
+ },
163
+ { label: "third group - third option", value: "3-third-group" }
164
+ ]
165
+ }
166
+ ]
167
+ } satisfies SelectProps
168
+ };