@true-engineering/true-react-common-ui-kit 1.0.2 → 1.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 (135) hide show
  1. package/dist/components/AccountInfo/AccountInfo.d.ts +4 -4
  2. package/dist/components/AccountInfo/AccountInfo.styles.d.ts +60 -56
  3. package/dist/components/AddButton/AddButton.d.ts +6 -6
  4. package/dist/components/AddButton/AddButton.styles.d.ts +23 -23
  5. package/dist/components/Button/Button.d.ts +19 -33
  6. package/dist/components/Button/Button.styles.d.ts +144 -144
  7. package/dist/components/Checkbox/Checkbox.d.ts +16 -27
  8. package/dist/components/Checkbox/Checkbox.styles.d.ts +39 -42
  9. package/dist/components/CloseButton/CloseButton.d.ts +4 -4
  10. package/dist/components/CloseButton/CloseButton.styles.d.ts +22 -22
  11. package/dist/components/Colors/Colors.styles.d.ts +28 -28
  12. package/dist/components/CssBaseline/CssBaseline.d.ts +1 -1
  13. package/dist/components/CssBaseline/CssBaseline.styles.d.ts +7 -7
  14. package/dist/components/DateInput/DateInput.d.ts +8 -9
  15. package/dist/components/DateInput/DateInput.styles.d.ts +7 -7
  16. package/dist/components/DatePicker/DatePicker.d.ts +29 -36
  17. package/dist/components/DatePicker/DatePicker.styles.d.ts +38 -34
  18. package/dist/components/DatePicker/DatePickerHeader/DatePickerHeader.d.ts +9 -9
  19. package/dist/components/DatePicker/DatePickerHeader/DatePickerHeader.styles.d.ts +59 -59
  20. package/dist/components/DatePicker/DatePickerInput/DatePickerInput.d.ts +7 -9
  21. package/dist/components/DatePicker/DatePickerInput/DatePickerInput.styles.d.ts +16 -16
  22. package/dist/components/Description/Description.d.ts +6 -6
  23. package/dist/components/Description/Description.styles.d.ts +18 -18
  24. package/dist/components/FiltersPane/FilterInterval/FilterInterval.d.ts +19 -19
  25. package/dist/components/FiltersPane/FilterInterval/FilterInterval.styles.d.ts +44 -44
  26. package/dist/components/FiltersPane/FilterMultiSelect/FilterMultiSelect.d.ts +2 -8
  27. package/dist/components/FiltersPane/FilterSelect/FilterSelect.d.ts +17 -35
  28. package/dist/components/FiltersPane/FilterSelect/FilterSelect.styles.d.ts +111 -111
  29. package/dist/components/FiltersPane/FilterSelect/locales.d.ts +6 -10
  30. package/dist/components/FiltersPane/FilterValueView/FilterValueView.d.ts +1 -9
  31. package/dist/components/FiltersPane/FilterValueView/FilterValueView.styles.d.ts +8 -8
  32. package/dist/components/FiltersPane/FilterWithDates/FilterWithDates.d.ts +13 -21
  33. package/dist/components/FiltersPane/FilterWithDates/FilterWithDates.styles.d.ts +41 -41
  34. package/dist/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.d.ts +8 -8
  35. package/dist/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.styles.d.ts +7 -7
  36. package/dist/components/FiltersPane/FilterWrapper/FilterWrapper.d.ts +18 -41
  37. package/dist/components/FiltersPane/FilterWrapper/FilterWrapper.styles.d.ts +92 -92
  38. package/dist/components/FiltersPane/FiltersPane.d.ts +15 -34
  39. package/dist/components/FiltersPane/FiltersPane.styles.d.ts +50 -50
  40. package/dist/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.d.ts +18 -37
  41. package/dist/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.styles.d.ts +82 -82
  42. package/dist/components/FiltersPane/locales.d.ts +22 -28
  43. package/dist/components/FiltersPane/types.d.ts +38 -65
  44. package/dist/components/Flag/Flag.d.ts +2 -2
  45. package/dist/components/Flag/Flag.styles.d.ts +8 -8
  46. package/dist/components/FlexibleTable/FlexibleTable.d.ts +20 -45
  47. package/dist/components/FlexibleTable/FlexibleTable.styles.d.ts +93 -93
  48. package/dist/components/FlexibleTable/TableRow.d.ts +21 -38
  49. package/dist/components/FlexibleTable/TableValue.d.ts +16 -28
  50. package/dist/components/FlexibleTable/types.d.ts +31 -37
  51. package/dist/components/Icon/ComplexIconBoilerplate.d.ts +1 -1
  52. package/dist/components/Icon/Icon.d.ts +2 -2
  53. package/dist/components/Icon/Icon.styles.d.ts +4 -4
  54. package/dist/components/Icon/IconBoilerplate.d.ts +1 -1
  55. package/dist/components/Icon/complexIcons/icons.d.ts +1 -1
  56. package/dist/components/Icon/icons/icons.d.ts +5 -97
  57. package/dist/components/IncrementInput/ChangeButton.d.ts +5 -5
  58. package/dist/components/IncrementInput/IncrementInput.d.ts +3 -4
  59. package/dist/components/IncrementInput/IncrementInput.styles.d.ts +52 -52
  60. package/dist/components/Input/Input.d.ts +37 -48
  61. package/dist/components/Input/Input.styles.d.ts +242 -242
  62. package/dist/components/List/List.d.ts +12 -12
  63. package/dist/components/List/List.styles.d.ts +35 -35
  64. package/dist/components/Modal/Modal.d.ts +19 -19
  65. package/dist/components/Modal/Modal.styles.d.ts +235 -235
  66. package/dist/components/MoreMenu/MoreMenu.d.ts +7 -7
  67. package/dist/components/MoreMenu/MoreMenu.styles.d.ts +45 -45
  68. package/dist/components/MultiSelect/MultiSelect.d.ts +13 -28
  69. package/dist/components/MultiSelect/MultiSelect.styles.d.ts +38 -38
  70. package/dist/components/MultiSelect/MultiSelectInput/MultiSelectInput.d.ts +6 -12
  71. package/dist/components/MultiSelect/MultiSelectInput/MultiSelectInput.styles.d.ts +58 -58
  72. package/dist/components/MultiSelectList/MultiSelectList.d.ts +20 -43
  73. package/dist/components/MultiSelectList/MultiSelectList.styles.d.ts +90 -90
  74. package/dist/components/MultiSelectList/locales.d.ts +6 -10
  75. package/dist/components/Notification/Notification.d.ts +9 -14
  76. package/dist/components/Notification/Notification.styles.d.ts +30 -33
  77. package/dist/components/NumberInput/NumberInput.d.ts +10 -16
  78. package/dist/components/NumberInput/helpers.d.ts +2 -10
  79. package/dist/components/PhoneInput/PhoneInput.d.ts +7 -14
  80. package/dist/components/PhoneInput/PhoneInput.styles.d.ts +60 -60
  81. package/dist/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.d.ts +7 -7
  82. package/dist/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.styles.d.ts +74 -78
  83. package/dist/components/PhoneInput/types.d.ts +11 -11
  84. package/dist/components/RadioButton/RadioButton.d.ts +8 -18
  85. package/dist/components/RadioButton/RadioButton.styles.d.ts +25 -25
  86. package/dist/components/ScrollIntoViewIfNeeded/ScrollIntoViewIfNeeded.d.ts +374 -634
  87. package/dist/components/SearchInput/SearchInput.d.ts +2 -12
  88. package/dist/components/SearchInput/SearchInput.styles.d.ts +32 -32
  89. package/dist/components/Select/Select.d.ts +24 -51
  90. package/dist/components/Select/Select.styles.d.ts +53 -53
  91. package/dist/components/Select/SelectList/SelectList.d.ts +17 -32
  92. package/dist/components/Select/SelectList/SelectList.styles.d.ts +35 -37
  93. package/dist/components/Select/helpers.d.ts +3 -9
  94. package/dist/components/SmartInput/SmartInput.d.ts +16 -28
  95. package/dist/components/SmartInput/helpers.d.ts +4 -8
  96. package/dist/components/Switch/Switch.d.ts +13 -26
  97. package/dist/components/Switch/Switch.styles.d.ts +58 -58
  98. package/dist/components/TextArea/TextArea.d.ts +23 -26
  99. package/dist/components/TextArea/TextArea.styles.d.ts +124 -124
  100. package/dist/components/TextWithInfo/TextWithInfo.d.ts +9 -9
  101. package/dist/components/TextWithInfo/TextWithInfo.styles.d.ts +40 -40
  102. package/dist/components/TextWithTooltip/TextWithTooltip.d.ts +12 -12
  103. package/dist/components/TextWithTooltip/TextWithTooltip.styles.d.ts +10 -10
  104. package/dist/components/ThemedPreloader/ThemedPreloader.d.ts +4 -4
  105. package/dist/components/ThemedPreloader/ThemedPreloader.styles.d.ts +10 -10
  106. package/dist/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.d.ts +1 -1
  107. package/dist/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.styles.d.ts +35 -35
  108. package/dist/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.d.ts +2 -2
  109. package/dist/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.styles.d.ts +5 -5
  110. package/dist/components/Toaster/Toaster.d.ts +11 -16
  111. package/dist/components/Toaster/Toaster.styles.d.ts +41 -41
  112. package/dist/components/Tooltip/Tooltip.d.ts +4 -4
  113. package/dist/components/Tooltip/Tooltip.styles.d.ts +27 -25
  114. package/dist/helpers/data-attributes.d.ts +4 -11
  115. package/dist/helpers/phone.d.ts +8 -28
  116. package/dist/helpers/utils.d.ts +7 -28
  117. package/dist/hooks/use-did-mount-effect.d.ts +1 -4
  118. package/dist/hooks/use-dropdown.d.ts +7 -14
  119. package/dist/hooks/use-is-mounted.d.ts +1 -1
  120. package/dist/hooks/use-on-click-outside.d.ts +4 -25
  121. package/dist/hooks/use-theme.d.ts +5 -10
  122. package/dist/hooks/use-tweak-styles.d.ts +1 -5
  123. package/dist/style.css +90 -205
  124. package/dist/theme.d.ts +55 -51
  125. package/dist/true-react-common-ui-kit.js +16711 -24314
  126. package/dist/true-react-common-ui-kit.js.map +1 -1
  127. package/dist/true-react-common-ui-kit.umd.cjs +39 -35
  128. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  129. package/dist/types.d.ts +23 -77
  130. package/package.json +1 -1
  131. package/src/components/Select/Select.stories.tsx +16 -12
  132. package/src/components/Select/Select.tsx +51 -41
  133. package/src/components/Select/SelectList/SelectList.tsx +17 -22
  134. package/src/components/Select/helpers.ts +14 -6
  135. package/src/components/SmartInput/SmartInput.tsx +130 -127
package/dist/types.d.ts CHANGED
@@ -1,89 +1,35 @@
1
1
  import { Styles } from 'react-jss';
2
2
  import { Modifier, Placement } from 'react-overlays/usePopper';
3
- import {
4
- ICommonIcon,
5
- IComplexIcon,
6
- IPreloaderSvgType,
7
- ISvgIcon,
8
- } from './components';
3
+ import { ICommonIcon, IComplexIcon, IPreloaderSvgType, ISvgIcon } from './components';
9
4
  export interface IDataAttributes {
10
- [key: string]: unknown;
5
+ [key: string]: unknown;
11
6
  }
12
7
  export interface ICommonProps {
13
- data?: IDataAttributes;
8
+ data?: IDataAttributes;
14
9
  }
15
10
  export interface IDropdownWithPopperOptions {
16
- shouldUsePopper?: boolean;
17
- shouldRenderInBody?: boolean;
18
- scrollParent?: 'auto' | 'document' | Element;
19
- shouldHideOnScroll?: boolean;
20
- canBeFlipped?: boolean;
21
- modifiers?: Array<Partial<Modifier<any, any>>>;
22
- placement?: Placement;
23
- flipOptions?: Record<string, any>;
11
+ shouldUsePopper?: boolean;
12
+ shouldRenderInBody?: boolean;
13
+ scrollParent?: 'auto' | 'document' | Element;
14
+ shouldHideOnScroll?: boolean;
15
+ canBeFlipped?: boolean;
16
+ modifiers?: Array<Partial<Modifier<any, any>>>;
17
+ placement?: Placement;
18
+ flipOptions?: Record<string, any>;
24
19
  }
25
- export declare type ComponentStyles<StyleSheet, Props = unknown> = Partial<
26
- Styles<keyof StyleSheet, Props>
27
- >;
28
- export declare type ComponentName =
29
- | 'AccountInfo'
30
- | 'AddButton'
31
- | 'Button'
32
- | 'CloseButton'
33
- | 'Checkbox'
34
- | 'CssBaseline'
35
- | 'Colors'
36
- | 'DateInput'
37
- | 'DatePicker'
38
- | 'DatePickerInput'
39
- | 'DatePickerHeader'
40
- | 'Description'
41
- | 'DotsPreloader'
42
- | 'SvgPreloader'
43
- | 'FiltersPane'
44
- | 'FilterInterval'
45
- | 'FilterSelect'
46
- | 'FilterWithDates'
47
- | 'FilterWithPeriod'
48
- | 'FilterWrapper'
49
- | 'FiltersPaneSearch'
50
- | 'Flag'
51
- | 'FlexibleTable'
52
- | 'Icon'
53
- | 'IncrementInput'
54
- | 'Input'
55
- | 'List'
56
- | 'Modal'
57
- | 'MoreMenu'
58
- | 'MultiSelect'
59
- | 'MultiSelectInput'
60
- | 'MultiSelectList'
61
- | 'Notification'
62
- | 'PhoneInput'
63
- | 'PhoneInputCountryList'
64
- | 'RadioButton'
65
- | 'SearchInput'
66
- | 'Select'
67
- | 'SelectList'
68
- | 'ScrollIntoViewIfNeeded'
69
- | 'Switch'
70
- | 'TextArea'
71
- | 'TextWithInfo'
72
- | 'TextWithTooltip'
73
- | 'ThemedPreloader'
74
- | 'Tooltip'
75
- | 'Toaster';
20
+ export declare type ComponentStyles<StyleSheet, Props = unknown> = Partial<Styles<keyof StyleSheet, Props>>;
21
+ export declare type ComponentName = 'AccountInfo' | 'AddButton' | 'Button' | 'CloseButton' | 'Checkbox' | 'CssBaseline' | 'Colors' | 'DateInput' | 'DatePicker' | 'DatePickerInput' | 'DatePickerHeader' | 'Description' | 'DotsPreloader' | 'SvgPreloader' | 'FiltersPane' | 'FilterInterval' | 'FilterSelect' | 'FilterWithDates' | 'FilterWithPeriod' | 'FilterWrapper' | 'FiltersPaneSearch' | 'Flag' | 'FlexibleTable' | 'Icon' | 'IncrementInput' | 'Input' | 'List' | 'Modal' | 'MoreMenu' | 'MultiSelect' | 'MultiSelectInput' | 'MultiSelectList' | 'Notification' | 'PhoneInput' | 'PhoneInputCountryList' | 'RadioButton' | 'SearchInput' | 'Select' | 'SelectList' | 'ScrollIntoViewIfNeeded' | 'Switch' | 'TextArea' | 'TextWithInfo' | 'TextWithTooltip' | 'ThemedPreloader' | 'Tooltip' | 'Toaster';
76
22
  export declare type UiKitAnimations = Record<string, any>;
77
23
  export declare type UiKitHelpers = Record<string, Styles | (() => Styles)>;
78
24
  export interface UiKitTheme {
79
- name: string;
80
- components?: Partial<Record<ComponentName, ComponentStyles<any, any>>>;
81
- icons?: Partial<Record<ICommonIcon, ISvgIcon>>;
82
- complexIcons?: Partial<Record<IComplexIcon, string>>;
83
- preloaders?: Partial<Record<IPreloaderSvgType, string>>;
84
- animations?: UiKitAnimations;
85
- colors?: Record<string, string>;
86
- dimensions?: Record<string, number>;
87
- boxShadows?: Record<string, string>;
88
- helpers?: UiKitHelpers;
25
+ name: string;
26
+ components?: Partial<Record<ComponentName, ComponentStyles<any, any>>>;
27
+ icons?: Partial<Record<ICommonIcon, ISvgIcon>>;
28
+ complexIcons?: Partial<Record<IComplexIcon, string>>;
29
+ preloaders?: Partial<Record<IPreloaderSvgType, string>>;
30
+ animations?: UiKitAnimations;
31
+ colors?: Record<string, string>;
32
+ dimensions?: Record<string, number>;
33
+ boxShadows?: Record<string, string>;
34
+ helpers?: UiKitHelpers;
89
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@true-engineering/true-react-common-ui-kit",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "True Engineering React UI Kit with theming support",
5
5
  "author": "True Engineering (https://trueengineering.ru)",
6
6
  "keywords": [
@@ -27,21 +27,19 @@ const genLetters = (qnt = 1): string =>
27
27
  .replace(/[^a-z]+/g, '')
28
28
  .substr(0, qnt);
29
29
 
30
- const convertObjectToString = (v?: ObjectValue): string | undefined =>
31
- v !== undefined ? `${v.name}` : undefined;
30
+ const convertObjectToString = (v: ObjectValue): string => v.name;
32
31
 
33
- const convertObjectToId = (v?: ObjectValue): string | undefined =>
34
- v !== undefined ? `${v.name}${v.age}` : undefined;
32
+ const convertObjectToId = (v: ObjectValue): string => `${v.name}${v.age}`;
35
33
 
36
- const convertObjectToReactNode = (v?: ObjectValue): ReactNode | undefined =>
37
- v !== undefined ? (
38
- <span>
39
- <i>{v.name}</i>, {v.age}
40
- </span>
41
- ) : undefined;
34
+ const convertObjectToReactNode = (v: ObjectValue): ReactNode => (
35
+ <span>
36
+ <i>{v.name}</i>, {v.age}
37
+ </span>
38
+ );
39
+
40
+ const convertStringToReactNode = (v: string): ReactNode => <i>{v}</i>;
42
41
 
43
- const convertStringToReactNode = (v?: string): ReactNode | undefined =>
44
- v !== undefined ? <i>{v}</i> : undefined;
42
+ const isOptionDisabled = (option: string) => option.startsWith('Опция');
45
43
 
46
44
  const stringOptions = [
47
45
  'Опция 1',
@@ -76,6 +74,7 @@ interface ISelectWithCustomProps<T> extends ISelectProps<T> {
76
74
  shouldUsePopper?: boolean;
77
75
  shouldRenderInBody?: boolean;
78
76
  shouldHideOnScroll?: boolean;
77
+ shouldUseCustomIsDisabledFunction?: boolean;
79
78
  canBeFlipped?: boolean;
80
79
  scrollParent?: 'document' | 'auto';
81
80
  }
@@ -87,6 +86,7 @@ function SelectWithCustomProps<T>({
87
86
  shouldUsePopper,
88
87
  shouldRenderInBody,
89
88
  shouldHideOnScroll,
89
+ shouldUseCustomIsDisabledFunction,
90
90
  canBeFlipped,
91
91
  scrollParent,
92
92
  ...rest
@@ -165,6 +165,9 @@ function SelectWithCustomProps<T>({
165
165
  optionsMode={optionsMode}
166
166
  onType={async () => setDynamicOptions(await getOptions())}
167
167
  onOpen={handleOpen}
168
+ isOptionDisabled={
169
+ shouldUseCustomIsDisabledFunction ? isOptionDisabled : undefined
170
+ }
168
171
  dropdownOptions={{
169
172
  shouldUsePopper,
170
173
  shouldRenderInBody,
@@ -225,6 +228,7 @@ Default.args = {
225
228
  shouldUsePopper: false,
226
229
  shouldRenderInBody: false,
227
230
  shouldHideOnScroll: false,
231
+ shouldUseCustomIsDisabledFunction: false,
228
232
  canBeFlipped: false,
229
233
  scrollParent: 'document',
230
234
  };
@@ -1,5 +1,8 @@
1
- import React, {
1
+ import {
2
2
  ReactNode,
3
+ FocusEvent,
4
+ KeyboardEvent,
5
+ MouseEvent,
3
6
  useCallback,
4
7
  useEffect,
5
8
  useMemo,
@@ -11,8 +14,7 @@ import clsx from 'clsx';
11
14
  import { merge } from 'lodash';
12
15
  import { debounce } from 'ts-debounce';
13
16
  import { Portal } from 'react-overlays';
14
-
15
- import { SelectList, isOptionDisabled } from './SelectList';
17
+ import { SelectList } from './SelectList';
16
18
  import { IInputProps, Input } from '../Input';
17
19
  import { IIconType, Icon } from '../Icon';
18
20
  import {
@@ -22,61 +24,48 @@ import {
22
24
  useDropdown,
23
25
  } from '../../hooks';
24
26
  import { IDropdownWithPopperOptions } from '../../types';
25
-
26
- import { SelectStyles, styles } from './Select.styles';
27
+ import { isNotEmpty } from '../../helpers';
27
28
  import {
28
29
  defaultConvertFunction,
29
30
  defaultCompareFunction,
30
31
  getActiveValueIndex,
32
+ defaultIsOptionDisabled,
31
33
  } from './helpers';
34
+ import { SelectStyles, styles } from './Select.styles';
32
35
 
33
36
  export interface ISelectProps<Value>
34
37
  extends Omit<IInputProps, 'value' | 'onChange' | 'type'> {
35
38
  tweakStyles?: SelectStyles;
36
39
  defaultOptionLabel?: string;
37
40
  noMatchesLabel?: string;
38
- loadingLabel?: React.ReactNode;
41
+ loadingLabel?: ReactNode;
39
42
  optionsMode?: 'search' | 'dynamic' | 'normal';
40
- onType?: (value: string) => Promise<void>;
41
43
  debounceTime?: number;
42
44
  minSymbolsCountToOpenList?: number;
43
45
  dropdownOptions?: IDropdownWithPopperOptions;
44
46
  dropdownIcon?: IIconType;
45
- onOpen?: () => void;
46
-
47
- optionsFilter?: (options: Value[], query: string) => Value[];
48
47
  options: Value[];
49
- value?: Value;
50
- onChange: (value?: Value) => void; // подумать как возвращать индекс
51
- compareValuesOnChange?: (
52
- v1: Value | undefined,
53
- v2: Value | undefined,
54
- ) => boolean;
55
- // возможно делать какую-то индексацию опций
56
-
48
+ value: Value | undefined;
49
+ shouldScrollToList?: boolean;
50
+ isOptionDisabled?(option: Value): boolean;
51
+ onChange(value: Value | undefined): void; // подумать как возвращать индекс
52
+ onType?(value: string): Promise<void>;
53
+ optionsFilter?(options: Value[], query: string): Value[];
54
+ onOpen?(): void;
55
+ compareValuesOnChange?(v1: Value | undefined, v2: Value | undefined): boolean;
57
56
  // Для избежания проблем юзайте useCallback на эти функции
58
57
  // или выносите их из компонента (чтобы не было сайдэфектов от перерендеринга их)
59
- convertValueToString?: (value?: Value) => string | undefined;
60
- convertValueToReactNode?: (value?: Value) => ReactNode | undefined;
61
- convertValueToId?: (value?: Value) => string | undefined;
58
+ convertValueToString?(value: Value): string | undefined;
59
+ convertValueToReactNode?(value: Value): ReactNode;
60
+ convertValueToId?(value: Value): string | undefined;
62
61
  }
63
62
 
64
63
  export function Select<Value>({
65
64
  options,
66
65
  value,
67
- onChange,
68
- compareValuesOnChange = defaultCompareFunction,
69
- convertValueToString = defaultConvertFunction,
70
- convertValueToId,
71
- convertValueToReactNode,
72
66
  defaultOptionLabel,
73
- onFocus,
74
- onBlur,
75
- onType,
76
- onOpen,
77
67
  debounceTime = 400,
78
68
  optionsMode = 'normal',
79
- optionsFilter,
80
69
  noMatchesLabel,
81
70
  loadingLabel,
82
71
  tweakStyles,
@@ -85,6 +74,18 @@ export function Select<Value>({
85
74
  dropdownOptions,
86
75
  minSymbolsCountToOpenList = 0,
87
76
  dropdownIcon = 'chevron-down',
77
+ shouldScrollToList = true,
78
+ onChange,
79
+ onFocus,
80
+ onBlur,
81
+ onType,
82
+ onOpen,
83
+ isOptionDisabled = defaultIsOptionDisabled,
84
+ compareValuesOnChange = defaultCompareFunction,
85
+ convertValueToString = defaultConvertFunction,
86
+ convertValueToId,
87
+ convertValueToReactNode,
88
+ optionsFilter,
88
89
  ...inputProps
89
90
  }: ISelectProps<Value>): JSX.Element {
90
91
  const { classes, componentStyles } = useTheme('Select', styles, tweakStyles);
@@ -104,6 +105,10 @@ export function Select<Value>({
104
105
  const list = useRef<HTMLDivElement>(null);
105
106
  const input = useRef<HTMLInputElement>(null); // TODO ref снаружи?
106
107
 
108
+ const stringValue = isNotEmpty(value)
109
+ ? convertValueToString(value)
110
+ : undefined;
111
+
107
112
  const filteredOptions = useMemo(() => {
108
113
  if (optionsMode !== 'search') {
109
114
  return options;
@@ -140,7 +145,7 @@ export function Select<Value>({
140
145
  setIsListOpen(true);
141
146
  };
142
147
 
143
- const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
148
+ const handleFocus = (event: FocusEvent<HTMLInputElement>) => {
144
149
  if (onFocus !== undefined) {
145
150
  onFocus(event);
146
151
  }
@@ -151,7 +156,7 @@ export function Select<Value>({
151
156
  handleListOpen();
152
157
  };
153
158
 
154
- const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
159
+ const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
155
160
  if (onBlur !== undefined) {
156
161
  onBlur(event);
157
162
  }
@@ -218,7 +223,7 @@ export function Select<Value>({
218
223
  setSearchValue(v);
219
224
  };
220
225
 
221
- const handleKeyDown = (event: React.KeyboardEvent) => {
226
+ const handleKeyDown = (event: KeyboardEvent) => {
222
227
  if (!isListOpen) {
223
228
  return;
224
229
  }
@@ -369,7 +374,7 @@ export function Select<Value>({
369
374
  ref={inputWrapper}
370
375
  >
371
376
  <Input
372
- value={searchValue !== '' ? searchValue : convertValueToString(value)}
377
+ value={searchValue !== '' ? searchValue : stringValue}
373
378
  onChange={handleInputChange}
374
379
  isActive={isListOpen}
375
380
  isReadonly={optionsMode === 'normal'}
@@ -383,7 +388,7 @@ export function Select<Value>({
383
388
  {...inputProps}
384
389
  />
385
390
  <div
386
- onMouseDown={(event: React.MouseEvent) => {
391
+ onMouseDown={(event: MouseEvent) => {
387
392
  event.preventDefault();
388
393
  }}
389
394
  onClick={onArrowClick}
@@ -411,10 +416,6 @@ export function Select<Value>({
411
416
  {isOpen && (
412
417
  <SelectList
413
418
  options={filteredOptions}
414
- convertValueToString={convertValueToString}
415
- convertValueToReactNode={convertValueToReactNode}
416
- convertValueToId={convertValueToId}
417
- onOptionClick={handleOptionClick}
418
419
  defaultOptionLabel={
419
420
  hasDefaultOption && shouldShowDefaultOption
420
421
  ? defaultOptionLabel
@@ -428,7 +429,16 @@ export function Select<Value>({
428
429
  tweakStyles={tweakStyles?.tweakSelectList as Styles}
429
430
  testId={testId !== undefined ? `${testId}-list` : undefined}
430
431
  // скролл не работает с включеным поппером
431
- shouldScrollToList={!shouldUsePopper && !shouldHideOnScroll}
432
+ shouldScrollToList={
433
+ shouldScrollToList &&
434
+ !shouldUsePopper &&
435
+ !shouldHideOnScroll
436
+ }
437
+ isOptionDisabled={isOptionDisabled}
438
+ convertValueToString={convertValueToString}
439
+ convertValueToReactNode={convertValueToReactNode}
440
+ convertValueToId={convertValueToId}
441
+ onOptionClick={handleOptionClick}
432
442
  />
433
443
  )}
434
444
  </div>
@@ -1,10 +1,9 @@
1
- import React, { ReactNode, useMemo } from 'react';
2
- import { ScrollIntoViewIfNeeded } from '../../ScrollIntoViewIfNeeded';
1
+ import { ReactNode, useMemo } from 'react';
3
2
  import clsx from 'clsx';
4
-
3
+ import { ScrollIntoViewIfNeeded } from '../../ScrollIntoViewIfNeeded';
5
4
  import { useTheme } from '../../../hooks';
6
5
  import { ICommonProps } from '../../../types';
7
-
6
+ import { isNotEmpty } from '../../../helpers';
8
7
  import { SelectListStyles, styles } from './SelectList.styles';
9
8
 
10
9
  export interface ISelectListProps<Value> extends ICommonProps {
@@ -14,44 +13,40 @@ export interface ISelectListProps<Value> extends ICommonProps {
14
13
  activeValue?: Value;
15
14
  noMatchesLabel?: string;
16
15
  isLoading?: boolean;
17
- loadingLabel?: React.ReactNode;
16
+ loadingLabel?: ReactNode;
18
17
  defaultOptionLabel?: string;
19
- onOptionClick: (index: number) => void;
20
18
  testId?: string;
21
19
  shouldScrollToList?: boolean;
22
- convertValueToString: (value?: Value) => string | undefined;
23
- convertValueToReactNode?: (value?: Value) => ReactNode | undefined;
24
- convertValueToId?: (value?: Value) => string | undefined;
25
- }
26
-
27
- export function isOptionDisabled<Value>(option: Value): boolean {
28
- return (
29
- typeof option === 'object' &&
30
- option !== null &&
31
- ((option as { isDisabled?: boolean })?.isDisabled ?? false)
32
- );
20
+ onOptionClick(index: number): void;
21
+ isOptionDisabled(value: Value): boolean;
22
+ convertValueToString(value: Value): string | undefined;
23
+ convertValueToReactNode?(value: Value): ReactNode;
24
+ convertValueToId?(value: Value): string | undefined;
33
25
  }
34
26
 
35
27
  const DEFAULT_OPTION_INDEX = -1;
36
28
 
37
29
  export function SelectList<Value>({
38
30
  options,
39
- onOptionClick,
40
31
  focusedIndex,
41
32
  activeValue,
42
33
  defaultOptionLabel,
43
34
  noMatchesLabel = 'Совпадений не найдено',
44
35
  isLoading,
45
36
  loadingLabel = 'Загрузка...',
46
- convertValueToString,
47
- convertValueToReactNode,
48
- convertValueToId = convertValueToString,
49
37
  tweakStyles,
50
38
  testId,
51
39
  shouldScrollToList = true,
40
+ isOptionDisabled,
41
+ onOptionClick,
42
+ convertValueToString,
43
+ convertValueToReactNode,
44
+ convertValueToId = convertValueToString,
52
45
  }: ISelectListProps<Value>): JSX.Element {
53
46
  const { classes } = useTheme('SelectList', styles, tweakStyles);
54
- const activeValueId = convertValueToId(activeValue);
47
+ const activeValueId = isNotEmpty(activeValue)
48
+ ? convertValueToId(activeValue)
49
+ : undefined;
55
50
 
56
51
  const convertedToStringOptions = useMemo(
57
52
  () => options.map(convertValueToString),
@@ -1,13 +1,21 @@
1
+ import { isNotEmpty } from '../../helpers';
2
+
3
+ export const defaultIsOptionDisabled = <Value>(option: Value): boolean =>
4
+ typeof option === 'object' &&
5
+ option !== null &&
6
+ ((option as { isDisabled?: boolean })?.isDisabled ?? false);
7
+
1
8
  export const defaultConvertFunction = (v: unknown) =>
2
9
  v === undefined ? undefined : String(v);
3
10
 
4
- export const defaultCompareFunction = <Value>(
5
- v1: Value | undefined,
6
- v2: Value | undefined,
7
- ) => v1 === v2;
11
+ export const defaultCompareFunction = <Value>(v1: Value, v2: Value) =>
12
+ v1 === v2;
8
13
 
9
14
  export const getActiveValueIndex = <Value>(
10
15
  options: Value[],
11
16
  value: Value | undefined,
12
- convertFunc: (v?: Value) => string | undefined,
13
- ): number => options.findIndex((o) => convertFunc(o) === convertFunc(value));
17
+ convertFunc: (v: Value) => string | undefined,
18
+ ): number =>
19
+ isNotEmpty(value)
20
+ ? options.findIndex((o) => convertFunc(o) === convertFunc(value))
21
+ : -1;