@true-engineering/true-react-common-ui-kit 3.45.1 → 4.0.0-alpha0
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/README.md +0 -40
- package/dist/components/CloseButton/CloseButton.d.ts +1 -1
- package/dist/components/ControlGroup/ControlGroup.d.ts +10 -0
- package/dist/components/ControlGroup/ControlGroup.stories.d.ts +7 -0
- package/dist/components/ControlGroup/ControlGroup.styles.d.ts +3 -0
- package/dist/components/ControlGroup/index.d.ts +2 -0
- package/dist/components/ControlWrapper/ControlWrapper.d.ts +27 -0
- package/dist/components/ControlWrapper/ControlWrapper.stories.d.ts +6 -0
- package/dist/components/ControlWrapper/ControlWrapper.styles.d.ts +6 -0
- package/dist/components/ControlWrapper/index.d.ts +2 -0
- package/dist/components/DateInput/DateInput.d.ts +3 -3
- package/dist/components/DatePicker/components/DatePickerHeader/DatePickerHeader.styles.d.ts +1 -1
- package/dist/components/DatePicker/types.d.ts +1 -1
- package/dist/components/FiltersPane/FiltersPane.stories.d.ts +1 -2
- package/dist/components/FiltersPane/components/FilterWithDates/FilterWithDates.d.ts +1 -1
- package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -2
- package/dist/components/Input/Input.d.ts +5 -52
- package/dist/components/Input/Input.stories.d.ts +4 -13
- package/dist/components/Input/Input.styles.d.ts +5 -4
- package/dist/components/Input/InputBase.d.ts +24 -0
- package/dist/components/Input/index.d.ts +1 -0
- package/dist/components/Input/types.d.ts +3 -4
- package/dist/components/NumberInput/NumberInput.d.ts +3 -3
- package/dist/components/PhoneInput/PhoneInput.d.ts +3 -3
- package/dist/components/PhoneInput/PhoneInput.stories.d.ts +2 -2
- package/dist/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.d.ts +3 -2
- package/dist/components/PhoneInput/types.d.ts +2 -0
- package/dist/components/SearchInput/SearchInput.d.ts +1 -3
- package/dist/components/SearchInput/SearchInput.stories.d.ts +11 -1
- package/dist/components/SearchInput/SearchInput.styles.d.ts +1 -1
- package/dist/components/Select/Select.d.ts +5 -5
- package/dist/components/Select/Select.styles.d.ts +17 -16
- package/dist/components/Select/types.d.ts +3 -0
- package/dist/components/SmartInput/SmartInput.d.ts +3 -3
- package/dist/components/TextArea/TextArea.d.ts +5 -14
- package/dist/components/TextArea/TextArea.styles.d.ts +8 -2
- package/dist/components/WithPopup/WithPopup.d.ts +3 -10
- package/dist/components/WithPopup/WithPopup.styles.d.ts +1 -1
- package/dist/components/WithPopup/types.d.ts +0 -3
- package/dist/components/WithTooltip/WithTooltip.styles.d.ts +0 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/theme/common.d.ts +13 -5
- package/dist/theme/types.d.ts +4 -2
- package/dist/true-react-common-ui-kit.js +1184 -1029
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1164 -1009
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/Button/Button.stories.tsx +4 -8
- package/src/components/CloseButton/CloseButton.tsx +4 -4
- package/src/components/ControlGroup/ControlGroup.stories.tsx +40 -0
- package/src/components/ControlGroup/ControlGroup.styles.ts +46 -0
- package/src/components/ControlGroup/ControlGroup.tsx +55 -0
- package/src/components/ControlGroup/index.ts +2 -0
- package/src/components/ControlWrapper/ControlWrapper.stories.tsx +45 -0
- package/src/components/ControlWrapper/ControlWrapper.styles.ts +185 -0
- package/src/components/ControlWrapper/ControlWrapper.tsx +151 -0
- package/src/components/ControlWrapper/index.ts +2 -0
- package/src/components/DateInput/DateInput.styles.ts +2 -7
- package/src/components/DateInput/DateInput.tsx +4 -4
- package/src/components/DatePicker/DatePicker.tsx +3 -3
- package/src/components/DatePicker/components/DatePickerHeader/DatePickerHeader.styles.ts +7 -41
- package/src/components/DatePicker/components/DatePickerHeader/DatePickerHeader.tsx +18 -26
- package/src/components/DatePicker/types.ts +1 -1
- package/src/components/FileItem/FileItem.stories.tsx +4 -8
- package/src/components/FiltersPane/FiltersPane.stories.tsx +0 -4
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.styles.ts +9 -7
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.tsx +1 -8
- package/src/components/FiltersPane/components/FilterSelect/FilterSelect.styles.ts +7 -5
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +7 -9
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.ts +12 -17
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.tsx +2 -5
- package/src/components/IconButton/IconButton.stories.tsx +5 -5
- package/src/components/IncrementInput/IncrementInput.stories.tsx +0 -2
- package/src/components/IncrementInput/IncrementInput.styles.ts +9 -9
- package/src/components/Input/Input.stories.tsx +17 -25
- package/src/components/Input/Input.styles.ts +50 -260
- package/src/components/Input/Input.tsx +22 -285
- package/src/components/Input/InputBase.tsx +250 -0
- package/src/components/Input/index.ts +1 -0
- package/src/components/Input/types.ts +3 -32
- package/src/components/MultiSelectList/MultiSelectList.styles.ts +7 -5
- package/src/components/Notification/Notification.stories.tsx +2 -6
- package/src/components/NumberInput/NumberInput.stories.tsx +0 -2
- package/src/components/NumberInput/NumberInput.tsx +4 -7
- package/src/components/PhoneInput/PhoneInput.stories.tsx +6 -10
- package/src/components/PhoneInput/PhoneInput.styles.ts +13 -10
- package/src/components/PhoneInput/PhoneInput.tsx +9 -12
- package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.styles.ts +6 -4
- package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.tsx +6 -6
- package/src/components/PhoneInput/types.ts +4 -0
- package/src/components/SearchInput/SearchInput.stories.tsx +1 -0
- package/src/components/SearchInput/SearchInput.styles.ts +17 -27
- package/src/components/SearchInput/SearchInput.tsx +13 -34
- package/src/components/Select/CustomSelect.stories.tsx +6 -9
- package/src/components/Select/MultiSelect.stories.tsx +4 -12
- package/src/components/Select/Select.stories.tsx +3 -11
- package/src/components/Select/Select.styles.ts +28 -42
- package/src/components/Select/Select.tsx +73 -81
- package/src/components/Select/types.ts +5 -0
- package/src/components/SmartInput/SmartInput.stories.tsx +0 -1
- package/src/components/SmartInput/SmartInput.tsx +4 -4
- package/src/components/Status/Status.stories.tsx +3 -7
- package/src/components/TextArea/TextArea.stories.tsx +1 -3
- package/src/components/TextArea/TextArea.styles.ts +27 -126
- package/src/components/TextArea/TextArea.tsx +86 -112
- package/src/components/TextButton/TextButton.stories.tsx +4 -8
- package/src/components/WithPopup/WithPopup.stories.tsx +0 -1
- package/src/components/WithPopup/WithPopup.styles.ts +0 -2
- package/src/components/WithPopup/WithPopup.tsx +10 -36
- package/src/components/WithPopup/types.ts +0 -7
- package/src/components/WithTooltip/WithTooltip.styles.ts +0 -6
- package/src/components/WithTooltip/WithTooltip.tsx +2 -7
- package/src/components/index.ts +2 -0
- package/src/theme/common.ts +15 -6
- package/src/theme/types.ts +8 -4
- package/src/types.ts +3 -0
- package/dist/components/Input/constants.d.ts +0 -1
- package/dist/components/WithPopup/helpers.d.ts +0 -2
- package/src/components/Input/constants.ts +0 -1
- package/src/components/WithPopup/helpers.ts +0 -9
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { colors, createThemedStyles, ITweakStyles } from '../../theme';
|
|
1
|
+
import { colors, createThemedStyles, dimensions, ITweakStyles } from '../../theme';
|
|
3
2
|
import { IInputStyles } from '../Input';
|
|
4
3
|
|
|
5
|
-
const
|
|
4
|
+
const { Z_INDEX } = dimensions;
|
|
6
5
|
|
|
7
6
|
export const useStyles = createThemedStyles('SearchInput', {
|
|
8
7
|
root: {
|
|
@@ -16,38 +15,29 @@ export const useStyles = createThemedStyles('SearchInput', {
|
|
|
16
15
|
left: 12,
|
|
17
16
|
height: '100%',
|
|
18
17
|
width: 20,
|
|
19
|
-
zIndex: 2,
|
|
20
18
|
color: colors.GREY_ACTIVE,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
iconClickable: {
|
|
24
|
-
cursor: 'pointer',
|
|
19
|
+
zIndex: Z_INDEX.CONTROL_FOCUS + 1,
|
|
25
20
|
},
|
|
26
21
|
});
|
|
27
22
|
|
|
28
23
|
export const inputStyles: IInputStyles = {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
input: {
|
|
44
|
-
fontSize: 14,
|
|
45
|
-
paddingLeft: 0,
|
|
24
|
+
tweakControlWrapper: {
|
|
25
|
+
root: {
|
|
26
|
+
borderColor: 'transparent',
|
|
27
|
+
borderRadius: 18,
|
|
28
|
+
paddingLeft: 0,
|
|
29
|
+
transitionProperty: 'background-color, border-color',
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
focused: {
|
|
33
|
+
backgroundColor: colors.CLASSIC_WHITE,
|
|
34
|
+
borderColor: colors.BORDER_MAIN,
|
|
35
|
+
},
|
|
46
36
|
},
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
left: LEFT_PADDING,
|
|
38
|
+
inputContent: {
|
|
50
39
|
fontSize: 14,
|
|
40
|
+
paddingLeft: 44,
|
|
51
41
|
},
|
|
52
42
|
};
|
|
53
43
|
|
|
@@ -1,41 +1,25 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
addClickHandler,
|
|
5
|
-
addDataAttributes,
|
|
6
|
-
getTestId,
|
|
7
|
-
isNotEmpty,
|
|
8
|
-
} from '@true-engineering/true-react-platform-helpers';
|
|
2
|
+
import { addDataTestId, getTestId } from '@true-engineering/true-react-platform-helpers';
|
|
3
|
+
import { addDataAttributes } from '../../helpers';
|
|
9
4
|
import { useTweakStyles } from '../../hooks';
|
|
10
5
|
import { ICommonProps } from '../../types';
|
|
11
6
|
import { Icon } from '../Icon';
|
|
12
7
|
import { IInputProps, Input } from '../Input';
|
|
13
8
|
import { inputStyles, ISearchInputStyles, useStyles } from './SearchInput.styles';
|
|
14
9
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
| 'isInvalid'
|
|
21
|
-
| 'errorMessage'
|
|
22
|
-
| 'label'
|
|
23
|
-
| 'isActive'
|
|
24
|
-
| 'errorPosition'
|
|
25
|
-
| 'hasFloatingLabel'
|
|
26
|
-
| 'border'
|
|
27
|
-
| 'tweakStyles'
|
|
28
|
-
> {
|
|
29
|
-
// TODO: Можно будет удалить в 4й версии
|
|
30
|
-
onSearchIconClick?: () => void;
|
|
31
|
-
}
|
|
10
|
+
export type ISearchInputProps = Omit<
|
|
11
|
+
IInputProps,
|
|
12
|
+
'type' | 'label' | 'isInvalid' | 'errorMessage' | 'isActive' | 'tweakStyles'
|
|
13
|
+
> &
|
|
14
|
+
ICommonProps<ISearchInputStyles>;
|
|
32
15
|
|
|
33
16
|
export const SearchInput: FC<ISearchInputProps> = ({
|
|
34
17
|
isClearable = true,
|
|
35
18
|
tweakStyles,
|
|
19
|
+
placeholder,
|
|
20
|
+
value,
|
|
36
21
|
testId,
|
|
37
22
|
data,
|
|
38
|
-
onSearchIconClick,
|
|
39
23
|
...props
|
|
40
24
|
}) => {
|
|
41
25
|
const classes = useStyles({ theme: tweakStyles });
|
|
@@ -48,21 +32,16 @@ export const SearchInput: FC<ISearchInputProps> = ({
|
|
|
48
32
|
});
|
|
49
33
|
|
|
50
34
|
return (
|
|
51
|
-
<div className={classes.root} {...addDataAttributes(data
|
|
52
|
-
<div
|
|
53
|
-
className={clsx(classes.icon, { [classes.iconClickable]: isNotEmpty(onSearchIconClick) })}
|
|
54
|
-
{...addClickHandler(onSearchIconClick)}
|
|
55
|
-
>
|
|
35
|
+
<div className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
|
|
36
|
+
<div className={classes.icon}>
|
|
56
37
|
<Icon type="search" />
|
|
57
38
|
</div>
|
|
58
39
|
<Input
|
|
59
|
-
|
|
40
|
+
value={value}
|
|
41
|
+
placeholder={placeholder}
|
|
60
42
|
isClearable={isClearable}
|
|
61
|
-
isActive={props.value !== '' && props.value !== undefined}
|
|
62
43
|
testId={getTestId(testId, 'input')}
|
|
63
44
|
tweakStyles={tweakInputStyles}
|
|
64
|
-
hasFloatingLabel={false}
|
|
65
|
-
label={props.placeholder}
|
|
66
45
|
{...props}
|
|
67
46
|
/>
|
|
68
47
|
</div>
|
|
@@ -3,9 +3,9 @@ import { createUseStyles } from 'react-jss';
|
|
|
3
3
|
import { isStringNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
4
4
|
import { type ComponentMeta, type ComponentStory } from '@storybook/react';
|
|
5
5
|
import { Button, type IButtonStyles } from '../Button';
|
|
6
|
-
import {
|
|
6
|
+
import { type IInputStyles, Input } from '../Input';
|
|
7
7
|
import { TextButton } from '../TextButton';
|
|
8
|
-
import {
|
|
8
|
+
import { type ISelectProps, Select } from './Select';
|
|
9
9
|
|
|
10
10
|
interface ISelectWithCustomProps<Option> extends ISelectProps<Option> {
|
|
11
11
|
shouldUsePopper?: boolean;
|
|
@@ -54,8 +54,10 @@ const useCustomListFooterStyles = createUseStyles({
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
const inputTweakStyles: IInputStyles = {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
tweakControlWrapper: {
|
|
58
|
+
root: {
|
|
59
|
+
'--control-height': '24px',
|
|
60
|
+
}
|
|
59
61
|
},
|
|
60
62
|
|
|
61
63
|
input: {
|
|
@@ -102,7 +104,6 @@ function CustomListHeader({ onAdd }: ICustomListHeaderProps) {
|
|
|
102
104
|
<div className={classes.inputView}>
|
|
103
105
|
<Input
|
|
104
106
|
value={inputValue}
|
|
105
|
-
border="bottom"
|
|
106
107
|
placeholder="Option Value"
|
|
107
108
|
tweakStyles={inputTweakStyles}
|
|
108
109
|
shouldFocusOnMount
|
|
@@ -237,13 +238,9 @@ CustomSelect.args = {
|
|
|
237
238
|
noMatchesLabel: 'No matches',
|
|
238
239
|
isInvalid: false,
|
|
239
240
|
errorMessage: '',
|
|
240
|
-
errorPosition: 'bottom',
|
|
241
|
-
hasFloatingLabel: true,
|
|
242
|
-
hasRequiredLabel: false,
|
|
243
241
|
isDisabled: false,
|
|
244
242
|
isRequired: false,
|
|
245
243
|
isClearable: false,
|
|
246
|
-
|
|
247
244
|
shouldUsePopper: false,
|
|
248
245
|
shouldRenderInBody: false,
|
|
249
246
|
shouldHideOnScroll: false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, useEffect, useState } from 'react';
|
|
2
2
|
import { isStringNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
4
|
-
import {
|
|
4
|
+
import { IMultipleSelectProps, Select } from './Select';
|
|
5
5
|
|
|
6
6
|
interface ObjectValue {
|
|
7
7
|
name: string;
|
|
@@ -9,9 +9,7 @@ interface ObjectValue {
|
|
|
9
9
|
isDisabled?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
const borders: Array<ISelectProps<any>['border']> = [undefined, 'left', 'top', 'right', 'bottom'];
|
|
14
|
-
const errorPositions: Array<ISelectProps<any>['errorPosition']> = ['bottom', 'top'];
|
|
12
|
+
const groupPlacements = [undefined, 'left', 'right', 'middle'];
|
|
15
13
|
|
|
16
14
|
const genLetters = (qnt = 1): string =>
|
|
17
15
|
Math.random()
|
|
@@ -188,9 +186,7 @@ export default {
|
|
|
188
186
|
debounceTime: {
|
|
189
187
|
control: { type: 'range', min: 0, max: 1000, step: 100 },
|
|
190
188
|
},
|
|
191
|
-
|
|
192
|
-
border: { control: 'inline-radio', options: borders },
|
|
193
|
-
inlineStyle: { control: 'select', options: inlineStyles },
|
|
189
|
+
groupPlacement: { control: 'select', options: groupPlacements },
|
|
194
190
|
optionsMode: {
|
|
195
191
|
control: 'inline-radio',
|
|
196
192
|
options: ['normal', 'search', 'dynamic'],
|
|
@@ -211,13 +207,9 @@ export const MultiSelect = Template.bind({});
|
|
|
211
207
|
MultiSelect.args = {
|
|
212
208
|
label: 'Dropdown',
|
|
213
209
|
noMatchesLabel: 'No matches',
|
|
214
|
-
border: undefined,
|
|
215
210
|
isInvalid: false,
|
|
216
211
|
errorMessage: 'Error Text',
|
|
217
|
-
|
|
218
|
-
hasFloatingLabel: true,
|
|
219
|
-
hasRequiredLabel: true,
|
|
220
|
-
iconType: 'document',
|
|
212
|
+
icon: 'document',
|
|
221
213
|
defaultOptionLabel: '',
|
|
222
214
|
allOptionsLabel: 'Все опции',
|
|
223
215
|
isDisabled: false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, useEffect, useState } from 'react';
|
|
2
2
|
import { isStringNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
3
3
|
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
4
|
-
import {
|
|
4
|
+
import { ISelectProps, Select } from './Select';
|
|
5
5
|
|
|
6
6
|
interface ObjectValue {
|
|
7
7
|
name: string;
|
|
@@ -9,9 +9,7 @@ interface ObjectValue {
|
|
|
9
9
|
isDisabled?: boolean;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
const borders: Array<ISelectProps<any>['border']> = [undefined, 'left', 'top', 'right', 'bottom'];
|
|
14
|
-
const errorPositions: Array<ISelectProps<any>['errorPosition']> = ['bottom', 'top'];
|
|
12
|
+
const groupPlacements = [undefined, 'left', 'right', 'middle'];
|
|
15
13
|
|
|
16
14
|
const genLetters = (qnt = 1): string =>
|
|
17
15
|
Math.random()
|
|
@@ -185,9 +183,7 @@ export default {
|
|
|
185
183
|
debounceTime: {
|
|
186
184
|
control: { type: 'range', min: 0, max: 1000, step: 100 },
|
|
187
185
|
},
|
|
188
|
-
|
|
189
|
-
border: { control: 'inline-radio', options: borders },
|
|
190
|
-
inlineStyle: { control: 'select', options: inlineStyles },
|
|
186
|
+
groupPlacement: { control: 'select', options: groupPlacements },
|
|
191
187
|
optionsMode: {
|
|
192
188
|
control: 'inline-radio',
|
|
193
189
|
options: ['normal', 'search', 'dynamic'],
|
|
@@ -209,12 +205,8 @@ Default.args = {
|
|
|
209
205
|
label: 'Dropdown',
|
|
210
206
|
defaultOptionLabel: 'Default Option',
|
|
211
207
|
noMatchesLabel: 'No matches',
|
|
212
|
-
border: undefined,
|
|
213
208
|
isInvalid: false,
|
|
214
209
|
errorMessage: 'Error Text',
|
|
215
|
-
errorPosition: 'bottom',
|
|
216
|
-
hasFloatingLabel: true,
|
|
217
|
-
hasRequiredLabel: true,
|
|
218
210
|
isDisabled: false,
|
|
219
211
|
isReadonly: false,
|
|
220
212
|
isRequired: false,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { mergeStyles } from '@true-engineering/true-react-platform-helpers';
|
|
2
|
-
import { animations, createThemedStyles, type ITweakStyles } from '../../theme';
|
|
2
|
+
import { animations, createThemedStyles, dimensions, type ITweakStyles } from '../../theme';
|
|
3
|
+
import { IControlGroupStyles } from '../ControlGroup';
|
|
3
4
|
import { type IInputStyles } from '../Input';
|
|
4
5
|
import { type ISearchInputStyles } from '../SearchInput';
|
|
5
6
|
import { type ISelectListStyles } from './components';
|
|
6
7
|
|
|
8
|
+
const { CONTROL, Z_INDEX } = dimensions;
|
|
9
|
+
|
|
7
10
|
export const useStyles = createThemedStyles('Select', {
|
|
8
11
|
root: {
|
|
9
12
|
width: '100%',
|
|
@@ -26,7 +29,8 @@ export const useStyles = createThemedStyles('Select', {
|
|
|
26
29
|
|
|
27
30
|
withoutPopper: {
|
|
28
31
|
position: 'absolute',
|
|
29
|
-
top: '
|
|
32
|
+
top: '100%',
|
|
33
|
+
paddingTop: 4,
|
|
30
34
|
},
|
|
31
35
|
|
|
32
36
|
listWrapperInBody: {
|
|
@@ -38,17 +42,18 @@ export const useStyles = createThemedStyles('Select', {
|
|
|
38
42
|
arrow: {
|
|
39
43
|
position: 'absolute',
|
|
40
44
|
right: 12,
|
|
41
|
-
top:
|
|
45
|
+
top: '50%',
|
|
42
46
|
width: 20,
|
|
43
47
|
height: 20,
|
|
44
48
|
cursor: 'pointer',
|
|
45
|
-
|
|
49
|
+
transform: 'translateY(-50%)',
|
|
46
50
|
transition: animations.defaultTransition,
|
|
47
51
|
transitionProperty: 'transform',
|
|
52
|
+
zIndex: Z_INDEX.CONTROL_FOCUS + 1,
|
|
48
53
|
},
|
|
49
54
|
|
|
50
55
|
activeArrow: {
|
|
51
|
-
transform: 'rotate(180deg)',
|
|
56
|
+
transform: 'translateY(-50%) rotate(180deg)',
|
|
52
57
|
},
|
|
53
58
|
|
|
54
59
|
disabled: {
|
|
@@ -64,24 +69,31 @@ export const useStyles = createThemedStyles('Select', {
|
|
|
64
69
|
},
|
|
65
70
|
|
|
66
71
|
icon: {
|
|
67
|
-
width:
|
|
68
|
-
height:
|
|
72
|
+
width: CONTROL.ICON_INNER_SIZE,
|
|
73
|
+
height: CONTROL.ICON_INNER_SIZE,
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
iconWrapper: {
|
|
77
|
+
display: 'flex',
|
|
78
|
+
alignItems: 'center',
|
|
69
79
|
},
|
|
70
80
|
});
|
|
71
81
|
|
|
72
82
|
const baseInputStyles: IInputStyles = {
|
|
73
|
-
|
|
83
|
+
inputContent: {
|
|
74
84
|
paddingRight: 32,
|
|
75
85
|
},
|
|
76
86
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
tweakControlWrapper: {
|
|
88
|
+
controls: {
|
|
89
|
+
paddingRight: 40,
|
|
80
90
|
},
|
|
81
|
-
},
|
|
82
91
|
|
|
83
|
-
|
|
84
|
-
|
|
92
|
+
icon: {
|
|
93
|
+
'&:last-child': {
|
|
94
|
+
paddingRight: 0,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
85
97
|
},
|
|
86
98
|
};
|
|
87
99
|
|
|
@@ -91,21 +103,8 @@ const readonlyInputBaseStyles: IInputStyles = {
|
|
|
91
103
|
},
|
|
92
104
|
};
|
|
93
105
|
|
|
94
|
-
const multiSelectInputBaseStyles: IInputStyles = {
|
|
95
|
-
inputIcon: {
|
|
96
|
-
'&:not($loading)': {
|
|
97
|
-
width: 'auto',
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
};
|
|
101
|
-
|
|
102
106
|
export const readonlyInputStyles = mergeStyles(baseInputStyles, readonlyInputBaseStyles);
|
|
103
|
-
export const
|
|
104
|
-
export const readonlyMultiSelectStyles = mergeStyles(
|
|
105
|
-
baseInputStyles,
|
|
106
|
-
readonlyInputBaseStyles,
|
|
107
|
-
multiSelectInputBaseStyles,
|
|
108
|
-
);
|
|
107
|
+
export const readonlyMultiSelectStyles = mergeStyles(baseInputStyles, readonlyInputBaseStyles);
|
|
109
108
|
|
|
110
109
|
export const getInputStyles = ({
|
|
111
110
|
hasReadonlyInput,
|
|
@@ -120,26 +119,13 @@ export const getInputStyles = ({
|
|
|
120
119
|
if (hasReadonlyInput && !isMultiSelect) {
|
|
121
120
|
return readonlyInputStyles;
|
|
122
121
|
}
|
|
123
|
-
if (!hasReadonlyInput && isMultiSelect) {
|
|
124
|
-
return multiSelectInputStyles;
|
|
125
|
-
}
|
|
126
122
|
return baseInputStyles;
|
|
127
123
|
};
|
|
128
124
|
|
|
129
|
-
export const searchInputStyles: ISearchInputStyles = {
|
|
130
|
-
tweakInput: {
|
|
131
|
-
inputWrapper: {
|
|
132
|
-
height: 48,
|
|
133
|
-
borderRadius: 0,
|
|
134
|
-
border: 'none',
|
|
135
|
-
backgroundColor: 'transparent',
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
};
|
|
139
|
-
|
|
140
125
|
export type ISelectStyles = ITweakStyles<
|
|
141
126
|
typeof useStyles,
|
|
142
127
|
{
|
|
128
|
+
tweakControlGroup: IControlGroupStyles;
|
|
143
129
|
tweakInput: IInputStyles;
|
|
144
130
|
tweakSelectList: ISelectListStyles;
|
|
145
131
|
tweakSearchInput: ISearchInputStyles;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
-
useCallback,
|
|
3
|
-
useEffect,
|
|
4
|
-
useMemo,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
2
|
ChangeEvent,
|
|
8
3
|
CSSProperties,
|
|
9
4
|
FocusEvent,
|
|
10
|
-
FormEvent,
|
|
11
5
|
KeyboardEvent,
|
|
12
6
|
MouseEvent,
|
|
13
7
|
ReactNode,
|
|
14
8
|
SyntheticEvent,
|
|
9
|
+
useCallback,
|
|
10
|
+
useEffect,
|
|
11
|
+
useMemo,
|
|
12
|
+
useRef,
|
|
13
|
+
useState,
|
|
15
14
|
} from 'react';
|
|
16
15
|
import { Portal } from 'react-overlays';
|
|
17
16
|
import clsx from 'clsx';
|
|
@@ -26,10 +25,11 @@ import {
|
|
|
26
25
|
} from '@true-engineering/true-react-platform-helpers';
|
|
27
26
|
import { hasExactParent } from '../../helpers';
|
|
28
27
|
import { useDropdown, useIsMounted, useOnClickOutsideWithRef, useTweakStyles } from '../../hooks';
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
28
|
+
import { ICommonProps, IDropdownWithPopperOptions } from '../../types';
|
|
29
|
+
import { ControlGroup } from '../ControlGroup';
|
|
30
|
+
import { IIcon, renderIcon } from '../Icon';
|
|
31
|
+
import { IChangeInputEvent, IInputProps, InputBase } from '../Input';
|
|
32
|
+
import { ISearchInputProps, SearchInput } from '../SearchInput';
|
|
33
33
|
import { SelectList } from './components';
|
|
34
34
|
import { ALL_OPTION_INDEX, DEFAULT_OPTION_INDEX } from './constants';
|
|
35
35
|
import {
|
|
@@ -38,8 +38,8 @@ import {
|
|
|
38
38
|
defaultIsOptionDisabled,
|
|
39
39
|
getDefaultConvertToIdFunction,
|
|
40
40
|
} from './helpers';
|
|
41
|
-
import { IMultipleSelectValue } from './types';
|
|
42
|
-
import { getInputStyles,
|
|
41
|
+
import { IChangeSelectEvent, IMultipleSelectValue } from './types';
|
|
42
|
+
import { getInputStyles, ISelectStyles, useStyles } from './Select.styles';
|
|
43
43
|
|
|
44
44
|
export interface ISelectProps<Value>
|
|
45
45
|
extends Omit<IInputProps, 'value' | 'onChange' | 'onBlur' | 'type' | 'tweakStyles'>,
|
|
@@ -66,14 +66,7 @@ export interface ISelectProps<Value>
|
|
|
66
66
|
isMultiSelect?: false;
|
|
67
67
|
searchInput?: { shouldRenderInList: true } & Pick<ISearchInputProps, 'placeholder'>;
|
|
68
68
|
isOptionDisabled?: (option: Value) => boolean;
|
|
69
|
-
onChange: (
|
|
70
|
-
value: Value | undefined,
|
|
71
|
-
event:
|
|
72
|
-
| MouseEvent<HTMLElement>
|
|
73
|
-
| KeyboardEvent
|
|
74
|
-
| ChangeEvent<HTMLElement>
|
|
75
|
-
| FormEvent<HTMLElement>,
|
|
76
|
-
) => void; // подумать как возвращать индекс
|
|
69
|
+
onChange: (value: Value | undefined, event: IChangeSelectEvent) => void; // подумать как возвращать индекс
|
|
77
70
|
onBlur?: (event: Event | SyntheticEvent) => void;
|
|
78
71
|
onType?: (value: string) => Promise<void>;
|
|
79
72
|
optionsFilter?: (options: Value[], query: string) => Value[];
|
|
@@ -94,14 +87,7 @@ export interface IMultipleSelectProps<Value>
|
|
|
94
87
|
> {
|
|
95
88
|
isMultiSelect: true;
|
|
96
89
|
value: IMultipleSelectValue<Value> | undefined;
|
|
97
|
-
onChange: (
|
|
98
|
-
value: IMultipleSelectValue<Value> | undefined,
|
|
99
|
-
event:
|
|
100
|
-
| MouseEvent<HTMLElement>
|
|
101
|
-
| KeyboardEvent
|
|
102
|
-
| ChangeEvent<HTMLElement>
|
|
103
|
-
| FormEvent<HTMLElement>,
|
|
104
|
-
) => void;
|
|
90
|
+
onChange: (value: IMultipleSelectValue<Value> | undefined, event: IChangeSelectEvent) => void;
|
|
105
91
|
compareValuesOnChange?: (
|
|
106
92
|
v1?: IMultipleSelectValue<Value>,
|
|
107
93
|
v2?: IMultipleSelectValue<Value>,
|
|
@@ -133,7 +119,7 @@ export function Select<Value>(
|
|
|
133
119
|
dropdownIcon = 'chevron-down',
|
|
134
120
|
shouldScrollToList = true,
|
|
135
121
|
searchInput,
|
|
136
|
-
|
|
122
|
+
icon,
|
|
137
123
|
onChange,
|
|
138
124
|
onFocus,
|
|
139
125
|
onBlur,
|
|
@@ -145,6 +131,8 @@ export function Select<Value>(
|
|
|
145
131
|
convertValueToId,
|
|
146
132
|
convertValueToReactNode,
|
|
147
133
|
optionsFilter,
|
|
134
|
+
infoMessage,
|
|
135
|
+
errorMessage,
|
|
148
136
|
...inputProps
|
|
149
137
|
} = props;
|
|
150
138
|
const classes = useStyles({ theme: tweakStyles });
|
|
@@ -154,6 +142,12 @@ export function Select<Value>(
|
|
|
154
142
|
const hasSearchInputInList = optionsMode !== 'normal' && shouldRenderSearchInputInList;
|
|
155
143
|
const hasReadonlyInput = isReadonly || optionsMode === 'normal' || shouldRenderSearchInputInList;
|
|
156
144
|
|
|
145
|
+
const tweakControlGroupStyles = useTweakStyles({
|
|
146
|
+
tweakStyles,
|
|
147
|
+
className: 'tweakControlGroup',
|
|
148
|
+
currentComponentName: 'Select',
|
|
149
|
+
});
|
|
150
|
+
|
|
157
151
|
const tweakInputStyles = useTweakStyles({
|
|
158
152
|
innerStyles: getInputStyles({ hasReadonlyInput, isMultiSelect }),
|
|
159
153
|
tweakStyles,
|
|
@@ -162,7 +156,6 @@ export function Select<Value>(
|
|
|
162
156
|
});
|
|
163
157
|
|
|
164
158
|
const tweakSearchInputStyles = useTweakStyles({
|
|
165
|
-
innerStyles: searchInputStyles,
|
|
166
159
|
tweakStyles,
|
|
167
160
|
className: 'tweakSearchInput',
|
|
168
161
|
currentComponentName: 'Select',
|
|
@@ -249,7 +242,7 @@ export function Select<Value>(
|
|
|
249
242
|
);
|
|
250
243
|
|
|
251
244
|
const getDropdownOffset = () => {
|
|
252
|
-
if (isEmpty(input.current)
|
|
245
|
+
if (isEmpty(input.current)) {
|
|
253
246
|
return 0;
|
|
254
247
|
}
|
|
255
248
|
|
|
@@ -325,14 +318,7 @@ export function Select<Value>(
|
|
|
325
318
|
};
|
|
326
319
|
|
|
327
320
|
const handleChange = useCallback(
|
|
328
|
-
(
|
|
329
|
-
newValue: Value | IMultipleSelectValue<Value> | undefined,
|
|
330
|
-
event:
|
|
331
|
-
| MouseEvent<HTMLElement>
|
|
332
|
-
| KeyboardEvent
|
|
333
|
-
| ChangeEvent<HTMLElement>
|
|
334
|
-
| FormEvent<HTMLElement>,
|
|
335
|
-
) => {
|
|
321
|
+
(newValue: Value | IMultipleSelectValue<Value> | undefined, event: IChangeSelectEvent) => {
|
|
336
322
|
// Тут беда с типами, сорри
|
|
337
323
|
if (!compareValuesOnChange(value as never, newValue as never)) {
|
|
338
324
|
onChange(newValue as (Value & IMultipleSelectValue<Value>) | undefined, event);
|
|
@@ -403,7 +389,7 @@ export function Select<Value>(
|
|
|
403
389
|
[handleOnType, debounceTime],
|
|
404
390
|
);
|
|
405
391
|
|
|
406
|
-
const handleInputChange = (v: string, event:
|
|
392
|
+
const handleInputChange = (v: string, event: IChangeInputEvent) => {
|
|
407
393
|
if (onType !== undefined) {
|
|
408
394
|
debounceHandleOnType(v);
|
|
409
395
|
}
|
|
@@ -603,56 +589,62 @@ export function Select<Value>(
|
|
|
603
589
|
);
|
|
604
590
|
|
|
605
591
|
const multiSelectCounterWithIcon =
|
|
606
|
-
shouldShowMultiSelectCounter || isNotEmpty(
|
|
607
|
-
|
|
592
|
+
shouldShowMultiSelectCounter || isNotEmpty(icon) ? (
|
|
593
|
+
<div className={classes.iconWrapper}>
|
|
608
594
|
{shouldShowMultiSelectCounter && (
|
|
609
595
|
<div className={classes.counter}>(+{value.length - 1})</div>
|
|
610
596
|
)}
|
|
611
|
-
{isNotEmpty(
|
|
612
|
-
|
|
597
|
+
{isNotEmpty(icon) && <div className={classes.icon}>{renderIcon(icon)}</div>}
|
|
598
|
+
</div>
|
|
613
599
|
) : undefined;
|
|
614
600
|
|
|
615
601
|
return (
|
|
616
|
-
<
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
>
|
|
622
|
-
<Input
|
|
623
|
-
value={
|
|
624
|
-
searchValue !== '' && !shouldRenderSearchInputInList ? searchValue : showedStringValue
|
|
625
|
-
}
|
|
626
|
-
onChange={handleInputChange}
|
|
627
|
-
isActive={isListOpen || isActive}
|
|
628
|
-
isReadonly={hasReadonlyInput}
|
|
629
|
-
onFocus={handleFocus}
|
|
630
|
-
onBlur={handleBlur}
|
|
631
|
-
isDisabled={isDisabled}
|
|
632
|
-
ref={input}
|
|
633
|
-
isLoading={areOptionsLoading}
|
|
634
|
-
tweakStyles={tweakInputStyles}
|
|
635
|
-
testId={testId}
|
|
636
|
-
iconType={isMultiSelect ? multiSelectCounterWithIcon : iconType}
|
|
637
|
-
{...inputProps}
|
|
638
|
-
/>
|
|
602
|
+
<ControlGroup
|
|
603
|
+
errorMessage={errorMessage}
|
|
604
|
+
infoMessage={infoMessage}
|
|
605
|
+
tweakStyles={tweakControlGroupStyles}
|
|
606
|
+
>
|
|
607
|
+
<div className={classes.root} onKeyDown={handleKeyDown} ref={root}>
|
|
639
608
|
<div
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
}
|
|
643
|
-
onClick={onArrowClick}
|
|
644
|
-
className={clsx(classes.arrow, isOpen && classes.activeArrow)}
|
|
609
|
+
className={clsx(classes.inputWrapper, isDisabled && classes.disabled)}
|
|
610
|
+
onClick={isDisabled || isReadonly ? undefined : handleOnClick}
|
|
611
|
+
ref={inputWrapper}
|
|
645
612
|
>
|
|
646
|
-
|
|
613
|
+
<InputBase
|
|
614
|
+
value={
|
|
615
|
+
searchValue !== '' && !shouldRenderSearchInputInList ? searchValue : showedStringValue
|
|
616
|
+
}
|
|
617
|
+
onChange={handleInputChange}
|
|
618
|
+
isActive={isListOpen || isActive}
|
|
619
|
+
isReadonly={hasReadonlyInput}
|
|
620
|
+
onFocus={handleFocus}
|
|
621
|
+
onBlur={handleBlur}
|
|
622
|
+
isDisabled={isDisabled}
|
|
623
|
+
ref={input}
|
|
624
|
+
isLoading={areOptionsLoading}
|
|
625
|
+
tweakStyles={tweakInputStyles}
|
|
626
|
+
testId={testId}
|
|
627
|
+
icon={isMultiSelect ? multiSelectCounterWithIcon : icon}
|
|
628
|
+
{...inputProps}
|
|
629
|
+
/>
|
|
630
|
+
<div
|
|
631
|
+
onMouseDown={(event: MouseEvent) => {
|
|
632
|
+
event.preventDefault();
|
|
633
|
+
}}
|
|
634
|
+
onClick={onArrowClick}
|
|
635
|
+
className={clsx(classes.arrow, isOpen && classes.activeArrow)}
|
|
636
|
+
>
|
|
637
|
+
{renderIcon(dropdownIcon)}
|
|
638
|
+
</div>
|
|
647
639
|
</div>
|
|
640
|
+
{shouldUsePopper ? (
|
|
641
|
+
<Portal container={shouldRenderInBody ? document.body : inputWrapper.current}>
|
|
642
|
+
<>{listEl}</>
|
|
643
|
+
</Portal>
|
|
644
|
+
) : (
|
|
645
|
+
<>{isOpen && listEl}</>
|
|
646
|
+
)}
|
|
648
647
|
</div>
|
|
649
|
-
|
|
650
|
-
<Portal container={shouldRenderInBody ? document.body : inputWrapper.current}>
|
|
651
|
-
<>{listEl}</>
|
|
652
|
-
</Portal>
|
|
653
|
-
) : (
|
|
654
|
-
<>{isOpen && listEl}</>
|
|
655
|
-
)}
|
|
656
|
-
</div>
|
|
648
|
+
</ControlGroup>
|
|
657
649
|
);
|
|
658
650
|
}
|