@astral/ui 4.106.0 → 4.108.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.
- package/components/AsyncAutocomplete/useLogic/useLogic.d.ts +1 -0
- package/components/Autocomplete/Autocomplete.d.ts +1 -0
- package/components/Autocomplete/Autocomplete.js +12 -8
- package/components/Autocomplete/constants.d.ts +1 -0
- package/components/Autocomplete/constants.js +1 -0
- package/components/Autocomplete/styles.d.ts +4 -0
- package/components/Autocomplete/styles.js +9 -0
- package/components/Autocomplete/types.d.ts +4 -0
- package/components/Autocomplete/useLogic/useLogic.d.ts +11 -4
- package/components/Autocomplete/useLogic/useLogic.js +77 -11
- package/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/checkIsFocusedHelperChange.d.ts +4 -0
- package/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/checkIsFocusedHelperChange.js +17 -0
- package/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/index.d.ts +1 -0
- package/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/index.js +1 -0
- package/components/Autocomplete/useLogic/utils/checkIsPopperVisible/checkIsPopperVisible.d.ts +8 -0
- package/components/Autocomplete/useLogic/utils/checkIsPopperVisible/checkIsPopperVisible.js +6 -0
- package/components/Autocomplete/useLogic/utils/checkIsPopperVisible/index.d.ts +1 -0
- package/components/Autocomplete/useLogic/utils/checkIsPopperVisible/index.js +1 -0
- package/components/Autocomplete/useLogic/utils/index.d.ts +2 -0
- package/components/Autocomplete/useLogic/utils/index.js +2 -0
- package/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.d.ts +5 -0
- package/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.js +7 -0
- package/components/Autocomplete/utils/checkIsFocusedHelperOption/index.d.ts +1 -0
- package/components/Autocomplete/utils/checkIsFocusedHelperOption/index.js +1 -0
- package/components/Autocomplete/utils/index.d.ts +1 -0
- package/components/Autocomplete/utils/index.js +1 -0
- package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +1 -1
- package/components/Select/Select.js +4 -3
- package/components/Select/useLogic/useLogic.d.ts +11 -2
- package/components/Select/useLogic/useLogic.js +4 -1
- package/components/TagsList/PopoverTags/PopoverTags.d.ts +7 -0
- package/components/TagsList/PopoverTags/PopoverTags.js +8 -0
- package/components/TagsList/PopoverTags/index.d.ts +2 -0
- package/components/TagsList/PopoverTags/index.js +2 -0
- package/components/TagsList/PopoverTags/styles.d.ts +8 -0
- package/components/TagsList/PopoverTags/styles.js +15 -0
- package/components/TagsList/PopoverTags/types.d.ts +24 -0
- package/components/TagsList/PopoverTags/types.js +1 -0
- package/components/TagsList/Tag/Tag.d.ts +9 -1
- package/components/TagsList/Tag/Tag.js +4 -3
- package/components/TagsList/TagsList.js +11 -5
- package/components/TagsList/constants.d.ts +35 -0
- package/components/TagsList/constants.js +35 -0
- package/components/TagsList/styles.d.ts +9 -1
- package/components/TagsList/styles.js +20 -1
- package/components/TagsList/types.d.ts +4 -0
- package/components/TagsList/useLogic/hooks/index.d.ts +1 -0
- package/components/TagsList/useLogic/hooks/index.js +1 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/index.d.ts +1 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/index.js +1 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/types.d.ts +20 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/types.js +1 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/useHoverDelay.d.ts +5 -0
- package/components/TagsList/useLogic/hooks/useHoverDelay/useHoverDelay.js +27 -0
- package/components/TagsList/useLogic/useLogic.d.ts +14 -2
- package/components/TagsList/useLogic/useLogic.js +84 -4
- package/components/TagsList/utils/calculatePopoverWidth/calculatePopoverWidth.d.ts +5 -0
- package/components/TagsList/utils/calculatePopoverWidth/calculatePopoverWidth.js +22 -0
- package/components/TagsList/utils/calculatePopoverWidth/index.d.ts +1 -0
- package/components/TagsList/utils/calculatePopoverWidth/index.js +1 -0
- package/components/TagsList/utils/index.d.ts +1 -0
- package/components/TagsList/utils/index.js +1 -0
- package/components/TreeLikeAsyncAutocomplete/Input/Input.js +3 -2
- package/components/TreeLikeAsyncAutocomplete/Input/useLogic/useLogic.d.ts +3 -2
- package/components/TreeLikeAsyncAutocomplete/Input/useLogic/useLogic.js +3 -1
- package/components/TreeLikeAutocomplete/Input/Input.js +2 -2
- package/components/TreeLikeAutocomplete/Input/useLogic/useLogic.d.ts +2 -1
- package/components/TreeLikeAutocomplete/Input/useLogic/useLogic.js +3 -1
- package/node/components/AsyncAutocomplete/useLogic/useLogic.d.ts +1 -0
- package/node/components/Autocomplete/Autocomplete.d.ts +1 -0
- package/node/components/Autocomplete/Autocomplete.js +11 -7
- package/node/components/Autocomplete/constants.d.ts +1 -0
- package/node/components/Autocomplete/constants.js +2 -1
- package/node/components/Autocomplete/styles.d.ts +4 -0
- package/node/components/Autocomplete/styles.js +10 -1
- package/node/components/Autocomplete/types.d.ts +4 -0
- package/node/components/Autocomplete/useLogic/useLogic.d.ts +11 -4
- package/node/components/Autocomplete/useLogic/useLogic.js +77 -11
- package/node/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/checkIsFocusedHelperChange.d.ts +4 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/checkIsFocusedHelperChange.js +21 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/index.d.ts +1 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsFocusedHelperChange/index.js +17 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsPopperVisible/checkIsPopperVisible.d.ts +8 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsPopperVisible/checkIsPopperVisible.js +10 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsPopperVisible/index.d.ts +1 -0
- package/node/components/Autocomplete/useLogic/utils/checkIsPopperVisible/index.js +5 -0
- package/node/components/Autocomplete/useLogic/utils/index.d.ts +2 -0
- package/node/components/Autocomplete/useLogic/utils/index.js +2 -0
- package/node/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.d.ts +5 -0
- package/node/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.js +11 -0
- package/node/components/Autocomplete/utils/checkIsFocusedHelperOption/index.d.ts +1 -0
- package/node/components/Autocomplete/utils/checkIsFocusedHelperOption/index.js +17 -0
- package/node/components/Autocomplete/utils/index.d.ts +1 -0
- package/node/components/Autocomplete/utils/index.js +17 -0
- package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +1 -1
- package/node/components/Select/Select.js +4 -3
- package/node/components/Select/useLogic/useLogic.d.ts +11 -2
- package/node/components/Select/useLogic/useLogic.js +4 -1
- package/node/components/TagsList/PopoverTags/PopoverTags.d.ts +7 -0
- package/node/components/TagsList/PopoverTags/PopoverTags.js +12 -0
- package/node/components/TagsList/PopoverTags/index.d.ts +2 -0
- package/node/components/TagsList/PopoverTags/index.js +18 -0
- package/node/components/TagsList/PopoverTags/styles.d.ts +8 -0
- package/node/components/TagsList/PopoverTags/styles.js +18 -0
- package/node/components/TagsList/PopoverTags/types.d.ts +24 -0
- package/node/components/TagsList/PopoverTags/types.js +2 -0
- package/node/components/TagsList/Tag/Tag.d.ts +9 -1
- package/node/components/TagsList/Tag/Tag.js +4 -4
- package/node/components/TagsList/TagsList.js +10 -4
- package/node/components/TagsList/constants.d.ts +35 -0
- package/node/components/TagsList/constants.js +36 -1
- package/node/components/TagsList/styles.d.ts +9 -1
- package/node/components/TagsList/styles.js +20 -1
- package/node/components/TagsList/types.d.ts +4 -0
- package/node/components/TagsList/useLogic/hooks/index.d.ts +1 -0
- package/node/components/TagsList/useLogic/hooks/index.js +17 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/index.d.ts +1 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/index.js +17 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/types.d.ts +20 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/types.js +2 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/useHoverDelay.d.ts +5 -0
- package/node/components/TagsList/useLogic/hooks/useHoverDelay/useHoverDelay.js +31 -0
- package/node/components/TagsList/useLogic/useLogic.d.ts +14 -2
- package/node/components/TagsList/useLogic/useLogic.js +81 -1
- package/node/components/TagsList/utils/calculatePopoverWidth/calculatePopoverWidth.d.ts +5 -0
- package/node/components/TagsList/utils/calculatePopoverWidth/calculatePopoverWidth.js +26 -0
- package/node/components/TagsList/utils/calculatePopoverWidth/index.d.ts +1 -0
- package/node/components/TagsList/utils/calculatePopoverWidth/index.js +17 -0
- package/node/components/TagsList/utils/index.d.ts +1 -0
- package/node/components/TagsList/utils/index.js +3 -1
- package/node/components/TreeLikeAsyncAutocomplete/Input/Input.js +3 -2
- package/node/components/TreeLikeAsyncAutocomplete/Input/useLogic/useLogic.d.ts +3 -2
- package/node/components/TreeLikeAsyncAutocomplete/Input/useLogic/useLogic.js +3 -1
- package/node/components/TreeLikeAutocomplete/Input/Input.js +2 -2
- package/node/components/TreeLikeAutocomplete/Input/useLogic/useLogic.d.ts +2 -1
- package/node/components/TreeLikeAutocomplete/Input/useLogic/useLogic.js +3 -1
- package/package.json +1 -1
|
@@ -366,6 +366,7 @@ export declare const useLogic: <TOptions, TMultiple extends boolean, TDisableCle
|
|
|
366
366
|
openOnFocus?: boolean | undefined;
|
|
367
367
|
selectOnFocus?: boolean | undefined;
|
|
368
368
|
loadedDataError?: string | undefined;
|
|
369
|
+
focusedHelperText?: string | undefined;
|
|
369
370
|
overflowOption?: import("../..").OverflowedElementProps | undefined;
|
|
370
371
|
options: TOptions[];
|
|
371
372
|
disabled: boolean | undefined;
|
|
@@ -18,4 +18,5 @@ export declare const Autocomplete: <TAutocompleteValueProps, TMultiple extends b
|
|
|
18
18
|
openText?: string | undefined;
|
|
19
19
|
clearText?: string | undefined;
|
|
20
20
|
hideHelperText?: boolean | undefined;
|
|
21
|
+
focusedHelperText?: string | undefined;
|
|
21
22
|
} & import("react").RefAttributes<unknown>) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | null;
|
|
@@ -10,21 +10,23 @@ import { Loader } from '../Loader';
|
|
|
10
10
|
import { OverflowTypography } from '../OverflowTypography';
|
|
11
11
|
import { TagsList } from '../TagsList';
|
|
12
12
|
import { TextField } from '../TextField';
|
|
13
|
+
import { Typography } from '../Typography';
|
|
13
14
|
import { cn } from '../utils/cn';
|
|
14
15
|
import { DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT, DEFAULT_PLACEHOLDER, INPUT_MIN_WIDTH, } from './constants';
|
|
15
|
-
import { StyledAutocomplete, StyledMenuItem } from './styles';
|
|
16
|
+
import { StyledAutocomplete, StyledFocusedHelperOption, StyledMenuItem, } from './styles';
|
|
16
17
|
import { useLogic } from './useLogic';
|
|
18
|
+
import { checkIsFocusedHelperOption } from './utils';
|
|
17
19
|
const AutocompleteInner = (props, ref) => {
|
|
18
20
|
const { isValueEmpty, isPopperVisible, autocompleteProps } = useLogic(props);
|
|
19
21
|
const inputBaseRef = useRef(null);
|
|
20
|
-
const { required, success, error, label, getOptionLabel, helperText, inputRef, multiple, size = 'medium', placeholder = DEFAULT_PLACEHOLDER, overflowOption, closeText = 'Закрыть', openText = 'Открыть', clearText = 'Очистить', loadingText = _jsx(Loader, {}), isLoadedDataError, loadedDataError, noOptionsText, autoHighlight, renderInput: externalRenderInput, renderTags: externalRenderTags, renderOption: externalRenderOption, inputProps, hideHelperText = false, loading, value, onChange, ...restProps } = props;
|
|
22
|
+
const { required, success, error, label, getOptionLabel, helperText, inputRef, multiple, size = 'medium', placeholder = DEFAULT_PLACEHOLDER, overflowOption, closeText = 'Закрыть', openText = 'Открыть', clearText = 'Очистить', loadingText = _jsx(Loader, {}), isLoadedDataError, loadedDataError, noOptionsText, autoHighlight, renderInput: externalRenderInput, renderTags: externalRenderTags, renderOption: externalRenderOption, inputProps, hideHelperText = false, focusedHelperText, loading, value, onChange, ...restProps } = props;
|
|
21
23
|
const renderInput = useCallback((inputParams) => {
|
|
22
24
|
const createStartAdornment = () => {
|
|
23
25
|
if (!multiple || !Array.isArray(value)) {
|
|
24
26
|
return null;
|
|
25
27
|
}
|
|
26
|
-
|
|
27
|
-
option.toString(), inputContainerRef: inputBaseRef, reservedWidth: INPUT_MIN_WIDTH, onChange: (tagValues) => {
|
|
28
|
+
return (_jsx(TagsList, { data: value, getOptionLabel: (option) => getOptionLabel?.(option) ??
|
|
29
|
+
option.toString(), inputContainerRef: inputBaseRef, fieldRef: inputBaseRef, reservedWidth: INPUT_MIN_WIDTH, onChange: (tagValues) => {
|
|
28
30
|
if (!onChange) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
@@ -36,7 +38,6 @@ const AutocompleteInner = (props, ref) => {
|
|
|
36
38
|
const reason = 'removeOption';
|
|
37
39
|
onChange(syntheticEvent, tagValues, reason);
|
|
38
40
|
} }));
|
|
39
|
-
return tagsListElement;
|
|
40
41
|
};
|
|
41
42
|
const generalInputParams = {
|
|
42
43
|
...inputParams,
|
|
@@ -94,13 +95,16 @@ const AutocompleteInner = (props, ref) => {
|
|
|
94
95
|
onChange,
|
|
95
96
|
]);
|
|
96
97
|
const renderOption = useCallback((optionProps, option, optionState, ownerState) => {
|
|
98
|
+
const { key, ...restOptionProps } = optionProps;
|
|
99
|
+
if (checkIsFocusedHelperOption(option)) {
|
|
100
|
+
return (_jsx(StyledFocusedHelperOption, { role: "presentation", ...restOptionProps, children: _jsx(Typography, { variant: "body1", color: "grey", colorIntensity: "600", children: focusedHelperText }) }, key));
|
|
101
|
+
}
|
|
97
102
|
if (externalRenderOption) {
|
|
98
103
|
return externalRenderOption(optionProps, option, optionState, ownerState);
|
|
99
104
|
}
|
|
100
105
|
const isSelected = Boolean(optionProps['aria-selected']);
|
|
101
|
-
const { key, ...restOptionProps } = optionProps;
|
|
102
106
|
return (_jsxs(StyledMenuItem, { selected: isSelected, ...restOptionProps, children: [multiple && (_jsx(ListItemIcon, { children: _jsx(Checkbox, { role: "menuitemcheckbox", checked: isSelected }) })), _jsx(OverflowTypography, { rowsCount: DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT, ...overflowOption, children: optionProps.key })] }, key));
|
|
103
|
-
}, [multiple, overflowOption, externalRenderOption]);
|
|
107
|
+
}, [focusedHelperText, multiple, overflowOption, externalRenderOption]);
|
|
104
108
|
const renderPopper = useCallback((popperProps) => {
|
|
105
109
|
if (!isPopperVisible) {
|
|
106
110
|
return null;
|
|
@@ -117,6 +121,6 @@ const AutocompleteInner = (props, ref) => {
|
|
|
117
121
|
popper: {
|
|
118
122
|
component: renderPopper,
|
|
119
123
|
},
|
|
120
|
-
},
|
|
124
|
+
}, renderInput: renderInput, renderTags: renderTags, renderOption: renderOption, value: value, ...autocompleteProps }));
|
|
121
125
|
};
|
|
122
126
|
export const Autocomplete = forwardRefWithGeneric(AutocompleteInner);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT = 2;
|
|
2
2
|
export declare const INPUT_MIN_WIDTH = 110;
|
|
3
3
|
export declare const DEFAULT_PLACEHOLDER = "\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u0432\u0432\u043E\u0434\u0438\u0442\u044C \u0434\u043B\u044F \u043F\u043E\u0438\u0441\u043A\u0430";
|
|
4
|
+
export declare const FOCUSED_HELPER_OPTION: unique symbol;
|
|
4
5
|
export declare const autocompleteClassnames: {
|
|
5
6
|
root: string;
|
|
6
7
|
multiple: string;
|
|
@@ -2,6 +2,7 @@ import { createUIKitClassname } from '../utils/createUIKitClassname';
|
|
|
2
2
|
export const DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT = 2;
|
|
3
3
|
export const INPUT_MIN_WIDTH = 110;
|
|
4
4
|
export const DEFAULT_PLACEHOLDER = 'Начните вводить для поиска';
|
|
5
|
+
export const FOCUSED_HELPER_OPTION = Symbol('focusedHelperOption');
|
|
5
6
|
export const autocompleteClassnames = {
|
|
6
7
|
root: createUIKitClassname('autocomplete'),
|
|
7
8
|
multiple: createUIKitClassname('autocomplete_multiple'),
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import MuiAutocomplete from '@mui/material/Autocomplete';
|
|
3
|
+
export declare const StyledFocusedHelperOption: import("../styled").StyledComponent<{
|
|
4
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
5
|
+
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
6
|
+
}, import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, {}>;
|
|
3
7
|
export declare const StyledMenuItem: import("../styled").StyledComponent<import("..").WithoutEmotionSpecific<Omit<import("@mui/material").MenuItemProps, "component">> & {
|
|
4
8
|
disabledReason?: string | undefined;
|
|
5
9
|
note?: string | undefined;
|
|
@@ -7,6 +7,15 @@ import { MenuItem } from '../MenuItem';
|
|
|
7
7
|
import { svgIconClassnames } from '../SvgIcon';
|
|
8
8
|
import { styled } from '../styled';
|
|
9
9
|
import { autocompleteClassnames, INPUT_MIN_WIDTH } from './constants';
|
|
10
|
+
export const StyledFocusedHelperOption = styled.li `
|
|
11
|
+
&&.${autocompleteClasses.option} {
|
|
12
|
+
display: flex;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
align-items: center;
|
|
15
|
+
height: 48px;
|
|
16
|
+
opacity: 1;
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
10
19
|
export const StyledMenuItem = styled(MenuItem) `
|
|
11
20
|
max-height: ${({ theme }) => theme.spacing(13)};
|
|
12
21
|
|
|
@@ -48,4 +48,8 @@ export type AutocompleteProps<TAutocompleteValueProps, TMultiple extends boolean
|
|
|
48
48
|
* Включает/отключает резервирование места под helperText
|
|
49
49
|
*/
|
|
50
50
|
hideHelperText?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Текст подсказки в popover при фокусе
|
|
53
|
+
*/
|
|
54
|
+
focusedHelperText?: string;
|
|
51
55
|
};
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import { type AutocompleteInputChangeReason } from '@mui/material
|
|
1
|
+
import { type AutocompleteChangeDetails, type AutocompleteChangeReason, type AutocompleteFreeSoloValueMapping, type AutocompleteInputChangeReason, type AutocompleteValue } from '@mui/material';
|
|
2
2
|
import { type SyntheticEvent } from 'react';
|
|
3
3
|
import { type AutocompleteProps } from '../types';
|
|
4
4
|
type UseLogicParams<TAutocompleteValueProps, TMultiple extends boolean, TDisableClearable extends boolean, TFreeSolo extends boolean> = AutocompleteProps<TAutocompleteValueProps, TMultiple, TDisableClearable, TFreeSolo>;
|
|
5
|
-
export declare const useLogic: <TAutocompleteValueProps, TMultiple extends boolean, TDisableClearable extends boolean, TFreeSolo extends boolean>({ value, isOptionEqualToValue: externalOptionEqualToValue, autoHighlight, freeSolo, options, multiple, className, loading, isLoadedDataError, loadedDataError, noOptionsText, onInputChange, }: UseLogicParams<TAutocompleteValueProps, TMultiple, TDisableClearable, TFreeSolo>) => {
|
|
5
|
+
export declare const useLogic: <TAutocompleteValueProps, TMultiple extends boolean, TDisableClearable extends boolean, TFreeSolo extends boolean>({ value, inputValue, getOptionLabel: externalGetOptionLabel, isOptionEqualToValue: externalOptionEqualToValue, getOptionDisabled: externalGetOptionDisabled, filterOptions: externalFilterOptions, groupBy: externalGroupBy, openOnFocus, autoHighlight, freeSolo, options, multiple, className, loading, isLoadedDataError, loadedDataError, noOptionsText, focusedHelperText, onInputChange, onChange, }: UseLogicParams<TAutocompleteValueProps, TMultiple, TDisableClearable, TFreeSolo>) => {
|
|
6
6
|
isValueEmpty: boolean;
|
|
7
|
-
isPopperVisible: boolean
|
|
7
|
+
isPopperVisible: boolean;
|
|
8
8
|
autocompleteProps: {
|
|
9
9
|
className: string;
|
|
10
10
|
isOptionEqualToValue: (option: TAutocompleteValueProps, currentValue: TAutocompleteValueProps) => boolean;
|
|
11
|
+
getOptionDisabled: (option: TAutocompleteValueProps) => boolean;
|
|
11
12
|
autoHighlight: boolean;
|
|
12
|
-
noOptionsText: string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | null;
|
|
13
|
+
noOptionsText: string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | null | undefined;
|
|
14
|
+
options: readonly TAutocompleteValueProps[];
|
|
15
|
+
getOptionLabel: (option: TAutocompleteValueProps | AutocompleteFreeSoloValueMapping<TFreeSolo>) => string;
|
|
16
|
+
filterOptions: ((options: TAutocompleteValueProps[], state: import("@mui/material").FilterOptionsState<TAutocompleteValueProps>) => TAutocompleteValueProps[]) | undefined;
|
|
17
|
+
groupBy: ((option: TAutocompleteValueProps) => string) | undefined;
|
|
18
|
+
onChange: (event: SyntheticEvent, newValue: AutocompleteValue<TAutocompleteValueProps, TMultiple, TDisableClearable, TFreeSolo>, reason: AutocompleteChangeReason, details?: AutocompleteChangeDetails<TAutocompleteValueProps> | undefined) => void;
|
|
13
19
|
onInputChange: (event: SyntheticEvent, currentValue: string, reason: AutocompleteInputChangeReason) => void;
|
|
20
|
+
openOnFocus: boolean;
|
|
14
21
|
};
|
|
15
22
|
};
|
|
16
23
|
export {};
|
|
@@ -1,22 +1,81 @@
|
|
|
1
1
|
import { useCallback, useMemo, useState } from 'react';
|
|
2
2
|
import { cn } from '../../utils/cn';
|
|
3
|
-
import { autocompleteClassnames } from '../constants';
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import { autocompleteClassnames, FOCUSED_HELPER_OPTION } from '../constants';
|
|
4
|
+
import { checkIsFocusedHelperOption } from '../utils';
|
|
5
|
+
import { checkIsFocusedHelperChange, checkIsInputEmpty, checkIsPopperVisible, } from './utils';
|
|
6
|
+
export const useLogic = ({ value, inputValue, getOptionLabel: externalGetOptionLabel, isOptionEqualToValue: externalOptionEqualToValue, getOptionDisabled: externalGetOptionDisabled, filterOptions: externalFilterOptions, groupBy: externalGroupBy, openOnFocus, autoHighlight = true, freeSolo, options, multiple, className, loading, isLoadedDataError, loadedDataError = 'Ошибка загрузки данных', noOptionsText = 'Нет данных', focusedHelperText, onInputChange, onChange, }) => {
|
|
6
7
|
const [innerInputValue, setInnerInputValue] = useState('');
|
|
7
8
|
const isValueEmpty = checkIsInputEmpty(value);
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const isInputTextEmpty = (inputValue ?? '').length === 0 && innerInputValue.length === 0;
|
|
10
|
+
const hasOptions = options.length > 0;
|
|
11
|
+
const hasFocusedHelperText = Boolean(focusedHelperText);
|
|
12
|
+
const shouldShowFocusedHelper = hasFocusedHelperText &&
|
|
13
|
+
isInputTextEmpty &&
|
|
14
|
+
!hasOptions &&
|
|
15
|
+
!loading &&
|
|
16
|
+
!isLoadedDataError;
|
|
17
|
+
const isPopperVisible = checkIsPopperVisible({
|
|
18
|
+
loading,
|
|
19
|
+
hasOptions,
|
|
20
|
+
isInputValueNotEmpty: !isInputTextEmpty,
|
|
21
|
+
isLoadedDataError,
|
|
22
|
+
shouldShowFocusedHelper,
|
|
23
|
+
});
|
|
24
|
+
const hasFocusedHelperOption = shouldShowFocusedHelper && Boolean(freeSolo);
|
|
25
|
+
const resolvedNoOptionsText = useMemo(() => {
|
|
26
|
+
if (isLoadedDataError) {
|
|
27
|
+
return loadedDataError;
|
|
28
|
+
}
|
|
29
|
+
if (shouldShowFocusedHelper) {
|
|
30
|
+
return focusedHelperText;
|
|
31
|
+
}
|
|
32
|
+
return noOptionsText;
|
|
33
|
+
}, [
|
|
34
|
+
isLoadedDataError,
|
|
35
|
+
loadedDataError,
|
|
36
|
+
shouldShowFocusedHelper,
|
|
37
|
+
focusedHelperText,
|
|
38
|
+
noOptionsText,
|
|
39
|
+
]);
|
|
40
|
+
const autocompleteOptions = useMemo(() => {
|
|
41
|
+
if (hasFocusedHelperOption) {
|
|
42
|
+
return [FOCUSED_HELPER_OPTION];
|
|
43
|
+
}
|
|
44
|
+
return options;
|
|
45
|
+
}, [hasFocusedHelperOption, options]);
|
|
46
|
+
const resolveGetOptionLabel = useCallback((option) => {
|
|
47
|
+
if (checkIsFocusedHelperOption(option)) {
|
|
48
|
+
return focusedHelperText ?? '';
|
|
49
|
+
}
|
|
50
|
+
if (externalGetOptionLabel) {
|
|
51
|
+
return externalGetOptionLabel(option);
|
|
52
|
+
}
|
|
53
|
+
const optionWithLabel = option;
|
|
54
|
+
return optionWithLabel.label ?? String(option);
|
|
55
|
+
}, [externalGetOptionLabel, focusedHelperText]);
|
|
56
|
+
const handleChange = useCallback((event, newValue, reason, details) => {
|
|
57
|
+
if (checkIsFocusedHelperChange(newValue, details?.option)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
onChange?.(event, newValue, reason, details);
|
|
61
|
+
}, [onChange]);
|
|
14
62
|
const isOptionEqualToValue = useCallback((option, currentValue) => {
|
|
63
|
+
if (checkIsFocusedHelperOption(option) ||
|
|
64
|
+
checkIsFocusedHelperOption(currentValue)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
15
67
|
if (externalOptionEqualToValue) {
|
|
16
68
|
return externalOptionEqualToValue(option, currentValue);
|
|
17
69
|
}
|
|
18
70
|
return JSON.stringify(option) === JSON.stringify(currentValue);
|
|
19
71
|
}, [externalOptionEqualToValue]);
|
|
72
|
+
const resolveGetOptionDisabled = useCallback((option) => {
|
|
73
|
+
if (checkIsFocusedHelperOption(option)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return externalGetOptionDisabled?.(option) ?? false;
|
|
77
|
+
}, [externalGetOptionDisabled]);
|
|
78
|
+
const resolvedOpenOnFocus = hasFocusedHelperText || Boolean(openOnFocus);
|
|
20
79
|
const handleInputChange = (event, currentValue, reason) => {
|
|
21
80
|
onInputChange?.(event, currentValue, reason);
|
|
22
81
|
if (!loading) {
|
|
@@ -28,16 +87,23 @@ export const useLogic = ({ value, isOptionEqualToValue: externalOptionEqualToVal
|
|
|
28
87
|
[autocompleteClassnames.multiple]: multiple,
|
|
29
88
|
[autocompleteClassnames.emptyValue]: isValueEmpty,
|
|
30
89
|
});
|
|
31
|
-
}, [multiple, isValueEmpty]);
|
|
90
|
+
}, [className, multiple, isValueEmpty]);
|
|
32
91
|
return {
|
|
33
92
|
isValueEmpty,
|
|
34
93
|
isPopperVisible,
|
|
35
94
|
autocompleteProps: {
|
|
36
95
|
className: classnames,
|
|
37
96
|
isOptionEqualToValue,
|
|
97
|
+
getOptionDisabled: resolveGetOptionDisabled,
|
|
38
98
|
autoHighlight: freeSolo ? false : autoHighlight,
|
|
39
|
-
noOptionsText:
|
|
99
|
+
noOptionsText: resolvedNoOptionsText,
|
|
100
|
+
options: autocompleteOptions,
|
|
101
|
+
getOptionLabel: resolveGetOptionLabel,
|
|
102
|
+
filterOptions: hasFocusedHelperOption ? undefined : externalFilterOptions,
|
|
103
|
+
groupBy: hasFocusedHelperOption ? undefined : externalGroupBy,
|
|
104
|
+
onChange: handleChange,
|
|
40
105
|
onInputChange: handleInputChange,
|
|
106
|
+
openOnFocus: resolvedOpenOnFocus,
|
|
41
107
|
},
|
|
42
108
|
};
|
|
43
109
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { checkIsFocusedHelperOption } from '../../../utils';
|
|
2
|
+
/**
|
|
3
|
+
* Проверяет, является ли значение при onChange focusedHelper-опцией (freeSolo)
|
|
4
|
+
*/
|
|
5
|
+
export const checkIsFocusedHelperChange = (newValue, changedOption) => {
|
|
6
|
+
if (checkIsFocusedHelperOption(changedOption)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
if (checkIsFocusedHelperOption(newValue)) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(newValue) &&
|
|
13
|
+
newValue.some((item) => checkIsFocusedHelperOption(item))) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperChange';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperChange';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type CheckIsPopperVisibleParams = {
|
|
2
|
+
loading?: boolean;
|
|
3
|
+
hasOptions: boolean;
|
|
4
|
+
isInputValueNotEmpty: boolean;
|
|
5
|
+
isLoadedDataError?: boolean;
|
|
6
|
+
shouldShowFocusedHelper: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const checkIsPopperVisible: ({ loading, hasOptions, isInputValueNotEmpty, isLoadedDataError, shouldShowFocusedHelper, }: CheckIsPopperVisibleParams) => boolean;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const checkIsPopperVisible = ({ loading = false, hasOptions, isInputValueNotEmpty, isLoadedDataError = false, shouldShowFocusedHelper, }) => {
|
|
2
|
+
if (shouldShowFocusedHelper || hasOptions || isLoadedDataError) {
|
|
3
|
+
return true;
|
|
4
|
+
}
|
|
5
|
+
return !loading && isInputValueNotEmpty;
|
|
6
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { checkIsPopperVisible, type CheckIsPopperVisibleParams, } from './checkIsPopperVisible';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { checkIsPopperVisible, } from './checkIsPopperVisible';
|
package/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FOCUSED_HELPER_OPTION } from '../../constants';
|
|
2
|
+
/**
|
|
3
|
+
* Определяет, является ли опция специальной опцией для отображения focusedHelperText при freeSolo=true
|
|
4
|
+
*/
|
|
5
|
+
export declare const checkIsFocusedHelperOption: (option: unknown) => option is typeof FOCUSED_HELPER_OPTION;
|
package/components/Autocomplete/utils/checkIsFocusedHelperOption/checkIsFocusedHelperOption.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FOCUSED_HELPER_OPTION } from '../../constants';
|
|
2
|
+
/**
|
|
3
|
+
* Определяет, является ли опция специальной опцией для отображения focusedHelperText при freeSolo=true
|
|
4
|
+
*/
|
|
5
|
+
export const checkIsFocusedHelperOption = (option) => {
|
|
6
|
+
return option === FOCUSED_HELPER_OPTION;
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperOption';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperOption';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperOption';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './checkIsFocusedHelperOption';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const StepPopover: import("../../../../../styled").StyledComponent<Omit<import("../../../../../NewPopover").NewPopoverProps, "title" | "
|
|
2
|
+
export declare const StepPopover: import("../../../../../styled").StyledComponent<Omit<import("../../../../../NewPopover").NewPopoverProps, "title" | "hasArrow" | "disableMobileDrawer"> & {
|
|
3
3
|
variant?: import("../../../../../HintPopover").HintPopoverVariant | undefined;
|
|
4
4
|
title?: import("react").ReactNode;
|
|
5
5
|
action?: import("react").ReactNode;
|
|
@@ -18,7 +18,7 @@ import { EndAdornmentWrapper, Placeholder, StateWrapper, StyledSelect, } from '.
|
|
|
18
18
|
import { useLogic } from './useLogic';
|
|
19
19
|
const ClearButton = forwardRef(({ onClick, disabled }, ref) => (_jsx(IconButton, { disabled: disabled, ref: ref, onClick: onClick, variant: "text", title: CLEAR_TEXT, "aria-label": CLEAR_TEXT, children: _jsx(CrossOutlineMd, {}) })));
|
|
20
20
|
const SelectInner = ({ required, getOptionLabel, placeholder, helperText, hideHelperText = false, loading, success, children, disabled, error, label, fullWidth, onChange: externalOnChange, isShowClearButton, isEnableAllSelection = false, valueOptions, value, onSelectAll, onUnselectAll, ...props }, ref) => {
|
|
21
|
-
const { isOpened, isShowingClearButton, isNoData, onClearAll, openSelect, closeSelect, resetButtonRef, isShowingSelectAll, handleChangeOption, isSelectedAll, isIndeterminate, handleChangeArrayValue, selectAllClassName, findMenuItemsLabel, isShowingPlaceholder, } = useLogic({
|
|
21
|
+
const { isOpened, isShowingClearButton, isNoData, onClearAll, openSelect, closeSelect, resetButtonRef, isShowingSelectAll, handleChangeOption, isSelectedAll, isIndeterminate, handleChangeArrayValue, selectAllClassName, findMenuItemsLabel, isShowingPlaceholder, fieldRef, } = useLogic({
|
|
22
22
|
...props,
|
|
23
23
|
children,
|
|
24
24
|
value,
|
|
@@ -30,11 +30,12 @@ const SelectInner = ({ required, getOptionLabel, placeholder, helperText, hideHe
|
|
|
30
30
|
onSelectAll,
|
|
31
31
|
onUnselectAll,
|
|
32
32
|
loading,
|
|
33
|
+
ref,
|
|
33
34
|
});
|
|
34
35
|
const renderValue = (selectedOptions) => {
|
|
35
36
|
// Массив с выбранными опциями
|
|
36
37
|
if (Array.isArray(selectedOptions) && selectedOptions.length) {
|
|
37
|
-
return (_jsx(TagsList, { data: selectedOptions, getOptionLabel: getOptionLabel || ((optionLabel) => optionLabel), onChange: handleChangeArrayValue, onClick: openSelect }));
|
|
38
|
+
return (_jsx(TagsList, { data: selectedOptions, getOptionLabel: getOptionLabel || ((optionLabel) => optionLabel), fieldRef: fieldRef, onChange: handleChangeArrayValue, onClick: openSelect }));
|
|
38
39
|
}
|
|
39
40
|
// Пустой массив или пустая строка
|
|
40
41
|
if ((Array.isArray(selectedOptions) || typeof selectedOptions === 'string') &&
|
|
@@ -47,6 +48,6 @@ const SelectInner = ({ required, getOptionLabel, placeholder, helperText, hideHe
|
|
|
47
48
|
}
|
|
48
49
|
return findMenuItemsLabel(children, selectedOptions);
|
|
49
50
|
};
|
|
50
|
-
return (_jsxs(FormControl, { error: error, fullWidth: fullWidth, children: [label && (_jsx(InputLabel, { htmlFor: "grouped-select", required: required, disabled: disabled, children: label })), _jsxs(StyledSelect, { ...props, value: value === null || value === undefined ? '' : value, open: isOpened, disabled: disabled, onOpen: openSelect, onClose: closeSelect, renderValue: renderValue, IconComponent: () => null, displayEmpty: true, ref:
|
|
51
|
+
return (_jsxs(FormControl, { error: error, fullWidth: fullWidth, children: [label && (_jsx(InputLabel, { htmlFor: "grouped-select", required: required, disabled: disabled, children: label })), _jsxs(StyledSelect, { ...props, value: value === null || value === undefined ? '' : value, open: isOpened, disabled: disabled, onOpen: openSelect, onClose: closeSelect, renderValue: renderValue, IconComponent: () => null, displayEmpty: true, ref: fieldRef, fullWidth: fullWidth, onChange: handleChangeOption, "$isShowingPlaceholder": isShowingPlaceholder, endAdornment: _jsxs(EndAdornmentWrapper, { children: [loading && _jsx(Loader, { color: "primary", size: "small" }), !loading && isShowingClearButton && (_jsx(ClearButton, { disabled: disabled, ref: resetButtonRef, onClick: onClearAll })), !loading && (_jsx(IconButton, { variant: "text", disabled: disabled, onClick: openSelect, children: !isOpened ? _jsx(DownOutlineMd, {}) : _jsx(UpOutlineMd, {}) }))] }), children: [_jsx(Placeholder, { value: "", children: placeholder }), !loading && isShowingSelectAll && (_jsxs(MenuItem, { className: selectAllClassName, selected: isSelectedAll, value: SELECT_ALL_VALUE, children: [_jsx(ListItemIcon, { children: _jsx(Checkbox, { checked: isSelectedAll, indeterminate: isIndeterminate }) }), "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u0441\u0435"] })), !loading && children, !loading && isNoData && _jsx(StateWrapper, { children: "\u041D\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0445" })] }), _jsx(FormHelperText, { error: error, success: success, hideHelperText: hideHelperText, children: helperText })] }));
|
|
51
52
|
};
|
|
52
53
|
export const Select = forwardRefWithGeneric(SelectInner);
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { type ReactNode, type SyntheticEvent } from 'react';
|
|
1
|
+
import { type ForwardedRef, type ReactNode, type SyntheticEvent } from 'react';
|
|
2
2
|
import { type SelectProps } from '../types';
|
|
3
|
-
|
|
3
|
+
type UseLogicParams<TValue> = Omit<SelectProps<TValue>, 'ref'> & {
|
|
4
|
+
/**
|
|
5
|
+
* Ref, пробрасываемый на контейнер поля: по нему считается ширина
|
|
6
|
+
* всплывающего окна тэгов и он служит якорем его позиционирования
|
|
7
|
+
*/
|
|
8
|
+
ref: ForwardedRef<HTMLDivElement>;
|
|
9
|
+
};
|
|
10
|
+
export declare const useLogic: <TValue>({ value, onChange, children, open: externalIsOpened, defaultOpen, multiple, isEnableAllSelection, isShowClearButton, valueOptions, onSelectAll, onUnselectAll, name, placeholder, onClose, onOpen, loading, ref, }: UseLogicParams<TValue>) => {
|
|
4
11
|
isOpened: boolean;
|
|
5
12
|
isNoData: boolean;
|
|
6
13
|
isShowingClearButton: boolean;
|
|
@@ -17,4 +24,6 @@ export declare const useLogic: <TValue>({ value, onChange, children, open: exter
|
|
|
17
24
|
selectAllClassName: string | undefined;
|
|
18
25
|
findMenuItemsLabel: (nodes: ReactNode, selectedValue: TValue) => ReactNode;
|
|
19
26
|
isShowingPlaceholder: boolean;
|
|
27
|
+
fieldRef: import("react").RefObject<HTMLDivElement | null>;
|
|
20
28
|
};
|
|
29
|
+
export {};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { menuItemClasses } from '@mui/material/MenuItem';
|
|
2
2
|
import { Children, isValidElement, useRef, useState, } from 'react';
|
|
3
3
|
import { MenuItem } from '../../MenuItem';
|
|
4
|
+
import { useForwardedRef } from '../../useForwardedRef';
|
|
4
5
|
import { getNodeText } from '../../utils/getNodeText';
|
|
5
6
|
import { isSyncReactElement } from '../../utils/isSyncReactElement';
|
|
6
7
|
import { SELECT_ALL_VALUE } from '../constants';
|
|
7
8
|
import { isShowingPlaceholder } from './utils/isShowingPlaceholder';
|
|
8
|
-
export const useLogic = ({ value, onChange, children, open: externalIsOpened, defaultOpen, multiple, isEnableAllSelection, isShowClearButton = true, valueOptions, onSelectAll, onUnselectAll, name, placeholder, onClose, onOpen, loading, }) => {
|
|
9
|
+
export const useLogic = ({ value, onChange, children, open: externalIsOpened, defaultOpen, multiple, isEnableAllSelection, isShowClearButton = true, valueOptions, onSelectAll, onUnselectAll, name, placeholder, onClose, onOpen, loading, ref, }) => {
|
|
9
10
|
const [isOpened, setOpened] = useState(!loading && (defaultOpen || externalIsOpened || false));
|
|
11
|
+
const fieldRef = useForwardedRef(ref);
|
|
10
12
|
const resetButtonRef = useRef(null);
|
|
11
13
|
const optionsLength = Array.isArray(valueOptions)
|
|
12
14
|
? valueOptions?.length
|
|
@@ -129,5 +131,6 @@ export const useLogic = ({ value, onChange, children, open: externalIsOpened, de
|
|
|
129
131
|
selectAllClassName,
|
|
130
132
|
findMenuItemsLabel,
|
|
131
133
|
isShowingPlaceholder: isShowingPlaceholder(value, placeholder),
|
|
134
|
+
fieldRef,
|
|
132
135
|
};
|
|
133
136
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TagValue } from '../types';
|
|
2
|
+
import { type PopoverTagsProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Показывает все выбранные элементы тэгами с переносом по строкам.
|
|
5
|
+
* Используется как содержимое всплывающего окна TagsList
|
|
6
|
+
*/
|
|
7
|
+
export declare const PopoverTags: <TData extends TagValue>({ data, keyId, isDisabled, getOptionLabel, getTagProps, }: PopoverTagsProps<TData>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getKey } from '../utils';
|
|
3
|
+
import { StyledTag, Wrapper } from './styles';
|
|
4
|
+
/**
|
|
5
|
+
* Показывает все выбранные элементы тэгами с переносом по строкам.
|
|
6
|
+
* Используется как содержимое всплывающего окна TagsList
|
|
7
|
+
*/
|
|
8
|
+
export const PopoverTags = ({ data, keyId, isDisabled, getOptionLabel, getTagProps, }) => (_jsx(Wrapper, { children: data.map((option) => (_jsx(StyledTag, { isDisabled: isDisabled, ...getTagProps(option) }, getKey(option, keyId, getOptionLabel)))) }));
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare const Wrapper: import("../../styled").StyledComponent<{
|
|
3
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
4
|
+
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
5
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
6
|
+
export declare const StyledTag: import("../../styled").StyledComponent<import("../Tag").TagProps & import("react").RefAttributes<HTMLDivElement> & {
|
|
7
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
8
|
+
}, {}, {}>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { styled } from '../../styled';
|
|
2
|
+
import { POPOVER_MAX_HEIGHT, POPOVER_TAGS_GAP_SPACING, POPOVER_TAGS_PADDING_SPACING, } from '../constants';
|
|
3
|
+
import { Tag } from '../Tag';
|
|
4
|
+
export const Wrapper = styled.div `
|
|
5
|
+
overflow-y: auto;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-wrap: wrap;
|
|
8
|
+
gap: ${({ theme }) => theme.spacing(POPOVER_TAGS_GAP_SPACING)};
|
|
9
|
+
|
|
10
|
+
max-height: ${POPOVER_MAX_HEIGHT}px;
|
|
11
|
+
padding-inline: ${({ theme }) => theme.spacing(POPOVER_TAGS_PADDING_SPACING)};
|
|
12
|
+
`;
|
|
13
|
+
export const StyledTag = styled(Tag) `
|
|
14
|
+
max-width: 100%;
|
|
15
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type TagProps } from '../Tag';
|
|
2
|
+
import { type TagValue } from '../types';
|
|
3
|
+
export type PopoverTagsProps<TData extends TagValue = TagValue> = {
|
|
4
|
+
/**
|
|
5
|
+
* Полный список выбранных элементов
|
|
6
|
+
*/
|
|
7
|
+
data: TData[];
|
|
8
|
+
/**
|
|
9
|
+
* Поле, используемое в качестве ключа списка
|
|
10
|
+
*/
|
|
11
|
+
keyId?: TData extends object ? keyof TData : never;
|
|
12
|
+
/**
|
|
13
|
+
* Если `true`, то тэги будут недоступны для взаимодействия
|
|
14
|
+
*/
|
|
15
|
+
isDisabled?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Используется для определения строкового значения опции
|
|
18
|
+
*/
|
|
19
|
+
getOptionLabel: (value: TData) => string | number;
|
|
20
|
+
/**
|
|
21
|
+
* Возвращает пропсы тэга, включая обработчик удаления
|
|
22
|
+
*/
|
|
23
|
+
getTagProps: (option: TData) => Pick<TagProps, 'label' | 'onDelete'>;
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -21,9 +21,17 @@ export type TagProps = {
|
|
|
21
21
|
* Хендлер клика по тегу
|
|
22
22
|
*/
|
|
23
23
|
onClick?: (value: MouseEvent<HTMLDivElement>) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Хендлер наведения указателя на тег
|
|
26
|
+
*/
|
|
27
|
+
onMouseEnter?: (value: MouseEvent<HTMLDivElement>) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Хендлер увода указателя с тега
|
|
30
|
+
*/
|
|
31
|
+
onMouseLeave?: (value: MouseEvent<HTMLDivElement>) => void;
|
|
24
32
|
/**
|
|
25
33
|
* Название класса, применяется к корневому компоненту
|
|
26
34
|
*/
|
|
27
35
|
className?: string;
|
|
28
36
|
};
|
|
29
|
-
export declare const Tag: (
|
|
37
|
+
export declare const Tag: import("react").ForwardRefExoticComponent<TagProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
2
3
|
import { OverflowTypography } from '../../OverflowTypography';
|
|
3
4
|
import { StyledTag } from './styles';
|
|
4
5
|
import { useLogic } from './useLogic';
|
|
5
|
-
export const Tag = (props) => {
|
|
6
|
+
export const Tag = forwardRef((props, ref) => {
|
|
6
7
|
const { onMouseDown } = useLogic();
|
|
7
8
|
const { shrinks, isDisabled, label, ...restProps } = props;
|
|
8
|
-
return (_jsx(StyledTag, { "$shrinks": shrinks, color: "grey", variant: "light", disabled: isDisabled, label: _jsx(OverflowTypography, { children: label }), ...restProps, onMouseDown: onMouseDown }));
|
|
9
|
-
};
|
|
9
|
+
return (_jsx(StyledTag, { ref: ref, "$shrinks": shrinks, color: "grey", variant: "light", disabled: isDisabled, label: _jsx(OverflowTypography, { children: label }), ...restProps, onMouseDown: onMouseDown }));
|
|
10
|
+
});
|