@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 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 fuzzySearch = (0, hooks_1.useFuzzySearch)(options, flatMapOptions);
92
- const result = (0, react_1.useMemo)(() => !searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue), [fuzzySearch, options, searchValue, searchable, valueToRender]);
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 fuzzySearch = (0, hooks_1.useFuzzySearch)(options, flatMapOptions);
83
- const result = (0, react_1.useMemo)(() => !searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue), [fuzzySearch, options, searchValue, searchable, valueToRender]);
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 useFuzzySearch<T extends ContentRenderProps = ContentRenderProps>(options: FilterOption<T>[], flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[], minSearchInputLength?: number): (search: string) => FilterOption<T>[];
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.useFuzzySearch = useFuzzySearch;
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 useFuzzySearch(options, flatMapOptions, minSearchInputLength) {
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
- const searcher = new fuzzy_search_1.default(flatMapOptions, ['label', 'contentRenderProps.description', 'contentRenderProps.caption'], {});
52
- return search.length > (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH) ? searcher.search(search) : options;
53
- }, [flatMapOptions, minSearchInputLength, options]);
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(_ref2) {
72
+ function useAutoApply(_ref3) {
56
73
  let {
57
74
  autoApply,
58
75
  size,
59
76
  onApprove,
60
77
  onCancel
61
- } = _ref2;
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, useFuzzySearch, useHandleOnKeyDown } from '../hooks';
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 fuzzySearch = useFuzzySearch(options, flatMapOptions);
62
- const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)), [fuzzySearch, options, searchValue, searchable, valueToRender]);
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, useFuzzySearch, useHandleOnKeyDown } from '../hooks';
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 fuzzySearch = useFuzzySearch(options, flatMapOptions);
51
- const result = useMemo(() => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)), [fuzzySearch, options, searchValue, searchable, valueToRender]);
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 useFuzzySearch<T extends ContentRenderProps = ContentRenderProps>(options: FilterOption<T>[], flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[], minSearchInputLength?: number): (search: string) => FilterOption<T>[];
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 useFuzzySearch(options, flatMapOptions, minSearchInputLength) {
34
+ export function useOptionSearch({ options, flatMapOptions, minSearchInputLength, disableFuzzySearch, }) {
35
35
  return useCallback((search) => {
36
- const searcher = new FuzzySearch(flatMapOptions, ['label', 'contentRenderProps.description', 'contentRenderProps.caption'], {});
37
- return search.length > (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)
38
- ? searcher.search(search)
39
- : options;
40
- }, [flatMapOptions, minSearchInputLength, options]);
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.23.4",
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.15",
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.22.3",
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": "137a71cea0541ba2cbe468c3eb73df8bb8ea9ca0"
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, useFuzzySearch, useHandleOnKeyDown } from '../hooks';
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 fuzzySearch = useFuzzySearch(options, flatMapOptions);
93
+ const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
93
94
 
94
95
  const result = useMemo(
95
- () => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)),
96
- [fuzzySearch, options, searchValue, searchable, valueToRender],
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, useFuzzySearch, useHandleOnKeyDown } from '../hooks';
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 fuzzySearch = useFuzzySearch(options, flatMapOptions);
77
+ const optionSearch = useOptionSearch({ options, flatMapOptions, disableFuzzySearch });
77
78
 
78
79
  const result = useMemo(
79
- () => (!searchable || valueToRender === searchValue ? options : fuzzySearch(searchValue)),
80
- [fuzzySearch, options, searchValue, searchable, valueToRender],
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 useFuzzySearch<T extends ContentRenderProps = ContentRenderProps>(
51
- options: FilterOption<T>[],
52
- flatMapOptions: (BaseOption<T> | AccordionOption<T> | NestListOption<T>)[],
53
- minSearchInputLength?: number,
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
- const searcher = new FuzzySearch(
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
  /** Расположение выпадающего меню */