@snack-uikit/chips 0.12.9 → 0.13.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/CHANGELOG.md +18 -0
- package/README.md +22 -104
- package/dist/components/ChipAssist/styles.module.css +1 -1
- package/dist/components/ChipChoice/components/ChipChoiceBase/ChipChoiceBase.d.ts +20 -0
- package/dist/components/ChipChoice/components/ChipChoiceBase/ChipChoiceBase.js +65 -0
- package/dist/components/ChipChoice/components/ChipChoiceBase/index.d.ts +1 -0
- package/dist/components/ChipChoice/components/ChipChoiceBase/index.js +1 -0
- package/dist/components/ChipChoice/components/{ChipChoiceCustom → ChipChoiceBase}/styles.module.css +18 -10
- package/dist/components/ChipChoice/components/ChipChoiceCustom.d.ts +25 -0
- package/dist/components/ChipChoice/components/ChipChoiceCustom.js +38 -0
- package/dist/components/ChipChoice/components/ChipChoiceDate.d.ts +3 -2
- package/dist/components/ChipChoice/components/ChipChoiceDate.js +19 -9
- package/dist/components/ChipChoice/components/ChipChoiceDateRange.d.ts +3 -2
- package/dist/components/ChipChoice/components/ChipChoiceDateRange.js +18 -8
- package/dist/components/ChipChoice/components/ChipChoiceMultiple.d.ts +8 -0
- package/dist/components/ChipChoice/components/ChipChoiceMultiple.js +87 -0
- package/dist/components/ChipChoice/components/ChipChoiceSingle.d.ts +7 -13
- package/dist/components/ChipChoice/components/ChipChoiceSingle.js +64 -22
- package/dist/components/ChipChoice/components/index.d.ts +1 -1
- package/dist/components/ChipChoice/components/index.js +1 -1
- package/dist/components/ChipChoice/constants.d.ts +3 -2
- package/dist/components/ChipChoice/constants.js +2 -1
- package/dist/components/ChipChoice/hooks.d.ts +11 -0
- package/dist/components/ChipChoice/hooks.js +35 -0
- package/dist/components/ChipChoice/index.d.ts +5 -4
- package/dist/components/ChipChoice/index.js +3 -2
- package/dist/components/ChipChoice/styles.module.css +9 -5
- package/dist/components/ChipChoice/types.d.ts +55 -7
- package/dist/components/ChipChoice/utils/index.d.ts +2 -0
- package/dist/components/ChipChoice/utils/index.js +2 -0
- package/dist/components/ChipChoice/utils/options.d.ts +9 -0
- package/dist/components/ChipChoice/utils/options.js +32 -0
- package/dist/components/ChipChoice/utils/typeGuards.d.ts +6 -0
- package/dist/components/ChipChoice/utils/typeGuards.js +15 -0
- package/dist/components/ChipChoice/utils/utils.d.ts +18 -0
- package/dist/components/ChipChoice/utils/utils.js +29 -0
- package/dist/components/ChipChoiceRow/components/constants.d.ts +2 -1
- package/dist/components/ChipChoiceRow/components/constants.js +2 -1
- package/dist/components/ChipChoiceRow/types.d.ts +11 -5
- package/dist/components/ChipToggle/styles.module.css +1 -1
- package/package.json +13 -7
- package/src/components/ChipChoice/components/ChipChoiceBase/ChipChoiceBase.tsx +149 -0
- package/src/components/ChipChoice/components/ChipChoiceBase/index.ts +1 -0
- package/src/components/ChipChoice/components/{ChipChoiceCustom → ChipChoiceBase}/styles.module.scss +11 -5
- package/src/components/ChipChoice/components/ChipChoiceCustom.tsx +89 -0
- package/src/components/ChipChoice/components/ChipChoiceDate.tsx +42 -18
- package/src/components/ChipChoice/components/ChipChoiceDateRange.tsx +43 -18
- package/src/components/ChipChoice/components/ChipChoiceMultiple.tsx +157 -0
- package/src/components/ChipChoice/components/ChipChoiceSingle.tsx +123 -62
- package/src/components/ChipChoice/components/index.ts +1 -1
- package/src/components/ChipChoice/constants.ts +3 -2
- package/src/components/ChipChoice/hooks.ts +61 -0
- package/src/components/ChipChoice/index.ts +7 -13
- package/src/components/ChipChoice/styles.module.scss +11 -5
- package/src/components/ChipChoice/types.ts +105 -7
- package/src/components/ChipChoice/utils/index.ts +3 -0
- package/src/components/ChipChoice/utils/options.tsx +58 -0
- package/src/components/ChipChoice/utils/typeGuards.ts +35 -0
- package/src/components/ChipChoice/utils/utils.ts +60 -0
- package/src/components/ChipChoiceRow/components/constants.ts +2 -1
- package/src/components/ChipChoiceRow/types.ts +18 -10
- package/dist/components/ChipChoice/components/ChipChoiceCustom/ChipChoiceCustom.d.ts +0 -23
- package/dist/components/ChipChoice/components/ChipChoiceCustom/ChipChoiceCustom.js +0 -75
- package/dist/components/ChipChoice/components/ChipChoiceCustom/index.d.ts +0 -1
- package/dist/components/ChipChoice/components/ChipChoiceCustom/index.js +0 -1
- package/dist/components/ChipChoice/components/ChipChoiceMulti.d.ts +0 -14
- package/dist/components/ChipChoice/components/ChipChoiceMulti.js +0 -44
- package/dist/components/ChipChoice/utils.d.ts +0 -14
- package/dist/components/ChipChoice/utils.js +0 -26
- package/src/components/ChipChoice/components/ChipChoiceCustom/ChipChoiceCustom.tsx +0 -188
- package/src/components/ChipChoice/components/ChipChoiceCustom/index.ts +0 -1
- package/src/components/ChipChoice/components/ChipChoiceMulti.tsx +0 -90
- package/src/components/ChipChoice/utils.ts +0 -48
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
|
+
import { Droplist } from '@snack-uikit/list';
|
|
15
|
+
import { useLocale } from '@snack-uikit/locale';
|
|
16
|
+
import { useValueControl } from '@snack-uikit/utils';
|
|
17
|
+
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
18
|
+
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
19
|
+
import { useFuzzySearch, useHandleOnKeyDown } from '../hooks';
|
|
20
|
+
import { kindFlattenOptions } from '../utils';
|
|
21
|
+
import { transformOptionsToItems } from '../utils/options';
|
|
22
|
+
import { ChipChoiceBase } from './ChipChoiceBase';
|
|
23
|
+
const defaultMultiValueLabelFormatter = ({ value, total, allLabel }) => {
|
|
24
|
+
if (value.length === 0 || value.length === total) {
|
|
25
|
+
return allLabel;
|
|
26
|
+
}
|
|
27
|
+
if (value.length === 1) {
|
|
28
|
+
return value[0].label;
|
|
29
|
+
}
|
|
30
|
+
return `${value.length.toString()}/${total}`;
|
|
31
|
+
};
|
|
32
|
+
export function ChipChoiceMultiple(_a) {
|
|
33
|
+
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName, showClearButton } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "showClearButton"]);
|
|
34
|
+
const [value, setValue] = useValueControl({
|
|
35
|
+
value: valueProp,
|
|
36
|
+
defaultValue,
|
|
37
|
+
onChange: onChangeProp,
|
|
38
|
+
});
|
|
39
|
+
const flattenOptions = useMemo(() => {
|
|
40
|
+
const { flattenOptions } = kindFlattenOptions({ options });
|
|
41
|
+
return flattenOptions;
|
|
42
|
+
}, [options]);
|
|
43
|
+
const [searchValue = '', setSearchValue] = useState('');
|
|
44
|
+
const { t } = useLocale('Chips');
|
|
45
|
+
const [open, setOpen] = useState(false);
|
|
46
|
+
const handleOnKeyDown = useHandleOnKeyDown({ setOpen });
|
|
47
|
+
const flatMapOptions = useMemo(() => Object.values(flattenOptions), [flattenOptions]);
|
|
48
|
+
const selectedOptions = useMemo(() => (value && value.length ? value.map(id => flattenOptions[id]).filter(Boolean) : []), [flattenOptions, value]);
|
|
49
|
+
const valueToRender = valueRender
|
|
50
|
+
? valueRender(selectedOptions)
|
|
51
|
+
: defaultMultiValueLabelFormatter({
|
|
52
|
+
value: selectedOptions !== null && selectedOptions !== void 0 ? selectedOptions : [],
|
|
53
|
+
total: Object.keys(flattenOptions).length,
|
|
54
|
+
allLabel: t('allLabel'),
|
|
55
|
+
});
|
|
56
|
+
const fuzzySearch = useFuzzySearch(options, flatMapOptions);
|
|
57
|
+
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)), [fuzzySearch, options, searchValue, searchable, valueToRender]);
|
|
58
|
+
const items = useMemo(() => transformOptionsToItems(result, contentRender), [contentRender, result]);
|
|
59
|
+
const clearValue = () => setValue([]);
|
|
60
|
+
const chipRef = useRef(null);
|
|
61
|
+
const handleSelectionChange = useCallback((newValue) => {
|
|
62
|
+
if (newValue !== undefined) {
|
|
63
|
+
setValue(newValue);
|
|
64
|
+
setSearchValue('');
|
|
65
|
+
}
|
|
66
|
+
}, [setValue]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (searchValue && !open) {
|
|
69
|
+
setSearchValue('');
|
|
70
|
+
}
|
|
71
|
+
}, [searchable, open, searchValue]);
|
|
72
|
+
return (_jsx(Droplist, Object.assign({}, rest, { items: items, selection: {
|
|
73
|
+
value,
|
|
74
|
+
onChange: handleSelectionChange,
|
|
75
|
+
mode: 'multiple',
|
|
76
|
+
}, trigger: 'clickAndFocusVisible', placement: 'bottom-start', widthStrategy: 'gte', size: DROPLIST_SIZE_MAP[size], "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, open: open, triggerElemRef: chipRef, onOpenChange: open => {
|
|
77
|
+
if (!open) {
|
|
78
|
+
setSearchValue('');
|
|
79
|
+
}
|
|
80
|
+
setOpen(open);
|
|
81
|
+
}, scroll: true, className: dropDownClassName, search: searchable
|
|
82
|
+
? {
|
|
83
|
+
value: searchValue,
|
|
84
|
+
onChange: setSearchValue,
|
|
85
|
+
}
|
|
86
|
+
: undefined, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: chipRef, onClearButtonClick: clearValue, value: value, showClearButton: showClearButton && !(Array.isArray(value) && [0, Object.keys(flattenOptions).length].includes(value.length)), valueToRender: valueToRender, label: label, loading: rest.loading, size: size, onKeyDown: handleOnKeyDown() })) })));
|
|
87
|
+
}
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
value?: string;
|
|
7
|
-
/** Значение компонента по умолчанию */
|
|
8
|
-
defaultValue?: string;
|
|
9
|
-
/** Колбек смены значения */
|
|
10
|
-
onChange?(value: string): void;
|
|
11
|
-
/** Колбек формирующий строковое представление выбранного значения. Принимает выбранное значение. По умолчанию для отображения используется FilterOption.label */
|
|
12
|
-
valueFormatter?(option?: FilterOption): string;
|
|
1
|
+
import { ItemId } from '@snack-uikit/list';
|
|
2
|
+
import { ChipChoiceSingleProps, ContentRenderProps } from '../types';
|
|
3
|
+
export type ChipChoiceSingleValueFormatterProps = {
|
|
4
|
+
label?: ItemId;
|
|
5
|
+
allLabel?: string;
|
|
13
6
|
};
|
|
14
|
-
export declare function
|
|
7
|
+
export declare function defaultSingleValueFormatter({ label, allLabel }: ChipChoiceSingleValueFormatterProps): ItemId | undefined;
|
|
8
|
+
export declare function ChipChoiceSingle<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, ...rest }: ChipChoiceSingleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,29 +10,71 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import { useUncontrolledProp } from 'uncontrollable';
|
|
16
|
-
import { Droplist } from '@snack-uikit/droplist';
|
|
13
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
|
+
import { Droplist } from '@snack-uikit/list';
|
|
17
15
|
import { useLocale } from '@snack-uikit/locale';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
16
|
+
import { useValueControl } from '@snack-uikit/utils';
|
|
17
|
+
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
18
|
+
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
19
|
+
import { useFuzzySearch, useHandleOnKeyDown } from '../hooks';
|
|
20
|
+
import { kindFlattenOptions } from '../utils';
|
|
21
|
+
import { transformOptionsToItems } from '../utils/options';
|
|
22
|
+
import { ChipChoiceBase } from './ChipChoiceBase';
|
|
23
|
+
export function defaultSingleValueFormatter({ label, allLabel }) {
|
|
24
|
+
return label !== null && label !== void 0 ? label : allLabel;
|
|
25
|
+
}
|
|
21
26
|
export function ChipChoiceSingle(_a) {
|
|
22
|
-
var { value, defaultValue, options, onChange,
|
|
23
|
-
const [
|
|
27
|
+
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName"]);
|
|
28
|
+
const [value, setValue] = useValueControl({
|
|
29
|
+
value: valueProp,
|
|
30
|
+
defaultValue,
|
|
31
|
+
onChange: onChangeProp,
|
|
32
|
+
});
|
|
33
|
+
const flattenOptions = useMemo(() => {
|
|
34
|
+
const { flattenOptions } = kindFlattenOptions({ options });
|
|
35
|
+
return flattenOptions;
|
|
36
|
+
}, [options]);
|
|
24
37
|
const { t } = useLocale('Chips');
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
const [open, setOpen] = useState(false);
|
|
39
|
+
const handleOnKeyDown = useHandleOnKeyDown({ setOpen });
|
|
40
|
+
const flatMapOptions = useMemo(() => Object.values(flattenOptions), [flattenOptions]);
|
|
41
|
+
const selectedOption = useMemo(() => (value ? flattenOptions[value] : {}), [flattenOptions, value]);
|
|
42
|
+
const [searchValue, setSearchValue] = useState('');
|
|
43
|
+
const valueToRender = valueRender
|
|
44
|
+
? valueRender(selectedOption)
|
|
45
|
+
: defaultSingleValueFormatter({ label: selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label, allLabel: t('allLabel') });
|
|
46
|
+
const fuzzySearch = useFuzzySearch(options, flatMapOptions);
|
|
47
|
+
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)), [fuzzySearch, options, searchValue, searchable, valueToRender]);
|
|
48
|
+
const items = useMemo(() => transformOptionsToItems(result, contentRender), [contentRender, result]);
|
|
49
|
+
const clearValue = () => setValue(undefined);
|
|
50
|
+
const chipRef = useRef(null);
|
|
51
|
+
const handleSelectionChange = useCallback((newValue) => {
|
|
52
|
+
var _a;
|
|
53
|
+
if (newValue !== undefined) {
|
|
54
|
+
(_a = chipRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
55
|
+
setOpen(false);
|
|
56
|
+
setValue(newValue);
|
|
57
|
+
setSearchValue('');
|
|
58
|
+
}
|
|
59
|
+
}, [setSearchValue, setValue]);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (searchValue && !open) {
|
|
62
|
+
setSearchValue('');
|
|
63
|
+
}
|
|
64
|
+
}, [searchable, open, searchValue]);
|
|
65
|
+
return (_jsx(Droplist, Object.assign({}, rest, { items: items, selection: {
|
|
66
|
+
value,
|
|
67
|
+
onChange: handleSelectionChange,
|
|
68
|
+
mode: 'single',
|
|
69
|
+
}, "data-test-id": CHIP_CHOICE_TEST_IDS.droplist, size: DROPLIST_SIZE_MAP[size], trigger: 'click', placement: 'bottom-start', className: dropDownClassName, widthStrategy: 'gte', open: open, triggerElemRef: chipRef, onOpenChange: open => {
|
|
70
|
+
if (!open) {
|
|
71
|
+
setSearchValue('');
|
|
72
|
+
}
|
|
73
|
+
setOpen(open);
|
|
74
|
+
}, scroll: true, search: searchable
|
|
75
|
+
? {
|
|
76
|
+
value: searchValue,
|
|
77
|
+
onChange: setSearchValue,
|
|
78
|
+
}
|
|
79
|
+
: undefined, children: _jsx(ChipChoiceBase, Object.assign({}, rest, { ref: chipRef, onClearButtonClick: clearValue, value: value, valueToRender: valueToRender, label: label, loading: rest.loading, size: size, onKeyDown: handleOnKeyDown() })) })));
|
|
38
80
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CalendarProps } from '@snack-uikit/calendar';
|
|
2
|
-
import { DroplistProps } from '@snack-uikit/
|
|
2
|
+
import { DroplistProps } from '@snack-uikit/list';
|
|
3
3
|
import { Size } from '../../types';
|
|
4
4
|
export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
|
|
5
5
|
xs: "xxs";
|
|
@@ -10,8 +10,9 @@ export declare const BUTTON_CLEAR_VALUE_SIZE_MAP: {
|
|
|
10
10
|
export declare const CALENDAR_SIZE_MAP: Record<Size, CalendarProps['size']>;
|
|
11
11
|
export declare const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']>;
|
|
12
12
|
export declare const CHIP_CHOICE_TYPE: {
|
|
13
|
-
readonly
|
|
13
|
+
readonly Multiple: "multiple";
|
|
14
14
|
readonly Date: "date";
|
|
15
15
|
readonly DateRange: "date-range";
|
|
16
16
|
readonly Single: "single";
|
|
17
|
+
readonly Custom: "custom";
|
|
17
18
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { KeyboardEvent, KeyboardEventHandler } from 'react';
|
|
2
|
+
import { AccordionOption, BaseOption, ContentRenderProps, FilterOption, NestListOption } from './types';
|
|
3
|
+
type UseHandleOnKeyDownProps = {
|
|
4
|
+
setOpen(open: boolean): void;
|
|
5
|
+
};
|
|
6
|
+
export declare function useHandleOnKeyDown({ setOpen }: UseHandleOnKeyDownProps): (onKeyDown?: KeyboardEventHandler<HTMLElement>) => (e: KeyboardEvent<HTMLDivElement>) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
9
|
+
*/
|
|
10
|
+
export declare function useFuzzySearch<T extends ContentRenderProps = ContentRenderProps>(options: FilterOption<T>[], flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[], minSearchInputLength?: number): (search: string) => FilterOption<T>[];
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import FuzzySearch from 'fuzzy-search';
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
export function useHandleOnKeyDown({ setOpen }) {
|
|
4
|
+
return useCallback((onKeyDown) => (e) => {
|
|
5
|
+
if (e.code === 'Space') {
|
|
6
|
+
e.stopPropagation();
|
|
7
|
+
}
|
|
8
|
+
else {
|
|
9
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
|
|
10
|
+
}
|
|
11
|
+
if (['ArrowDown'].includes(e.key)) {
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
setOpen(true);
|
|
14
|
+
}
|
|
15
|
+
if (['ArrowUp'].includes(e.key)) {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
setOpen(false);
|
|
18
|
+
}
|
|
19
|
+
if (e.key === 'Tab') {
|
|
20
|
+
setOpen(false);
|
|
21
|
+
}
|
|
22
|
+
}, [setOpen]);
|
|
23
|
+
}
|
|
24
|
+
const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
|
|
25
|
+
/**
|
|
26
|
+
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
27
|
+
*/
|
|
28
|
+
export function useFuzzySearch(options, flatMapOptions, minSearchInputLength) {
|
|
29
|
+
return useCallback((search) => {
|
|
30
|
+
const searcher = new FuzzySearch(flatMapOptions, ['label', 'contentRenderProps.description', 'contentRenderProps.caption'], {});
|
|
31
|
+
return search.length > (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)
|
|
32
|
+
? searcher.search(search)
|
|
33
|
+
: options;
|
|
34
|
+
}, [flatMapOptions, minSearchInputLength, options]);
|
|
35
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps,
|
|
2
|
-
export type { FilterOption } from './types';
|
|
3
|
-
export type { ChipChoiceCustomProps,
|
|
1
|
+
import { ChipChoiceCustom, ChipChoiceCustomProps, ChipChoiceDate, ChipChoiceDateProps, ChipChoiceDateRange, ChipChoiceDateRangeProps, ChipChoiceMultiple, ChipChoiceSingle, CustomContentRenderProps } from './components';
|
|
2
|
+
export type { FilterOption, ChipChoiceMultipleProps, ChipChoiceSingleProps } from './types';
|
|
3
|
+
export type { ChipChoiceCustomProps, ChipChoiceDateProps, ChipChoiceDateRangeProps, CustomContentRenderProps };
|
|
4
4
|
export declare namespace ChipChoice {
|
|
5
5
|
const Custom: typeof ChipChoiceCustom;
|
|
6
6
|
const Single: typeof ChipChoiceSingle;
|
|
7
|
-
const
|
|
7
|
+
const Multiple: typeof ChipChoiceMultiple;
|
|
8
8
|
const Date: typeof ChipChoiceDate;
|
|
9
9
|
const DateRange: typeof ChipChoiceDateRange;
|
|
10
10
|
}
|
|
11
|
+
export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ChipChoiceCustom, ChipChoiceDate, ChipChoiceDateRange,
|
|
1
|
+
import { ChipChoiceCustom, ChipChoiceDate, ChipChoiceDateRange, ChipChoiceMultiple, ChipChoiceSingle, } from './components';
|
|
2
2
|
export var ChipChoice;
|
|
3
3
|
(function (ChipChoice) {
|
|
4
4
|
ChipChoice.Custom = ChipChoiceCustom;
|
|
5
5
|
ChipChoice.Single = ChipChoiceSingle;
|
|
6
|
-
ChipChoice.
|
|
6
|
+
ChipChoice.Multiple = ChipChoiceMultiple;
|
|
7
7
|
ChipChoice.Date = ChipChoiceDate;
|
|
8
8
|
ChipChoice.DateRange = ChipChoiceDateRange;
|
|
9
9
|
})(ChipChoice || (ChipChoice = {}));
|
|
10
|
+
export { isAccordionOption, isBaseOption, isGroupOption, isGroupSelectOption, isNextListOption } from './utils';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
.label,
|
|
1
|
+
.label,
|
|
2
|
+
.value{
|
|
2
3
|
display:inline-flex;
|
|
3
4
|
align-items:center;
|
|
4
5
|
}
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
border-style:solid;
|
|
21
22
|
outline:0;
|
|
22
23
|
outline-offset:0;
|
|
23
|
-
background-color:var(--sys-neutral-background1-level, #
|
|
24
|
+
background-color:var(--sys-neutral-background1-level, #fdfdff);
|
|
24
25
|
border-color:var(--sys-neutral-decor-default, #dfe2ec);
|
|
25
26
|
}
|
|
26
27
|
.choiceChip .spinner{
|
|
@@ -117,7 +118,8 @@
|
|
|
117
118
|
padding-right:var(--space-chips-label-layout-padding-l, 12px);
|
|
118
119
|
gap:var(--space-chips-label-layout-gap, 2px);
|
|
119
120
|
}
|
|
120
|
-
.choiceChip .label,
|
|
121
|
+
.choiceChip .label,
|
|
122
|
+
.choiceChip .value{
|
|
121
123
|
color:var(--sys-neutral-text-support, #656771);
|
|
122
124
|
}
|
|
123
125
|
.choiceChip .icon{
|
|
@@ -177,7 +179,8 @@
|
|
|
177
179
|
background-color:var(--sys-neutral-background, #f1f2f6);
|
|
178
180
|
border-color:var(--sys-neutral-decor-disabled, #e8eaf1);
|
|
179
181
|
}
|
|
180
|
-
.choiceChip[data-disabled] .label,
|
|
182
|
+
.choiceChip[data-disabled] .label,
|
|
183
|
+
.choiceChip[data-disabled] .value{
|
|
181
184
|
color:var(--sys-neutral-text-light, #868892);
|
|
182
185
|
}
|
|
183
186
|
.choiceChip[data-loading]{
|
|
@@ -190,7 +193,8 @@
|
|
|
190
193
|
align-items:center;
|
|
191
194
|
justify-content:center;
|
|
192
195
|
}
|
|
193
|
-
.choiceChip[data-loading] .label,
|
|
196
|
+
.choiceChip[data-loading] .label,
|
|
197
|
+
.choiceChip[data-loading] .value{
|
|
194
198
|
color:var(--sys-neutral-text-support, #656771);
|
|
195
199
|
}
|
|
196
200
|
|
|
@@ -1,10 +1,31 @@
|
|
|
1
|
-
import { MouseEventHandler } from 'react';
|
|
2
|
-
import {
|
|
1
|
+
import { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
import { DropdownProps } from '@snack-uikit/dropdown';
|
|
3
|
+
import { BaseItemProps, DroplistProps, GroupItemProps, GroupSelectItemProps, ItemContentProps, ItemId, NextListItemProps, SelectionMultipleState, SelectionSingleState } from '@snack-uikit/list';
|
|
3
4
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
5
|
import { BaseChipProps, Size } from '../../types';
|
|
5
|
-
export type
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
export type AnyType = any;
|
|
7
|
+
export type ContentRenderProps = Omit<ItemContentProps, 'option' | 'disabled'>;
|
|
8
|
+
export type FilterOption<T extends ContentRenderProps = ContentRenderProps> = BaseOption<T> | AccordionOption<T> | GroupOption<T> | GroupSelectOption<T> | NestListOption<T>;
|
|
9
|
+
export type BaseOption<T extends ContentRenderProps = ContentRenderProps> = Omit<BaseItemProps, 'content' | 'id'> & {
|
|
10
|
+
value: ItemId;
|
|
11
|
+
label: ItemId;
|
|
12
|
+
contentRenderProps?: T;
|
|
13
|
+
};
|
|
14
|
+
export type AccordionOption<T extends ContentRenderProps = ContentRenderProps> = Omit<BaseOption<T>, 'switch' | 'inactive' | 'value'> & {
|
|
15
|
+
id?: ItemId;
|
|
16
|
+
type: 'collapse';
|
|
17
|
+
options: FilterOption<T>[];
|
|
18
|
+
};
|
|
19
|
+
export type GroupOption<T extends ContentRenderProps = ContentRenderProps> = Omit<GroupItemProps, 'items'> & {
|
|
20
|
+
options: FilterOption<T>[];
|
|
21
|
+
};
|
|
22
|
+
export type GroupSelectOption<T extends ContentRenderProps = ContentRenderProps> = Omit<GroupSelectItemProps, 'items'> & {
|
|
23
|
+
options: FilterOption<T>[];
|
|
24
|
+
};
|
|
25
|
+
export type NestListOption<T extends ContentRenderProps = ContentRenderProps> = Omit<NextListItemProps, 'items' | 'content'> & {
|
|
26
|
+
label: ItemId;
|
|
27
|
+
contentRenderProps?: T;
|
|
28
|
+
options: FilterOption<T>[];
|
|
8
29
|
};
|
|
9
30
|
export type ChipChoiceCommonProps = WithSupportProps<Partial<BaseChipProps> & {
|
|
10
31
|
/** Размер */
|
|
@@ -14,7 +35,7 @@ export type ChipChoiceCommonProps = WithSupportProps<Partial<BaseChipProps> & {
|
|
|
14
35
|
/** Отображение кнопки очистки значения @default true*/
|
|
15
36
|
showClearButton?: boolean;
|
|
16
37
|
/** Расположение выпадающего меню */
|
|
17
|
-
placement?:
|
|
38
|
+
placement?: DropdownProps['placement'];
|
|
18
39
|
/**
|
|
19
40
|
* Стратегия управления шириной контейнера поповера
|
|
20
41
|
* <br> - `auto` - соответствует ширине контента,
|
|
@@ -22,5 +43,32 @@ export type ChipChoiceCommonProps = WithSupportProps<Partial<BaseChipProps> & {
|
|
|
22
43
|
* <br> - `eq` - Equal, строго равен ширине таргета.
|
|
23
44
|
* @default gte
|
|
24
45
|
*/
|
|
25
|
-
widthStrategy?:
|
|
46
|
+
widthStrategy?: DropdownProps['widthStrategy'];
|
|
47
|
+
dropDownClassName?: string;
|
|
26
48
|
}>;
|
|
49
|
+
export type ChipChoiceSelectCommonProps<T extends ContentRenderProps = ContentRenderProps> = ChipChoiceCommonProps & {
|
|
50
|
+
options: FilterOption<T>[];
|
|
51
|
+
contentRender?(option: {
|
|
52
|
+
label: ItemId;
|
|
53
|
+
value?: ItemId;
|
|
54
|
+
contentRenderProps?: T;
|
|
55
|
+
}): ReactNode;
|
|
56
|
+
filterFn?(option: {
|
|
57
|
+
label: ItemId;
|
|
58
|
+
value?: ItemId;
|
|
59
|
+
contentRenderProps?: T;
|
|
60
|
+
}): boolean;
|
|
61
|
+
searchable?: boolean;
|
|
62
|
+
} & Pick<DroplistProps, 'selection' | 'scrollRef' | 'scrollContainerRef' | 'noDataState' | 'footer' | 'footerActiveElementsRefs' | 'dataError' | 'errorDataState' | 'dataFiltered' | 'noResultsState' | 'loading'>;
|
|
63
|
+
export type ChipChoiceSingleProps<T extends ContentRenderProps = ContentRenderProps> = ChipChoiceSelectCommonProps<T> & Omit<SelectionSingleState, 'mode'> & {
|
|
64
|
+
/** Массив опций */
|
|
65
|
+
options: FilterOption<T>[];
|
|
66
|
+
/** Колбек формирующий отображение выбранного значения. Принимает выбранное значение. По умолчанию для отображения используется FilterOption.label */
|
|
67
|
+
valueRender?(option?: BaseOption<T>): ReactNode;
|
|
68
|
+
};
|
|
69
|
+
export type ChipChoiceMultipleProps<T extends ContentRenderProps = ContentRenderProps> = ChipChoiceSelectCommonProps<T> & Omit<SelectionMultipleState, 'mode'> & {
|
|
70
|
+
/** Массив опций */
|
|
71
|
+
options: FilterOption<T>[];
|
|
72
|
+
/** Колбек формирующий отображение выбранного значения. Принимает выбранное значение. По умолчанию для отображения используется FilterOption.label */
|
|
73
|
+
valueRender?(option?: BaseOption<T>[]): ReactNode;
|
|
74
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ItemId, ItemProps } from '@snack-uikit/list';
|
|
3
|
+
import { ContentRenderProps, FilterOption } from '../types';
|
|
4
|
+
export declare function transformOptionsToItems<T extends ContentRenderProps = ContentRenderProps>(options: FilterOption<T>[], contentRender?: (option: {
|
|
5
|
+
label: ItemId;
|
|
6
|
+
value?: ItemId;
|
|
7
|
+
contentRenderProps?: T;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}) => ReactNode): ItemProps[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { ItemContent } from '@snack-uikit/list';
|
|
14
|
+
import { isAccordionOption, isGroupOption, isGroupSelectOption, isNextListOption } from './typeGuards';
|
|
15
|
+
export function transformOptionsToItems(options, contentRender) {
|
|
16
|
+
return options.map(option => {
|
|
17
|
+
if (isAccordionOption(option) || isNextListOption(option)) {
|
|
18
|
+
const { label, options, id, contentRenderProps, disabled } = option, rest = __rest(option, ["label", "options", "id", "contentRenderProps", "disabled"]);
|
|
19
|
+
return Object.assign(Object.assign({}, rest), { id, content: contentRender ? (contentRender({ label, contentRenderProps })) : (_jsx(ItemContent, Object.assign({ option: label }, contentRenderProps, { disabled: disabled }))), items: transformOptionsToItems(options) });
|
|
20
|
+
}
|
|
21
|
+
if (isGroupSelectOption(option)) {
|
|
22
|
+
const { options } = option, rest = __rest(option, ["options"]);
|
|
23
|
+
return Object.assign(Object.assign({}, rest), { items: transformOptionsToItems(options) });
|
|
24
|
+
}
|
|
25
|
+
if (isGroupOption(option)) {
|
|
26
|
+
const { options } = option, rest = __rest(option, ["options"]);
|
|
27
|
+
return Object.assign(Object.assign({}, rest), { items: transformOptionsToItems(options) });
|
|
28
|
+
}
|
|
29
|
+
const _a = option, { label, value, contentRenderProps, disabled } = _a, rest = __rest(_a, ["label", "value", "contentRenderProps", "disabled"]);
|
|
30
|
+
return Object.assign(Object.assign({}, rest), { id: value, content: contentRender ? (contentRender({ label, contentRenderProps })) : (_jsx(ItemContent, Object.assign({ option: label }, contentRenderProps, { disabled: disabled }))) });
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AccordionOption, AnyType, BaseOption, ContentRenderProps, GroupOption, GroupSelectOption, NestListOption } from '../types';
|
|
2
|
+
export declare function isBaseOption<T extends ContentRenderProps = ContentRenderProps>(option: AnyType): option is BaseOption<T>;
|
|
3
|
+
export declare function isAccordionOption<T extends ContentRenderProps = ContentRenderProps>(option: AnyType): option is AccordionOption<T>;
|
|
4
|
+
export declare function isNextListOption<T extends ContentRenderProps = ContentRenderProps>(option: AnyType): option is NestListOption<T>;
|
|
5
|
+
export declare function isGroupOption<T extends ContentRenderProps = ContentRenderProps>(option: AnyType): option is GroupOption<T>;
|
|
6
|
+
export declare function isGroupSelectOption<T extends ContentRenderProps = ContentRenderProps>(option: AnyType): option is GroupSelectOption<T>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function isBaseOption(option) {
|
|
2
|
+
return !('options' in option);
|
|
3
|
+
}
|
|
4
|
+
export function isAccordionOption(option) {
|
|
5
|
+
return option && 'options' in option && option['type'] === 'collapse';
|
|
6
|
+
}
|
|
7
|
+
export function isNextListOption(option) {
|
|
8
|
+
return option && 'options' in option && option['type'] === 'next-list';
|
|
9
|
+
}
|
|
10
|
+
export function isGroupOption(option) {
|
|
11
|
+
return option && 'options' in option && option['type'] === 'group';
|
|
12
|
+
}
|
|
13
|
+
export function isGroupSelectOption(option) {
|
|
14
|
+
return option && 'options' in option && option['type'] === 'group-select';
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ItemId } from '@snack-uikit/list';
|
|
3
|
+
import { ContentRenderProps, FilterOption } from '../types';
|
|
4
|
+
export type FlattenOption<T extends ContentRenderProps = ContentRenderProps> = {
|
|
5
|
+
value: ItemId;
|
|
6
|
+
label: ItemId;
|
|
7
|
+
contentRenderProps?: T;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
afterContent?: ReactNode;
|
|
10
|
+
beforeContent?: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
type KindFlattenOptionsProps<T extends ContentRenderProps = ContentRenderProps> = {
|
|
13
|
+
options: FilterOption<T>[];
|
|
14
|
+
};
|
|
15
|
+
export declare function kindFlattenOptions<T extends ContentRenderProps = ContentRenderProps>({ options, }: KindFlattenOptionsProps<T>): {
|
|
16
|
+
flattenOptions: Record<string, FlattenOption<T>>;
|
|
17
|
+
};
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isBaseOption } from './typeGuards';
|
|
2
|
+
export function kindFlattenOptions({ options, }) {
|
|
3
|
+
const flattenOptions = {};
|
|
4
|
+
function flatten(option) {
|
|
5
|
+
if (isBaseOption(option)) {
|
|
6
|
+
const { value, label, contentRenderProps, disabled, afterContent, beforeContent } = option;
|
|
7
|
+
flattenOptions[value] = {
|
|
8
|
+
value,
|
|
9
|
+
label,
|
|
10
|
+
contentRenderProps,
|
|
11
|
+
disabled,
|
|
12
|
+
afterContent,
|
|
13
|
+
beforeContent,
|
|
14
|
+
};
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const { options } = option;
|
|
18
|
+
for (let idx = 0; idx < options.length; idx++) {
|
|
19
|
+
flatten(options[idx]);
|
|
20
|
+
}
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
for (let idx = 0; idx < options.length; idx++) {
|
|
24
|
+
flatten(options[idx]);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
flattenOptions,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare const MAP_CHIP_TYPE_TO_COMPONENT: {
|
|
2
2
|
single: typeof import("../../ChipChoice/components").ChipChoiceSingle;
|
|
3
|
-
|
|
3
|
+
multiple: typeof import("../../ChipChoice/components").ChipChoiceMultiple;
|
|
4
4
|
date: typeof import("../../ChipChoice/components").ChipChoiceDate;
|
|
5
5
|
"date-range": typeof import("../../ChipChoice/components").ChipChoiceDateRange;
|
|
6
|
+
custom: typeof import("../../ChipChoice/components").ChipChoiceCustom;
|
|
6
7
|
};
|
|
@@ -2,7 +2,8 @@ import { ChipChoice } from '../../ChipChoice';
|
|
|
2
2
|
import { CHIP_CHOICE_TYPE } from '../../ChipChoice/constants';
|
|
3
3
|
export const MAP_CHIP_TYPE_TO_COMPONENT = {
|
|
4
4
|
[CHIP_CHOICE_TYPE.Single]: ChipChoice.Single,
|
|
5
|
-
[CHIP_CHOICE_TYPE.
|
|
5
|
+
[CHIP_CHOICE_TYPE.Multiple]: ChipChoice.Multiple,
|
|
6
6
|
[CHIP_CHOICE_TYPE.Date]: ChipChoice.Date,
|
|
7
7
|
[CHIP_CHOICE_TYPE.DateRange]: ChipChoice.DateRange,
|
|
8
|
+
[CHIP_CHOICE_TYPE.Custom]: ChipChoice.Custom,
|
|
8
9
|
};
|