@snack-uikit/chips 0.23.4 → 0.24.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 +12 -0
- package/README.md +6 -0
- package/dist/cjs/components/ChipChoice/components/ChipChoiceMultiple.d.ts +1 -1
- package/dist/cjs/components/ChipChoice/components/ChipChoiceMultiple.js +8 -3
- package/dist/cjs/components/ChipChoice/components/ChipChoiceSingle.d.ts +1 -1
- package/dist/cjs/components/ChipChoice/components/ChipChoiceSingle.js +8 -3
- package/dist/cjs/components/ChipChoice/hooks.d.ts +6 -1
- package/dist/cjs/components/ChipChoice/hooks.js +24 -7
- package/dist/cjs/components/ChipChoice/types.d.ts +5 -0
- package/dist/esm/components/ChipChoice/components/ChipChoiceMultiple.d.ts +1 -1
- package/dist/esm/components/ChipChoice/components/ChipChoiceMultiple.js +4 -4
- package/dist/esm/components/ChipChoice/components/ChipChoiceSingle.d.ts +1 -1
- package/dist/esm/components/ChipChoice/components/ChipChoiceSingle.js +4 -4
- package/dist/esm/components/ChipChoice/hooks.d.ts +6 -1
- package/dist/esm/components/ChipChoice/hooks.js +18 -6
- package/dist/esm/components/ChipChoice/types.d.ts +5 -0
- package/package.json +4 -4
- package/src/components/ChipChoice/components/ChipChoiceMultiple.tsx +5 -4
- package/src/components/ChipChoice/components/ChipChoiceSingle.tsx +5 -4
- package/src/components/ChipChoice/hooks.tsx +32 -13
- package/src/components/ChipChoice/types.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 0.24.0 (2025-01-22)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **CORESERV-5847:** add ability to disable fuzzy search on chips ([5016fe7](https://github.com/cloud-ru-tech/snack-uikit/commit/5016fe7989cd363e834dca181b60c870128da72f))
|
|
12
|
+
* **CORESERV-5847:** add optional virtualization to list ([6a05691](https://github.com/cloud-ru-tech/snack-uikit/commit/6a056917c7cd8b56fa432bf4edc804c13feb0a0a))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
6
18
|
## 0.23.4 (2025-01-20)
|
|
7
19
|
|
|
8
20
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -124,6 +124,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
124
124
|
| tabIndex | `number` | - | HTML tab index |
|
|
125
125
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
126
126
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
127
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
127
128
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
128
129
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
129
130
|
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
|
|
@@ -145,6 +146,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
145
146
|
| tabIndex | `number` | - | HTML tab index |
|
|
146
147
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
147
148
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
149
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
148
150
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
149
151
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
150
152
|
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
|
|
@@ -183,6 +185,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
183
185
|
| tabIndex | `number` | - | HTML tab index |
|
|
184
186
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
185
187
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
188
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
186
189
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
187
190
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
188
191
|
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
|
|
@@ -220,6 +223,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
220
223
|
| tabIndex | `number` | - | HTML tab index |
|
|
221
224
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
222
225
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
226
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
223
227
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
224
228
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
225
229
|
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
|
|
@@ -243,6 +247,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
243
247
|
| tabIndex | `number` | - | HTML tab index |
|
|
244
248
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
245
249
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
250
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
246
251
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
247
252
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
248
253
|
| widthStrategy | enum PopoverWidthStrategy: `"auto"`, `"gte"`, `"eq"` | gte | Стратегия управления шириной контейнера поповера <br> - `auto` - соответствует ширине контента, <br> - `gte` - Great Than or Equal, равен ширине таргета или больше ее, если контент в поповере шире, <br> - `eq` - Equal, строго равен ширине таргета. |
|
|
@@ -264,6 +269,7 @@ import { PlaceholderSVG } from '@snack-uikit/icons';
|
|
|
264
269
|
| tabIndex | `number` | - | HTML tab index |
|
|
265
270
|
| size | enum Size: `"xs"`, `"s"`, `"m"`, `"l"` | - | Размер |
|
|
266
271
|
| onClick | `MouseEventHandler<HTMLButtonElement \| HTMLDivElement>` | - | Колбек обработки клика |
|
|
272
|
+
| disableFuzzySearch | `boolean` | false | Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search |
|
|
267
273
|
| showClearButton | `boolean` | true | Отображение кнопки очистки значения |
|
|
268
274
|
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | - | Расположение выпадающего меню |
|
|
269
275
|
| dropDownClassName | `string` | - | |
|
|
@@ -5,4 +5,4 @@ export type ChipChoiceMultipleValueFormatterProps<T extends ContentRenderProps =
|
|
|
5
5
|
total: number;
|
|
6
6
|
allLabel: string;
|
|
7
7
|
};
|
|
8
|
-
export declare function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, showClearButton, autoApply, onApprove, onCancel, ...rest }: ChipChoiceMultipleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, showClearButton, autoApply, disableFuzzySearch, onApprove, onCancel, ...rest }: ChipChoiceMultipleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -52,10 +52,11 @@ function ChipChoiceMultiple(_a) {
|
|
|
52
52
|
dropDownClassName,
|
|
53
53
|
showClearButton = true,
|
|
54
54
|
autoApply = true,
|
|
55
|
+
disableFuzzySearch = false,
|
|
55
56
|
onApprove,
|
|
56
57
|
onCancel
|
|
57
58
|
} = _a,
|
|
58
|
-
rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "showClearButton", "autoApply", "onApprove", "onCancel"]);
|
|
59
|
+
rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "showClearButton", "autoApply", "disableFuzzySearch", "onApprove", "onCancel"]);
|
|
59
60
|
const [value, setValue] = (0, utils_1.useValueControl)({
|
|
60
61
|
value: valueProp,
|
|
61
62
|
defaultValue,
|
|
@@ -88,8 +89,12 @@ function ChipChoiceMultiple(_a) {
|
|
|
88
89
|
total: Object.keys(flattenOptions).length,
|
|
89
90
|
allLabel: t('allLabel')
|
|
90
91
|
});
|
|
91
|
-
const
|
|
92
|
-
|
|
92
|
+
const optionSearch = (0, hooks_1.useOptionSearch)({
|
|
93
|
+
options,
|
|
94
|
+
flatMapOptions,
|
|
95
|
+
disableFuzzySearch
|
|
96
|
+
});
|
|
97
|
+
const result = (0, react_1.useMemo)(() => !searchable || valueToRender === searchValue ? options : optionSearch(searchValue), [optionSearch, options, searchValue, searchable, valueToRender]);
|
|
93
98
|
const items = (0, react_1.useMemo)(() => (0, options_1.transformOptionsToItems)(result, contentRender), [contentRender, result]);
|
|
94
99
|
const clearValue = () => {
|
|
95
100
|
setValue([]);
|
|
@@ -5,4 +5,4 @@ export type ChipChoiceSingleValueFormatterProps = {
|
|
|
5
5
|
allLabel?: string;
|
|
6
6
|
};
|
|
7
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, autoApply, onApprove, onCancel, ...rest }: ChipChoiceSingleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function ChipChoiceSingle<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, disableFuzzySearch, autoApply, onApprove, onCancel, ...rest }: ChipChoiceSingleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -43,11 +43,12 @@ function ChipChoiceSingle(_a) {
|
|
|
43
43
|
searchable,
|
|
44
44
|
contentRender,
|
|
45
45
|
dropDownClassName,
|
|
46
|
+
disableFuzzySearch,
|
|
46
47
|
autoApply = true,
|
|
47
48
|
onApprove,
|
|
48
49
|
onCancel
|
|
49
50
|
} = _a,
|
|
50
|
-
rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "autoApply", "onApprove", "onCancel"]);
|
|
51
|
+
rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "disableFuzzySearch", "autoApply", "onApprove", "onCancel"]);
|
|
51
52
|
const [value, setValue] = (0, utils_1.useValueControl)({
|
|
52
53
|
value: valueProp,
|
|
53
54
|
defaultValue,
|
|
@@ -79,8 +80,12 @@ function ChipChoiceSingle(_a) {
|
|
|
79
80
|
label: selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label,
|
|
80
81
|
allLabel: t('allLabel')
|
|
81
82
|
});
|
|
82
|
-
const
|
|
83
|
-
|
|
83
|
+
const optionSearch = (0, hooks_1.useOptionSearch)({
|
|
84
|
+
options,
|
|
85
|
+
flatMapOptions,
|
|
86
|
+
disableFuzzySearch
|
|
87
|
+
});
|
|
88
|
+
const result = (0, react_1.useMemo)(() => !searchable || valueToRender === searchValue ? options : optionSearch(searchValue), [optionSearch, options, searchValue, searchable, valueToRender]);
|
|
84
89
|
const items = (0, react_1.useMemo)(() => (0, options_1.transformOptionsToItems)(result, contentRender), [contentRender, result]);
|
|
85
90
|
const clearValue = () => {
|
|
86
91
|
setValue(undefined);
|
|
@@ -9,7 +9,12 @@ export declare function useHandleOnKeyDown({ setOpen }: UseHandleOnKeyDownProps)
|
|
|
9
9
|
/**
|
|
10
10
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
11
11
|
*/
|
|
12
|
-
export declare function
|
|
12
|
+
export declare function useOptionSearch<T extends ContentRenderProps = ContentRenderProps>({ options, flatMapOptions, minSearchInputLength, disableFuzzySearch, }: {
|
|
13
|
+
options: FilterOption<T>[];
|
|
14
|
+
flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[];
|
|
15
|
+
minSearchInputLength?: number;
|
|
16
|
+
disableFuzzySearch?: boolean;
|
|
17
|
+
}): (search: string) => FilterOption<T>[];
|
|
13
18
|
type UseAutoApplyProps = {
|
|
14
19
|
autoApply: boolean;
|
|
15
20
|
size: Size;
|
|
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
9
9
|
value: true
|
|
10
10
|
});
|
|
11
11
|
exports.useHandleOnKeyDown = useHandleOnKeyDown;
|
|
12
|
-
exports.
|
|
12
|
+
exports.useOptionSearch = useOptionSearch;
|
|
13
13
|
exports.useAutoApply = useAutoApply;
|
|
14
14
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
15
15
|
const fuzzy_search_1 = __importDefault(require("fuzzy-search"));
|
|
@@ -46,19 +46,36 @@ const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
|
|
|
46
46
|
/**
|
|
47
47
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
48
48
|
*/
|
|
49
|
-
function
|
|
49
|
+
function useOptionSearch(_ref2) {
|
|
50
|
+
let {
|
|
51
|
+
options,
|
|
52
|
+
flatMapOptions,
|
|
53
|
+
minSearchInputLength,
|
|
54
|
+
disableFuzzySearch
|
|
55
|
+
} = _ref2;
|
|
50
56
|
return (0, react_1.useCallback)(search => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
if (search.length < (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)) return options;
|
|
58
|
+
if (disableFuzzySearch) {
|
|
59
|
+
return options.filter(option => {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
const fieldsForSearch = [option.label];
|
|
62
|
+
if ('contentRenderProps' in option) {
|
|
63
|
+
fieldsForSearch.push((_a = option === null || option === void 0 ? void 0 : option.contentRenderProps) === null || _a === void 0 ? void 0 : _a.description);
|
|
64
|
+
fieldsForSearch.push((_b = option === null || option === void 0 ? void 0 : option.contentRenderProps) === null || _b === void 0 ? void 0 : _b.caption);
|
|
65
|
+
}
|
|
66
|
+
return fieldsForSearch.filter(v => Boolean(v)).some(value => value.toString().includes(search));
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return new fuzzy_search_1.default(flatMapOptions, ['label', 'contentRenderProps.description', 'contentRenderProps.caption'], {}).search(search);
|
|
70
|
+
}, [disableFuzzySearch, flatMapOptions, minSearchInputLength, options]);
|
|
54
71
|
}
|
|
55
|
-
function useAutoApply(
|
|
72
|
+
function useAutoApply(_ref3) {
|
|
56
73
|
let {
|
|
57
74
|
autoApply,
|
|
58
75
|
size,
|
|
59
76
|
onApprove,
|
|
60
77
|
onCancel
|
|
61
|
-
} =
|
|
78
|
+
} = _ref3;
|
|
62
79
|
const {
|
|
63
80
|
t
|
|
64
81
|
} = (0, locale_1.useLocale)('Chips');
|
|
@@ -32,6 +32,11 @@ export type ChipChoiceCommonProps = WithSupportProps<Partial<BaseChipProps> & {
|
|
|
32
32
|
size?: Size;
|
|
33
33
|
/** Колбек обработки клика */
|
|
34
34
|
onClick?: MouseEventHandler<HTMLButtonElement | HTMLDivElement>;
|
|
35
|
+
/**
|
|
36
|
+
* Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
disableFuzzySearch?: boolean;
|
|
35
40
|
/** Отображение кнопки очистки значения @default true*/
|
|
36
41
|
showClearButton?: boolean;
|
|
37
42
|
/** Расположение выпадающего меню */
|
|
@@ -5,4 +5,4 @@ export type ChipChoiceMultipleValueFormatterProps<T extends ContentRenderProps =
|
|
|
5
5
|
total: number;
|
|
6
6
|
allLabel: string;
|
|
7
7
|
};
|
|
8
|
-
export declare function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, showClearButton, autoApply, onApprove, onCancel, ...rest }: ChipChoiceMultipleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, showClearButton, autoApply, disableFuzzySearch, onApprove, onCancel, ...rest }: ChipChoiceMultipleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,7 +16,7 @@ import { useLocale } from '@snack-uikit/locale';
|
|
|
16
16
|
import { useValueControl } from '@snack-uikit/utils';
|
|
17
17
|
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
18
18
|
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
19
|
-
import { useAutoApply,
|
|
19
|
+
import { useAutoApply, useHandleOnKeyDown, useOptionSearch } from '../hooks';
|
|
20
20
|
import { kindFlattenOptions } from '../utils';
|
|
21
21
|
import { transformOptionsToItems } from '../utils/options';
|
|
22
22
|
import { ChipChoiceBase } from './ChipChoiceBase';
|
|
@@ -31,7 +31,7 @@ const defaultMultiValueLabelFormatter = ({ value, total, allLabel }) => {
|
|
|
31
31
|
return `${len.toString()}/${total}`;
|
|
32
32
|
};
|
|
33
33
|
export function ChipChoiceMultiple(_a) {
|
|
34
|
-
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName, showClearButton = true, autoApply = true, onApprove, onCancel } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "showClearButton", "autoApply", "onApprove", "onCancel"]);
|
|
34
|
+
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName, showClearButton = true, autoApply = true, disableFuzzySearch = false, onApprove, onCancel } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "showClearButton", "autoApply", "disableFuzzySearch", "onApprove", "onCancel"]);
|
|
35
35
|
const [value, setValue] = useValueControl({
|
|
36
36
|
value: valueProp,
|
|
37
37
|
defaultValue,
|
|
@@ -58,8 +58,8 @@ export function ChipChoiceMultiple(_a) {
|
|
|
58
58
|
total: Object.keys(flattenOptions).length,
|
|
59
59
|
allLabel: t('allLabel'),
|
|
60
60
|
});
|
|
61
|
-
const
|
|
62
|
-
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options :
|
|
61
|
+
const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
|
|
62
|
+
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : optionSearch(searchValue)), [optionSearch, options, searchValue, searchable, valueToRender]);
|
|
63
63
|
const items = useMemo(() => transformOptionsToItems(result, contentRender), [contentRender, result]);
|
|
64
64
|
const clearValue = () => {
|
|
65
65
|
setValue([]);
|
|
@@ -5,4 +5,4 @@ export type ChipChoiceSingleValueFormatterProps = {
|
|
|
5
5
|
allLabel?: string;
|
|
6
6
|
};
|
|
7
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, autoApply, onApprove, onCancel, ...rest }: ChipChoiceSingleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function ChipChoiceSingle<T extends ContentRenderProps = ContentRenderProps>({ value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size, label, searchable, contentRender, dropDownClassName, disableFuzzySearch, autoApply, onApprove, onCancel, ...rest }: ChipChoiceSingleProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -16,7 +16,7 @@ import { useLocale } from '@snack-uikit/locale';
|
|
|
16
16
|
import { useValueControl } from '@snack-uikit/utils';
|
|
17
17
|
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
18
18
|
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
19
|
-
import { useAutoApply,
|
|
19
|
+
import { useAutoApply, useHandleOnKeyDown, useOptionSearch } from '../hooks';
|
|
20
20
|
import { kindFlattenOptions } from '../utils';
|
|
21
21
|
import { transformOptionsToItems } from '../utils/options';
|
|
22
22
|
import { ChipChoiceBase } from './ChipChoiceBase';
|
|
@@ -24,7 +24,7 @@ export function defaultSingleValueFormatter({ label, allLabel }) {
|
|
|
24
24
|
return label !== null && label !== void 0 ? label : allLabel;
|
|
25
25
|
}
|
|
26
26
|
export function ChipChoiceSingle(_a) {
|
|
27
|
-
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName, autoApply = true, onApprove, onCancel } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "autoApply", "onApprove", "onCancel"]);
|
|
27
|
+
var { value: valueProp, defaultValue, options, onChange: onChangeProp, valueRender, size = SIZE.S, label, searchable, contentRender, dropDownClassName, disableFuzzySearch, autoApply = true, onApprove, onCancel } = _a, rest = __rest(_a, ["value", "defaultValue", "options", "onChange", "valueRender", "size", "label", "searchable", "contentRender", "dropDownClassName", "disableFuzzySearch", "autoApply", "onApprove", "onCancel"]);
|
|
28
28
|
const [value, setValue] = useValueControl({
|
|
29
29
|
value: valueProp,
|
|
30
30
|
defaultValue,
|
|
@@ -47,8 +47,8 @@ export function ChipChoiceSingle(_a) {
|
|
|
47
47
|
const valueToRender = valueRender
|
|
48
48
|
? valueRender(selectedOption)
|
|
49
49
|
: defaultSingleValueFormatter({ label: selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label, allLabel: t('allLabel') });
|
|
50
|
-
const
|
|
51
|
-
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options :
|
|
50
|
+
const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
|
|
51
|
+
const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : optionSearch(searchValue)), [optionSearch, options, searchValue, searchable, valueToRender]);
|
|
52
52
|
const items = useMemo(() => transformOptionsToItems(result, contentRender), [contentRender, result]);
|
|
53
53
|
const clearValue = () => {
|
|
54
54
|
setValue(undefined);
|
|
@@ -9,7 +9,12 @@ export declare function useHandleOnKeyDown({ setOpen }: UseHandleOnKeyDownProps)
|
|
|
9
9
|
/**
|
|
10
10
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
11
11
|
*/
|
|
12
|
-
export declare function
|
|
12
|
+
export declare function useOptionSearch<T extends ContentRenderProps = ContentRenderProps>({ options, flatMapOptions, minSearchInputLength, disableFuzzySearch, }: {
|
|
13
|
+
options: FilterOption<T>[];
|
|
14
|
+
flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[];
|
|
15
|
+
minSearchInputLength?: number;
|
|
16
|
+
disableFuzzySearch?: boolean;
|
|
17
|
+
}): (search: string) => FilterOption<T>[];
|
|
13
18
|
type UseAutoApplyProps = {
|
|
14
19
|
autoApply: boolean;
|
|
15
20
|
size: Size;
|
|
@@ -31,13 +31,25 @@ const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
|
|
|
31
31
|
/**
|
|
32
32
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
33
33
|
*/
|
|
34
|
-
export function
|
|
34
|
+
export function useOptionSearch({ options, flatMapOptions, minSearchInputLength, disableFuzzySearch, }) {
|
|
35
35
|
return useCallback((search) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
if (search.length < (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH))
|
|
37
|
+
return options;
|
|
38
|
+
if (disableFuzzySearch) {
|
|
39
|
+
return options.filter(option => {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const fieldsForSearch = [option.label];
|
|
42
|
+
if ('contentRenderProps' in option) {
|
|
43
|
+
fieldsForSearch.push((_a = option === null || option === void 0 ? void 0 : option.contentRenderProps) === null || _a === void 0 ? void 0 : _a.description);
|
|
44
|
+
fieldsForSearch.push((_b = option === null || option === void 0 ? void 0 : option.contentRenderProps) === null || _b === void 0 ? void 0 : _b.caption);
|
|
45
|
+
}
|
|
46
|
+
return fieldsForSearch
|
|
47
|
+
.filter((v) => Boolean(v))
|
|
48
|
+
.some(value => value.toString().includes(search));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return new FuzzySearch(flatMapOptions, ['label', 'contentRenderProps.description', 'contentRenderProps.caption'], {}).search(search);
|
|
52
|
+
}, [disableFuzzySearch, flatMapOptions, minSearchInputLength, options]);
|
|
41
53
|
}
|
|
42
54
|
export function useAutoApply({ autoApply, size, onApprove, onCancel, }) {
|
|
43
55
|
const { t } = useLocale('Chips');
|
|
@@ -32,6 +32,11 @@ export type ChipChoiceCommonProps = WithSupportProps<Partial<BaseChipProps> & {
|
|
|
32
32
|
size?: Size;
|
|
33
33
|
/** Колбек обработки клика */
|
|
34
34
|
onClick?: MouseEventHandler<HTMLButtonElement | HTMLDivElement>;
|
|
35
|
+
/**
|
|
36
|
+
* Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
disableFuzzySearch?: boolean;
|
|
35
40
|
/** Отображение кнопки очистки значения @default true*/
|
|
36
41
|
showClearButton?: boolean;
|
|
37
42
|
/** Расположение выпадающего меню */
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Chips",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.24.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"scripts": {},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@snack-uikit/button": "0.19.5",
|
|
40
|
-
"@snack-uikit/calendar": "0.11.
|
|
40
|
+
"@snack-uikit/calendar": "0.11.16",
|
|
41
41
|
"@snack-uikit/dropdown": "0.4.2",
|
|
42
42
|
"@snack-uikit/icons": "0.24.1",
|
|
43
|
-
"@snack-uikit/list": "0.
|
|
43
|
+
"@snack-uikit/list": "0.23.0",
|
|
44
44
|
"@snack-uikit/loaders": "0.9.0",
|
|
45
45
|
"@snack-uikit/utils": "3.6.0",
|
|
46
46
|
"classnames": "2.5.1",
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@snack-uikit/locale": "*"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "546ae486452e74e78f65fd9ce0044c13b058872c"
|
|
58
58
|
}
|
|
@@ -6,7 +6,7 @@ import { useValueControl } from '@snack-uikit/utils';
|
|
|
6
6
|
|
|
7
7
|
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
8
8
|
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
9
|
-
import { useAutoApply,
|
|
9
|
+
import { useAutoApply, useHandleOnKeyDown, useOptionSearch } from '../hooks';
|
|
10
10
|
import { ChipChoiceMultipleProps, ContentRenderProps } from '../types';
|
|
11
11
|
import { FlattenOption, kindFlattenOptions } from '../utils';
|
|
12
12
|
import { transformOptionsToItems } from '../utils/options';
|
|
@@ -45,6 +45,7 @@ export function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderP
|
|
|
45
45
|
dropDownClassName,
|
|
46
46
|
showClearButton = true,
|
|
47
47
|
autoApply = true,
|
|
48
|
+
disableFuzzySearch = false,
|
|
48
49
|
onApprove,
|
|
49
50
|
onCancel,
|
|
50
51
|
...rest
|
|
@@ -89,11 +90,11 @@ export function ChipChoiceMultiple<T extends ContentRenderProps = ContentRenderP
|
|
|
89
90
|
allLabel: t('allLabel'),
|
|
90
91
|
});
|
|
91
92
|
|
|
92
|
-
const
|
|
93
|
+
const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
|
|
93
94
|
|
|
94
95
|
const result = useMemo(
|
|
95
|
-
() => (!searchable || valueToRender === searchValue ? options :
|
|
96
|
-
[
|
|
96
|
+
() => (!searchable || valueToRender === searchValue ? options : optionSearch(searchValue)),
|
|
97
|
+
[optionSearch, options, searchValue, searchable, valueToRender],
|
|
97
98
|
);
|
|
98
99
|
const items = useMemo(() => transformOptionsToItems<T>(result, contentRender), [contentRender, result]);
|
|
99
100
|
|
|
@@ -6,7 +6,7 @@ import { useValueControl } from '@snack-uikit/utils';
|
|
|
6
6
|
|
|
7
7
|
import { CHIP_CHOICE_TEST_IDS, SIZE } from '../../../constants';
|
|
8
8
|
import { DROPLIST_SIZE_MAP } from '../constants';
|
|
9
|
-
import { useAutoApply,
|
|
9
|
+
import { useAutoApply, useHandleOnKeyDown, useOptionSearch } from '../hooks';
|
|
10
10
|
import { ChipChoiceSingleProps, ContentRenderProps } from '../types';
|
|
11
11
|
import { FlattenOption, kindFlattenOptions } from '../utils';
|
|
12
12
|
import { transformOptionsToItems } from '../utils/options';
|
|
@@ -32,6 +32,7 @@ export function ChipChoiceSingle<T extends ContentRenderProps = ContentRenderPro
|
|
|
32
32
|
searchable,
|
|
33
33
|
contentRender,
|
|
34
34
|
dropDownClassName,
|
|
35
|
+
disableFuzzySearch,
|
|
35
36
|
autoApply = true,
|
|
36
37
|
onApprove,
|
|
37
38
|
onCancel,
|
|
@@ -73,11 +74,11 @@ export function ChipChoiceSingle<T extends ContentRenderProps = ContentRenderPro
|
|
|
73
74
|
? valueRender(selectedOption)
|
|
74
75
|
: defaultSingleValueFormatter({ label: selectedOption?.label, allLabel: t('allLabel') });
|
|
75
76
|
|
|
76
|
-
const
|
|
77
|
+
const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
|
|
77
78
|
|
|
78
79
|
const result = useMemo(
|
|
79
|
-
() => (!searchable || valueToRender === searchValue ? options :
|
|
80
|
-
[
|
|
80
|
+
() => (!searchable || valueToRender === searchValue ? options : optionSearch(searchValue)),
|
|
81
|
+
[optionSearch, options, searchValue, searchable, valueToRender],
|
|
81
82
|
);
|
|
82
83
|
const items = useMemo(() => transformOptionsToItems<T>(result, contentRender), [contentRender, result]);
|
|
83
84
|
|
|
@@ -2,7 +2,7 @@ import FuzzySearch from 'fuzzy-search';
|
|
|
2
2
|
import { KeyboardEvent, KeyboardEventHandler, useCallback } from 'react';
|
|
3
3
|
|
|
4
4
|
import { ButtonFilled, ButtonFunction } from '@snack-uikit/button';
|
|
5
|
-
import { DroplistProps } from '@snack-uikit/list';
|
|
5
|
+
import { DroplistProps, ItemId } from '@snack-uikit/list';
|
|
6
6
|
import { useLocale } from '@snack-uikit/locale';
|
|
7
7
|
|
|
8
8
|
import { CHIP_CHOICE_TEST_IDS } from '../../constants';
|
|
@@ -47,24 +47,43 @@ const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 2;
|
|
|
47
47
|
/**
|
|
48
48
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
49
49
|
*/
|
|
50
|
-
export function
|
|
51
|
-
options
|
|
52
|
-
flatMapOptions
|
|
53
|
-
minSearchInputLength
|
|
54
|
-
|
|
50
|
+
export function useOptionSearch<T extends ContentRenderProps = ContentRenderProps>({
|
|
51
|
+
options,
|
|
52
|
+
flatMapOptions,
|
|
53
|
+
minSearchInputLength,
|
|
54
|
+
disableFuzzySearch,
|
|
55
|
+
}: {
|
|
56
|
+
options: FilterOption<T>[];
|
|
57
|
+
flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[];
|
|
58
|
+
minSearchInputLength?: number;
|
|
59
|
+
disableFuzzySearch?: boolean;
|
|
60
|
+
}) {
|
|
55
61
|
return useCallback(
|
|
56
62
|
(search: string) => {
|
|
57
|
-
|
|
63
|
+
if (search.length < (minSearchInputLength ?? DEFAULT_MIN_SEARCH_INPUT_LENGTH)) return options;
|
|
64
|
+
|
|
65
|
+
if (disableFuzzySearch) {
|
|
66
|
+
return options.filter(option => {
|
|
67
|
+
const fieldsForSearch = [option.label];
|
|
68
|
+
|
|
69
|
+
if ('contentRenderProps' in option) {
|
|
70
|
+
fieldsForSearch.push(option?.contentRenderProps?.description);
|
|
71
|
+
fieldsForSearch.push(option?.contentRenderProps?.caption);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return fieldsForSearch
|
|
75
|
+
.filter((v): v is ItemId => Boolean(v))
|
|
76
|
+
.some(value => value.toString().includes(search));
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return new FuzzySearch(
|
|
58
81
|
flatMapOptions,
|
|
59
82
|
['label', 'contentRenderProps.description', 'contentRenderProps.caption'],
|
|
60
83
|
{},
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
return search.length > (minSearchInputLength ?? DEFAULT_MIN_SEARCH_INPUT_LENGTH)
|
|
64
|
-
? searcher.search(search)
|
|
65
|
-
: options;
|
|
84
|
+
).search(search);
|
|
66
85
|
},
|
|
67
|
-
[flatMapOptions, minSearchInputLength, options],
|
|
86
|
+
[disableFuzzySearch, flatMapOptions, minSearchInputLength, options],
|
|
68
87
|
);
|
|
69
88
|
}
|
|
70
89
|
|
|
@@ -74,6 +74,11 @@ export type ChipChoiceCommonProps = WithSupportProps<
|
|
|
74
74
|
size?: Size;
|
|
75
75
|
/** Колбек обработки клика */
|
|
76
76
|
onClick?: MouseEventHandler<HTMLButtonElement | HTMLDivElement>;
|
|
77
|
+
/**
|
|
78
|
+
* Отключает Fuzzy Search. Иногда в дроплисте могут быть различные айдишники - нам важно искать их без Fuzzy Search
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
disableFuzzySearch?: boolean;
|
|
77
82
|
/** Отображение кнопки очистки значения @default true*/
|
|
78
83
|
showClearButton?: boolean;
|
|
79
84
|
/** Расположение выпадающего меню */
|