@snack-uikit/fields 0.53.2-preview-0a70077b.0 → 0.54.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +28 -130
  3. package/dist/cjs/components/FieldSecure/FieldSecure.d.ts +1 -1
  4. package/dist/cjs/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
  5. package/dist/cjs/components/FieldSelect/FieldSelectMultiple.js +28 -7
  6. package/dist/cjs/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
  7. package/dist/cjs/components/FieldSelect/FieldSelectSingle.js +25 -12
  8. package/dist/cjs/components/FieldSelect/{hooks.d.ts → hooks/common.d.ts} +1 -1
  9. package/dist/cjs/components/FieldSelect/{hooks.js → hooks/common.js} +4 -5
  10. package/dist/cjs/components/FieldSelect/hooks/customOption.d.ts +26 -0
  11. package/dist/cjs/components/FieldSelect/hooks/customOption.js +69 -0
  12. package/dist/cjs/components/FieldSelect/hooks/index.d.ts +2 -0
  13. package/dist/cjs/components/FieldSelect/hooks/index.js +26 -0
  14. package/dist/cjs/components/FieldSelect/index.d.ts +1 -1
  15. package/dist/cjs/components/FieldSelect/types.d.ts +20 -3
  16. package/dist/cjs/components/FieldSelect/utils/customOption.d.ts +4 -0
  17. package/dist/cjs/components/FieldSelect/utils/customOption.js +21 -0
  18. package/dist/cjs/components/FieldSelect/utils/index.d.ts +2 -0
  19. package/dist/cjs/components/FieldSelect/utils/index.js +3 -1
  20. package/dist/cjs/components/FieldText/FieldText.d.ts +1 -1
  21. package/dist/cjs/components/FieldTextArea/FieldTextArea.d.ts +1 -1
  22. package/dist/cjs/components/index.d.ts +0 -1
  23. package/dist/cjs/components/index.js +0 -1
  24. package/dist/cjs/helperComponents/ButtonFieldList/ButtonFieldList.d.ts +1 -1
  25. package/dist/esm/components/FieldSecure/FieldSecure.d.ts +1 -1
  26. package/dist/esm/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
  27. package/dist/esm/components/FieldSelect/FieldSelectMultiple.js +27 -9
  28. package/dist/esm/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
  29. package/dist/esm/components/FieldSelect/FieldSelectSingle.js +24 -14
  30. package/dist/esm/components/FieldSelect/{hooks.d.ts → hooks/common.d.ts} +1 -1
  31. package/dist/esm/components/FieldSelect/{hooks.js → hooks/common.js} +3 -4
  32. package/dist/esm/components/FieldSelect/hooks/customOption.d.ts +26 -0
  33. package/dist/esm/components/FieldSelect/hooks/customOption.js +38 -0
  34. package/dist/esm/components/FieldSelect/hooks/index.d.ts +2 -0
  35. package/dist/esm/components/FieldSelect/hooks/index.js +2 -0
  36. package/dist/esm/components/FieldSelect/index.d.ts +1 -1
  37. package/dist/esm/components/FieldSelect/types.d.ts +20 -3
  38. package/dist/esm/components/FieldSelect/utils/customOption.d.ts +4 -0
  39. package/dist/esm/components/FieldSelect/utils/customOption.js +13 -0
  40. package/dist/esm/components/FieldSelect/utils/index.d.ts +2 -0
  41. package/dist/esm/components/FieldSelect/utils/index.js +2 -0
  42. package/dist/esm/components/FieldText/FieldText.d.ts +1 -1
  43. package/dist/esm/components/FieldTextArea/FieldTextArea.d.ts +1 -1
  44. package/dist/esm/components/index.d.ts +0 -1
  45. package/dist/esm/components/index.js +0 -1
  46. package/dist/esm/helperComponents/ButtonFieldList/ButtonFieldList.d.ts +1 -1
  47. package/package.json +2 -2
  48. package/src/components/FieldSelect/FieldSelectMultiple.tsx +55 -10
  49. package/src/components/FieldSelect/FieldSelectSingle.tsx +33 -15
  50. package/src/components/FieldSelect/{hooks.ts → hooks/common.ts} +4 -5
  51. package/src/components/FieldSelect/hooks/customOption.ts +90 -0
  52. package/src/components/FieldSelect/hooks/index.ts +2 -0
  53. package/src/components/FieldSelect/index.ts +2 -0
  54. package/src/components/FieldSelect/types.ts +24 -3
  55. package/src/components/FieldSelect/utils/customOption.ts +23 -0
  56. package/src/components/FieldSelect/utils/index.ts +2 -0
  57. package/src/components/index.ts +0 -1
  58. package/dist/cjs/components/FieldAdd/FieldAdd.d.ts +0 -52
  59. package/dist/cjs/components/FieldAdd/FieldAdd.js +0 -216
  60. package/dist/cjs/components/FieldAdd/index.d.ts +0 -2
  61. package/dist/cjs/components/FieldAdd/index.js +0 -13
  62. package/dist/cjs/components/FieldAdd/styles.module.css +0 -51
  63. package/dist/esm/components/FieldAdd/FieldAdd.d.ts +0 -52
  64. package/dist/esm/components/FieldAdd/FieldAdd.js +0 -31
  65. package/dist/esm/components/FieldAdd/index.d.ts +0 -2
  66. package/dist/esm/components/FieldAdd/index.js +0 -1
  67. package/dist/esm/components/FieldAdd/styles.module.css +0 -51
  68. package/src/components/FieldAdd/FieldAdd.tsx +0 -215
  69. package/src/components/FieldAdd/index.ts +0 -3
  70. package/src/components/FieldAdd/styles.module.scss +0 -60
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useFieldSelectMultipleCustomOption = useFieldSelectMultipleCustomOption;
7
+ exports.useFieldSelectSingleCustomOption = useFieldSelectSingleCustomOption;
8
+ const react_1 = require("react");
9
+ function useResolvedAddCustomOptionTriggers(_ref) {
10
+ let {
11
+ addCustomOptionTriggers,
12
+ addOptionByEnter
13
+ } = _ref;
14
+ return (0, react_1.useMemo)(() => {
15
+ if (addCustomOptionTriggers !== undefined) {
16
+ return addCustomOptionTriggers;
17
+ }
18
+ return addOptionByEnter ? ['enter'] : [];
19
+ }, [addCustomOptionTriggers, addOptionByEnter]);
20
+ }
21
+ function useFieldSelectMultipleCustomOption(_ref2) {
22
+ let {
23
+ addCustomOptionTriggers,
24
+ addOptionByEnter,
25
+ inputValue,
26
+ value,
27
+ setValue,
28
+ updateInputValue
29
+ } = _ref2;
30
+ const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
31
+ addCustomOptionTriggers,
32
+ addOptionByEnter
33
+ });
34
+ const tryCommitCustomOptionFromInput = (0, react_1.useCallback)(trigger => {
35
+ if (!resolvedAddCustomOptionTriggers.includes(trigger) || inputValue === '') {
36
+ return;
37
+ }
38
+ if (!(value !== null && value !== void 0 ? value : []).includes(inputValue)) {
39
+ setValue(prev => (prev !== null && prev !== void 0 ? prev : []).concat(inputValue));
40
+ updateInputValue();
41
+ }
42
+ }, [resolvedAddCustomOptionTriggers, inputValue, value, setValue, updateInputValue]);
43
+ return {
44
+ resolvedAddCustomOptionTriggers,
45
+ tryCommitCustomOptionFromInput
46
+ };
47
+ }
48
+ function useFieldSelectSingleCustomOption(_ref3) {
49
+ let {
50
+ addCustomOptionTriggers,
51
+ addOptionByEnter,
52
+ inputValue,
53
+ handleSelectionChange
54
+ } = _ref3;
55
+ const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
56
+ addCustomOptionTriggers,
57
+ addOptionByEnter
58
+ });
59
+ const tryCommitCustomOptionFromInput = (0, react_1.useCallback)(trigger => {
60
+ if (!resolvedAddCustomOptionTriggers.includes(trigger) || inputValue === '') {
61
+ return;
62
+ }
63
+ handleSelectionChange(inputValue);
64
+ }, [resolvedAddCustomOptionTriggers, inputValue, handleSelectionChange]);
65
+ return {
66
+ resolvedAddCustomOptionTriggers,
67
+ tryCommitCustomOptionFromInput
68
+ };
69
+ }
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './customOption';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = {
8
+ enumerable: true,
9
+ get: function () {
10
+ return m[k];
11
+ }
12
+ };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ } : function (o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ });
19
+ var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", {
23
+ value: true
24
+ });
25
+ __exportStar(require("./common"), exports);
26
+ __exportStar(require("./customOption"), exports);
@@ -1,2 +1,2 @@
1
1
  export { FieldSelect } from './FieldSelect';
2
- export type { FieldSelectSingleProps, FieldSelectMultipleProps, FieldSelectProps, OptionProps, BaseOptionProps, AccordionOptionProps, NestListOptionProps, GroupOptionProps, SelectedOptionFormatter, } from './types';
2
+ export type { FieldSelectMultipleAddCustomOptionTrigger, FieldSelectSingleAddCustomOptionTrigger, FieldSelectSingleProps, FieldSelectMultipleProps, FieldSelectProps, OptionProps, BaseOptionProps, AccordionOptionProps, NestListOptionProps, GroupOptionProps, SelectedOptionFormatter, } from './types';
@@ -31,9 +31,11 @@ export type SearchState = {
31
31
  defaultValue?: string;
32
32
  onChange?(value: string): void;
33
33
  };
34
+ /** События, по которым произвольное значение из строки поиска фиксируется в значении поля */
35
+ export type FieldSelectMultipleAddCustomOptionTrigger = 'enter' | 'blur' | 'space' | 'comma';
36
+ export type FieldSelectSingleAddCustomOptionTrigger = Extract<FieldSelectMultipleAddCustomOptionTrigger, 'enter' | 'blur'>;
34
37
  export type FieldSelectPrivateProps = InputProps & WrapperProps & {
35
38
  options: OptionProps[];
36
- /** Отображать ли состояние загрузки данных в поле и списке */
37
39
  loading?: boolean;
38
40
  /** Произвольный префикс для поля */
39
41
  prefix?: ReactNode;
@@ -65,6 +67,9 @@ type FiledSelectCommonProps = WithSupportProps<{
65
67
  widthStrategy?: DroplistProps['widthStrategy'];
66
68
  search?: SearchState;
67
69
  autocomplete?: boolean;
70
+ /**
71
+ * @deprecated Используйте `addCustomOptionTriggers`
72
+ */
68
73
  addOptionByEnter?: boolean;
69
74
  open?: boolean;
70
75
  /** Включить нечеткий поиск */
@@ -76,10 +81,22 @@ type FiledSelectCommonProps = WithSupportProps<{
76
81
  onOpenChange?(open: boolean): void;
77
82
  selectedOptionFormatter?: SelectedOptionFormatter;
78
83
  }> & Pick<DroplistProps, 'dataError' | 'noDataState' | 'noResultsState' | 'errorDataState' | 'dataFiltered' | 'untouchableScrollbars' | 'scrollToSelectedItem' | 'virtualized' | 'scrollRef' | 'scrollContainerRef' | 'onScroll'>;
79
- export type FieldSelectSingleProps = FieldSelectPrivateProps & Omit<SelectionSingleState, 'mode'> & WrapperProps & FiledSelectCommonProps;
84
+ export type FieldSelectSingleProps = FieldSelectPrivateProps & Omit<SelectionSingleState, 'mode'> & WrapperProps & FiledSelectCommonProps & {
85
+ /**
86
+ * Триггеры фиксации произвольного значения из строки поиска в режиме `single`.
87
+ * Если передан, имеет приоритет над устаревшим `addOptionByEnter`.
88
+ */
89
+ addCustomOptionTriggers?: FieldSelectSingleAddCustomOptionTrigger[];
90
+ };
80
91
  export type FieldSelectMultipleProps = FieldSelectPrivateProps & {
81
92
  removeByBackspace?: boolean;
82
- } & Omit<SelectionMultipleState, 'mode'> & Omit<FiledSelectCommonProps, 'showCopyButton' | 'onCopyButtonClick'>;
93
+ } & Omit<SelectionMultipleState, 'mode'> & Omit<FiledSelectCommonProps, 'showCopyButton' | 'onCopyButtonClick'> & {
94
+ /**
95
+ * Триггеры фиксации произвольного значения из строки поиска в режиме `multiple`.
96
+ * Если передан, имеет приоритет над устаревшим `addOptionByEnter`.
97
+ */
98
+ addCustomOptionTriggers?: FieldSelectMultipleAddCustomOptionTrigger[];
99
+ };
83
100
  export type FieldSelectProps = (FieldSelectSingleProps & {
84
101
  selection?: 'single';
85
102
  }) | (FieldSelectMultipleProps & {
@@ -0,0 +1,4 @@
1
+ import { KeyboardEvent } from 'react';
2
+ import { FieldSelectMultipleAddCustomOptionTrigger } from '../types';
3
+ export declare const getCustomOptionTriggerByCode: (code: KeyboardEvent<HTMLInputElement>["code"]) => FieldSelectMultipleAddCustomOptionTrigger | undefined;
4
+ export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectMultipleAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectMultipleAddCustomOptionTrigger[]) => trigger is FieldSelectMultipleAddCustomOptionTrigger;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldHandleCustomOptionTrigger = exports.getCustomOptionTriggerByCode = void 0;
7
+ const getCustomOptionTriggerByCode = code => {
8
+ switch (code) {
9
+ case 'Enter':
10
+ return 'enter';
11
+ case 'Space':
12
+ return 'space';
13
+ case 'Comma':
14
+ return 'comma';
15
+ default:
16
+ return undefined;
17
+ }
18
+ };
19
+ exports.getCustomOptionTriggerByCode = getCustomOptionTriggerByCode;
20
+ const shouldHandleCustomOptionTrigger = (trigger, availableTriggers) => trigger ? availableTriggers.includes(trigger) : false;
21
+ exports.shouldHandleCustomOptionTrigger = shouldHandleCustomOptionTrigger;
@@ -5,3 +5,5 @@ export * from './updateItems';
5
5
  export * from './getArrowIcon';
6
6
  export * from './getValueByPath';
7
7
  export * from './checkisSearchUnavailable';
8
+ export * from './customOption';
9
+ export * from './filterItemsByFlattenIds';
@@ -28,4 +28,6 @@ __exportStar(require("./options"), exports);
28
28
  __exportStar(require("./updateItems"), exports);
29
29
  __exportStar(require("./getArrowIcon"), exports);
30
30
  __exportStar(require("./getValueByPath"), exports);
31
- __exportStar(require("./checkisSearchUnavailable"), exports);
31
+ __exportStar(require("./checkisSearchUnavailable"), exports);
32
+ __exportStar(require("./customOption"), exports);
33
+ __exportStar(require("./filterItemsByFlattenIds"), exports);
@@ -32,5 +32,5 @@ type FieldTextOwnProps = {
32
32
  export type FieldTextProps = WithSupportProps<FieldTextOwnProps & InputProps & WrapperProps>;
33
33
  export declare const FieldText: import("react").ForwardRefExoticComponent<{
34
34
  'data-test-id'?: string;
35
- } & import("react").AriaAttributes & FieldTextOwnProps & Pick<Partial<InputPrivateProps>, "onChange" | "value"> & Pick<Required<InputPrivateProps>, "inputMode"> & Pick<InputPrivateProps, "id" | "name" | "onPaste" | "onFocus" | "onBlur" | "onKeyDown" | "disabled" | "placeholder" | "readonly" | "autoFocus" | "autoComplete" | "maxLength" | "spellCheck" | "pattern"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
35
+ } & import("react").AriaAttributes & FieldTextOwnProps & Pick<Partial<InputPrivateProps>, "onChange" | "value"> & Pick<Required<InputPrivateProps>, "inputMode"> & Pick<InputPrivateProps, "id" | "name" | "onPaste" | "onFocus" | "onBlur" | "onKeyDown" | "disabled" | "readonly" | "placeholder" | "autoFocus" | "autoComplete" | "maxLength" | "spellCheck" | "pattern"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
36
36
  export {};
@@ -30,5 +30,5 @@ type FieldTextAreaOwnProps = {
30
30
  export type FieldTextAreaProps = WithSupportProps<FieldTextAreaOwnProps & InputProps & WrapperProps>;
31
31
  export declare const FieldTextArea: import("react").ForwardRefExoticComponent<{
32
32
  'data-test-id'?: string;
33
- } & import("react").AriaAttributes & FieldTextAreaOwnProps & Pick<Partial<TextAreaProps>, "value"> & Pick<TextAreaProps, "id" | "name" | "onFocus" | "onBlur" | "onKeyDown" | "disabled" | "placeholder" | "readonly" | "autoFocus" | "inputMode" | "maxLength" | "spellCheck"> & WrapperProps & import("react").RefAttributes<HTMLTextAreaElement>>;
33
+ } & import("react").AriaAttributes & FieldTextAreaOwnProps & Pick<Partial<TextAreaProps>, "value"> & Pick<TextAreaProps, "id" | "name" | "onFocus" | "onBlur" | "onKeyDown" | "disabled" | "readonly" | "placeholder" | "autoFocus" | "inputMode" | "maxLength" | "spellCheck"> & WrapperProps & import("react").RefAttributes<HTMLTextAreaElement>>;
34
34
  export {};
@@ -1,4 +1,3 @@
1
- export * from './FieldAdd';
2
1
  export * from './FieldColor';
3
2
  export * from './FieldDate';
4
3
  export * from './FieldDecorator';
@@ -22,7 +22,6 @@ var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
22
22
  Object.defineProperty(exports, "__esModule", {
23
23
  value: true
24
24
  });
25
- __exportStar(require("./FieldAdd"), exports);
26
25
  __exportStar(require("./FieldColor"), exports);
27
26
  __exportStar(require("./FieldDate"), exports);
28
27
  __exportStar(require("./FieldDecorator"), exports);
@@ -1,4 +1,4 @@
1
1
  import { ButtonFieldProps } from '../ButtonField';
2
- export declare const ButtonFieldList: import("react").ForwardRefExoticComponent<Omit<ButtonFieldProps, "hasArrow" | "arrowOpen"> & Pick<import("@snack-uikit/list").DroplistProps, "search" | "items" | "scroll" | "open" | "onOpenChange"> & {
2
+ export declare const ButtonFieldList: import("react").ForwardRefExoticComponent<Omit<ButtonFieldProps, "hasArrow" | "arrowOpen"> & Pick<import("@snack-uikit/list").DroplistProps, "search" | "open" | "onOpenChange" | "items" | "scroll"> & {
3
3
  selection?: Omit<import("@snack-uikit/list").SelectionSingleState, "mode">;
4
4
  } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -23,5 +23,5 @@ type FieldSecureOwnProps = {
23
23
  export type FieldSecureProps = WithSupportProps<FieldSecureOwnProps & InputProps & WrapperProps>;
24
24
  export declare const FieldSecure: import("react").ForwardRefExoticComponent<{
25
25
  'data-test-id'?: string;
26
- } & import("react").AriaAttributes & FieldSecureOwnProps & Pick<Partial<InputPrivateProps>, "onChange" | "value"> & Pick<InputPrivateProps, "id" | "name" | "onFocus" | "onBlur" | "disabled" | "placeholder" | "readonly" | "autoFocus" | "autoComplete" | "maxLength"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
26
+ } & import("react").AriaAttributes & FieldSecureOwnProps & Pick<Partial<InputPrivateProps>, "onChange" | "value"> & Pick<InputPrivateProps, "id" | "name" | "onFocus" | "onBlur" | "disabled" | "readonly" | "placeholder" | "autoFocus" | "autoComplete" | "maxLength"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
27
27
  export {};
@@ -28,4 +28,6 @@ export declare const FieldSelectMultiple: import("react").ForwardRefExoticCompon
28
28
  resetSearchOnOptionSelection?: boolean;
29
29
  onOpenChange?(open: boolean): void;
30
30
  selectedOptionFormatter?: SelectedOptionFormatter;
31
- } & Pick<import("@snack-uikit/list").DroplistProps, "onScroll" | "scrollRef" | "scrollContainerRef" | "untouchableScrollbars" | "dataError" | "dataFiltered" | "scrollToSelectedItem" | "virtualized" | "noDataState" | "noResultsState" | "errorDataState">, "showCopyButton" | "onCopyButtonClick"> & import("react").RefAttributes<HTMLInputElement>>;
31
+ } & Pick<import("@snack-uikit/list").DroplistProps, "onScroll" | "scrollRef" | "scrollContainerRef" | "untouchableScrollbars" | "dataError" | "dataFiltered" | "scrollToSelectedItem" | "virtualized" | "noDataState" | "noResultsState" | "errorDataState">, "showCopyButton" | "onCopyButtonClick"> & {
32
+ addCustomOptionTriggers?: import("./types").FieldSelectMultipleAddCustomOptionTrigger[];
33
+ } & import("react").RefAttributes<HTMLInputElement>>;
@@ -12,7 +12,7 @@ var __rest = (this && this.__rest) || function (s, e) {
12
12
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
13
  import cn from 'classnames';
14
14
  import mergeRefs from 'merge-refs';
15
- import { forwardRef, useEffect, useRef, useState } from 'react';
15
+ import { forwardRef, useCallback, useEffect, useRef, useState, } from 'react';
16
16
  import { InputPrivate } from '@snack-uikit/input-private';
17
17
  import { Droplist } from '@snack-uikit/list';
18
18
  import { Tag } from '@snack-uikit/tag';
@@ -22,9 +22,9 @@ import { usePostfix, usePrefix, useValueControl } from '../../hooks';
22
22
  import { getValidationState } from '../../utils/getValidationState';
23
23
  import { FieldDecorator } from '../FieldDecorator';
24
24
  import { extractFieldDecoratorProps } from '../FieldDecorator/utils';
25
- import { useButtons, useHandleDeleteItem, useHandleOnKeyDown, useSearch, useSearchInput } from './hooks';
25
+ import { useButtons, useFieldSelectMultipleCustomOption, useHandleDeleteItem, useHandleOnKeyDown, useSearch, useSearchInput, } from './hooks';
26
26
  import styles from './styles.module.css';
27
- import { checkisSearchUnavailable, extractListProps, getArrowIcon, updateMultipleItems } from './utils';
27
+ import { checkisSearchUnavailable, extractListProps, getArrowIcon, getCustomOptionTriggerByCode, shouldHandleCustomOptionTrigger, updateMultipleItems, } from './utils';
28
28
  const BASE_MIN_WIDTH = 4;
29
29
  const defaultSelectedOptionFormatter = item =>
30
30
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -32,7 +32,7 @@ const defaultSelectedOptionFormatter = item =>
32
32
  (item === null || item === void 0 ? void 0 : item.content.option) || '';
33
33
  export const FieldSelectMultiple = forwardRef((props, ref) => {
34
34
  var _a;
35
- const { id, name, placeholder, size = 's', options, value: valueProp, defaultValue, onChange: onChangeProp, disabled = false, readonly = false, searchable = true, showClearButton = true, onKeyDown: onInputKeyDownProp, validationState = 'default', search, autocomplete = false, prefixIcon, prefix, postfix, removeByBackspace = false, addOptionByEnter = false, untouchableScrollbars = false, open: openProp, enableFuzzySearch = true, resetSearchOnOptionSelection = true, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter, autoFocus } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showClearButton", "onKeyDown", "validationState", "search", "autocomplete", "prefixIcon", "prefix", "postfix", "removeByBackspace", "addOptionByEnter", "untouchableScrollbars", "open", "enableFuzzySearch", "resetSearchOnOptionSelection", "onOpenChange", "selectedOptionFormatter", "autoFocus"]);
35
+ const { id, name, placeholder, size = 's', options, value: valueProp, defaultValue, onChange: onChangeProp, disabled = false, readonly = false, searchable = true, showClearButton = true, onKeyDown: onInputKeyDownProp, validationState = 'default', search, autocomplete = false, prefixIcon, prefix, postfix, removeByBackspace = false, addOptionByEnter = false, addCustomOptionTriggers, untouchableScrollbars = false, open: openProp, enableFuzzySearch = true, resetSearchOnOptionSelection = true, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter, autoFocus } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showClearButton", "onKeyDown", "validationState", "search", "autocomplete", "prefixIcon", "prefix", "postfix", "removeByBackspace", "addOptionByEnter", "addCustomOptionTriggers", "untouchableScrollbars", "open", "enableFuzzySearch", "resetSearchOnOptionSelection", "onOpenChange", "selectedOptionFormatter", "autoFocus"]);
36
36
  const localRef = useRef(null);
37
37
  const inputPlugRef = useRef(null);
38
38
  const contentRef = useRef(null);
@@ -45,6 +45,14 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
45
45
  const [{ selectedItems, items = [] }, setItems] = useState(() => updateMultipleItems({ options, value, currentItems: [], selectedItems: undefined }));
46
46
  const { inputValue, setInputValue, prevInputValue, updateInputValue } = useSearchInput(Object.assign(Object.assign({}, search), { defaultValue: '', selectedOptionFormatter,
47
47
  resetSearchOnOptionSelection }));
48
+ const { resolvedAddCustomOptionTriggers, tryCommitCustomOptionFromInput } = useFieldSelectMultipleCustomOption({
49
+ addCustomOptionTriggers,
50
+ addOptionByEnter,
51
+ inputValue,
52
+ value,
53
+ setValue,
54
+ updateInputValue,
55
+ });
48
56
  const prefixSettings = usePrefix({ prefix, disabled });
49
57
  const postfixSettings = usePostfix({ postfix, disabled });
50
58
  useLayoutEffect(() => {
@@ -73,6 +81,12 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
73
81
  setOpen,
74
82
  });
75
83
  const handleItemDelete = useHandleDeleteItem(setValue);
84
+ const handleTagDelete = useCallback((option) => () => {
85
+ var _a;
86
+ const deleteItemHandler = handleItemDelete(option);
87
+ deleteItemHandler();
88
+ (_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
89
+ }, [handleItemDelete]);
76
90
  const handleOnKeyDown = (onKeyDown) => (e) => {
77
91
  if (removeByBackspace && e.code === 'Backspace' && inputValue === '') {
78
92
  if ((selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) && !selectedItems.slice(-1)[0].disabled) {
@@ -82,11 +96,14 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
82
96
  if (e.code === 'Enter') {
83
97
  e.stopPropagation();
84
98
  e.preventDefault();
99
+ tryCommitCustomOptionFromInput('enter');
85
100
  }
86
- if (addOptionByEnter && e.code === 'Enter' && inputValue !== '') {
87
- if (!(value !== null && value !== void 0 ? value : []).includes(inputValue)) {
88
- setValue((value) => (value !== null && value !== void 0 ? value : []).concat(inputValue));
89
- updateInputValue();
101
+ else {
102
+ const customOptionTrigger = getCustomOptionTriggerByCode(e.code);
103
+ if (shouldHandleCustomOptionTrigger(customOptionTrigger, resolvedAddCustomOptionTriggers)) {
104
+ e.stopPropagation();
105
+ e.preventDefault();
106
+ tryCommitCustomOptionFromInput(customOptionTrigger);
90
107
  }
91
108
  }
92
109
  if (!open && prevInputValue.current !== inputValue) {
@@ -112,6 +129,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
112
129
  const handleBlur = (e) => {
113
130
  var _a;
114
131
  if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
132
+ tryCommitCustomOptionFromInput('blur');
115
133
  updateInputValue();
116
134
  (_a = rest === null || rest === void 0 ? void 0 : rest.onBlur) === null || _a === void 0 ? void 0 : _a.call(rest, e);
117
135
  }
@@ -154,7 +172,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
154
172
  return (_jsx(FieldContainerPrivate, { className: cn(styles.container, styles.tagContainer), validationState: fieldValidationState, disabled: disabled, readonly: readonly, focused: open, variant: 'single-line-container', inputRef: localRef, size: size, prefix: (prefixIcon || prefixSettings.show) && (_jsxs(_Fragment, { children: [prefixIcon, prefixSettings.show && prefixSettings.render({ key: prefixSettings.id })] })), children: _jsxs(_Fragment, { children: [_jsxs("div", { className: styles.contentWrapper, ref: contentRef, children: [selectedItems &&
155
173
  selectedItems.map(option => {
156
174
  var _a;
157
- return (_jsx(Tag, { size: size === 'l' ? 's' : 'xs', tabIndex: -1, label: selectedOptionFormatter(option), appearance: (_a = option.appearance) !== null && _a !== void 0 ? _a : 'neutral', onDelete: !option.disabled && !disabled && !readonly ? handleItemDelete(option) : undefined, className: styles.tag, "data-disabled": disabled || undefined }, option.id));
175
+ return (_jsx(Tag, { size: size === 'l' ? 's' : 'xs', tabIndex: -1, label: selectedOptionFormatter(option), appearance: (_a = option.appearance) !== null && _a !== void 0 ? _a : 'neutral', onDelete: !option.disabled && !disabled && !readonly ? handleTagDelete(option) : undefined, className: styles.tag, "data-disabled": disabled || undefined }, option.id));
158
176
  }), _jsx("div", { className: styles.inputWrapper, style: {
159
177
  minWidth: value
160
178
  ? Math.min((_b = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth) !== null && _b !== void 0 ? _b : BASE_MIN_WIDTH, (_d = (_c = inputPlugRef.current) === null || _c === void 0 ? void 0 : _c.clientWidth) !== null && _d !== void 0 ? _d : BASE_MIN_WIDTH)
@@ -26,4 +26,6 @@ export declare const FieldSelectSingle: import("react").ForwardRefExoticComponen
26
26
  resetSearchOnOptionSelection?: boolean;
27
27
  onOpenChange?(open: boolean): void;
28
28
  selectedOptionFormatter?: SelectedOptionFormatter;
29
- } & Pick<import("@snack-uikit/list").DroplistProps, "onScroll" | "scrollRef" | "scrollContainerRef" | "untouchableScrollbars" | "dataError" | "dataFiltered" | "scrollToSelectedItem" | "virtualized" | "noDataState" | "noResultsState" | "errorDataState"> & import("react").RefAttributes<HTMLInputElement>>;
29
+ } & Pick<import("@snack-uikit/list").DroplistProps, "onScroll" | "scrollRef" | "scrollContainerRef" | "untouchableScrollbars" | "dataError" | "dataFiltered" | "scrollToSelectedItem" | "virtualized" | "noDataState" | "noResultsState" | "errorDataState"> & {
30
+ addCustomOptionTriggers?: import("./types").FieldSelectSingleAddCustomOptionTrigger[];
31
+ } & import("react").RefAttributes<HTMLInputElement>>;
@@ -21,15 +21,15 @@ import { usePostfix, usePrefix, useValueControl } from '../../hooks';
21
21
  import { getValidationState } from '../../utils/getValidationState';
22
22
  import { FieldDecorator } from '../FieldDecorator';
23
23
  import { extractFieldDecoratorProps } from '../FieldDecorator/utils';
24
- import { useButtons, useHandleOnKeyDown, useSearch, useSearchInput } from './hooks';
24
+ import { useButtons, useFieldSelectSingleCustomOption, useHandleOnKeyDown, useSearch, useSearchInput } from './hooks';
25
25
  import styles from './styles.module.css';
26
- import { checkisSearchUnavailable, extractListProps, getArrowIcon, updateItems } from './utils';
26
+ import { checkisSearchUnavailable, extractListProps, getArrowIcon, shouldHandleCustomOptionTrigger, updateItems, } from './utils';
27
27
  const defaultSelectedOptionFormatter = item =>
28
28
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
29
29
  // @ts-expect-error
30
30
  (item === null || item === void 0 ? void 0 : item.content.option) || '';
31
31
  export const FieldSelectSingle = forwardRef((props, ref) => {
32
- const { id, name, placeholder, size = 's', options, value: valueProp, defaultValue, onChange: onChangeProp, disabled = false, readonly = false, searchable = true, showCopyButton = true, showClearButton = true, onKeyDown: onInputKeyDownProp, required = false, validationState = 'default', search, autocomplete = false, prefixIcon, prefix, postfix, addOptionByEnter = false, untouchableScrollbars = false, open: openProp, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter, enableFuzzySearch = true, resetSearchOnOptionSelection = true, onCopyButtonClick, autoFocus } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showCopyButton", "showClearButton", "onKeyDown", "required", "validationState", "search", "autocomplete", "prefixIcon", "prefix", "postfix", "addOptionByEnter", "untouchableScrollbars", "open", "onOpenChange", "selectedOptionFormatter", "enableFuzzySearch", "resetSearchOnOptionSelection", "onCopyButtonClick", "autoFocus"]);
32
+ const { id, name, placeholder, size = 's', options, value: valueProp, defaultValue, onChange: onChangeProp, disabled = false, readonly = false, searchable = true, showCopyButton = true, showClearButton = true, onKeyDown: onInputKeyDownProp, required = false, validationState = 'default', search, autocomplete = false, prefixIcon, prefix, postfix, addOptionByEnter = false, addCustomOptionTriggers: addCustomOptionTriggersProp, untouchableScrollbars = false, open: openProp, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter, enableFuzzySearch = true, resetSearchOnOptionSelection = true, onCopyButtonClick, autoFocus } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showCopyButton", "showClearButton", "onKeyDown", "required", "validationState", "search", "autocomplete", "prefixIcon", "prefix", "postfix", "addOptionByEnter", "addCustomOptionTriggers", "untouchableScrollbars", "open", "onOpenChange", "selectedOptionFormatter", "enableFuzzySearch", "resetSearchOnOptionSelection", "onCopyButtonClick", "autoFocus"]);
33
33
  const localRef = useRef(null);
34
34
  const [open = false, setOpen] = useValueControl({ value: openProp, onChange: onOpenChange });
35
35
  const [value, setValue] = useValueControl({
@@ -77,13 +77,6 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
77
77
  onCopyButtonClick,
78
78
  valueToCopy: selectedOptionFormatter(selectedItem),
79
79
  });
80
- const handleBlur = (e) => {
81
- var _a;
82
- if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
83
- updateInputValue(selectedItem);
84
- (_a = rest === null || rest === void 0 ? void 0 : rest.onBlur) === null || _a === void 0 ? void 0 : _a.call(rest, e);
85
- }
86
- };
87
80
  const commonHandleOnKeyDown = useHandleOnKeyDown({
88
81
  inputKeyDownNavigationHandler,
89
82
  onInputKeyDownProp,
@@ -97,6 +90,25 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
97
90
  setValue(newValue);
98
91
  }
99
92
  }, [setOpen, setValue]);
93
+ const { resolvedAddCustomOptionTriggers, tryCommitCustomOptionFromInput } = useFieldSelectSingleCustomOption({
94
+ addCustomOptionTriggers: addCustomOptionTriggersProp,
95
+ addOptionByEnter,
96
+ inputValue,
97
+ handleSelectionChange,
98
+ });
99
+ const handleBlur = (e) => {
100
+ var _a;
101
+ if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
102
+ const commitOnBlur = shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers) && inputValue !== '';
103
+ if (commitOnBlur) {
104
+ tryCommitCustomOptionFromInput('blur');
105
+ }
106
+ else {
107
+ updateInputValue(selectedItem);
108
+ }
109
+ (_a = rest === null || rest === void 0 ? void 0 : rest.onBlur) === null || _a === void 0 ? void 0 : _a.call(rest, e);
110
+ }
111
+ };
100
112
  const handleOnKeyDown = (onKeyDown) => (e) => {
101
113
  if (!open && prevInputValue.current !== inputValue) {
102
114
  setOpen(true);
@@ -104,16 +116,14 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
104
116
  if (e.code === 'Enter') {
105
117
  e.stopPropagation();
106
118
  e.preventDefault();
107
- }
108
- if (addOptionByEnter && e.code === 'Enter' && inputValue !== '') {
109
- handleSelectionChange(inputValue);
119
+ tryCommitCustomOptionFromInput('enter');
110
120
  }
111
121
  commonHandleOnKeyDown(onKeyDown)(e);
112
122
  };
113
123
  const handleOpenChange = (open) => {
114
124
  if (isBrowser() && !readonly && !disabled && !buttonsRefs.includes(document.activeElement)) {
115
125
  setOpen(open);
116
- if (!open) {
126
+ if (!open && !shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers)) {
117
127
  updateInputValue(selectedItem);
118
128
  }
119
129
  }
@@ -1,7 +1,7 @@
1
1
  import { KeyboardEvent, KeyboardEventHandler, MouseEvent, RefObject } from 'react';
2
2
  import { Handler } from 'uncontrollable';
3
3
  import { ItemProps } from '@snack-uikit/list';
4
- import { ItemWithId, SearchState, SelectedOptionFormatter } from './types';
4
+ import { ItemWithId, SearchState, SelectedOptionFormatter } from '../types';
5
5
  type UseHandleOnKeyDownProps = {
6
6
  inputKeyDownNavigationHandler: KeyboardEventHandler<HTMLInputElement>;
7
7
  onInputKeyDownProp: KeyboardEventHandler<HTMLInputElement> | undefined;
@@ -2,10 +2,9 @@ import FuzzySearch from 'fuzzy-search';
2
2
  import { useCallback, useMemo, useRef } from 'react';
3
3
  import { useButtonNavigation, useClearButton } from '@snack-uikit/input-private';
4
4
  import { isAccordionItemProps, isNextListItemProps, kindFlattenItems, } from '@snack-uikit/list';
5
- import { useCopyButton, useValueControl } from '../../hooks';
6
- import { extractChildIds } from './legacy';
7
- import { getValueByPath, isBaseOptionProps } from './utils';
8
- import { filterItemsByFlattenIds } from './utils/filterItemsByFlattenIds';
5
+ import { useCopyButton, useValueControl } from '../../../hooks';
6
+ import { extractChildIds } from '../legacy';
7
+ import { filterItemsByFlattenIds, getValueByPath, isBaseOptionProps } from '../utils';
9
8
  export function useHandleOnKeyDown({ setOpen, inputKeyDownNavigationHandler, onInputKeyDownProp, }) {
10
9
  return useCallback((onKeyDown) => (e) => {
11
10
  if (e.code === 'Space') {
@@ -0,0 +1,26 @@
1
+ import { Handler } from 'uncontrollable';
2
+ import { SelectionSingleValueType } from '@snack-uikit/list';
3
+ import { FieldSelectMultipleAddCustomOptionTrigger } from '../types';
4
+ type UseResolvedAddCustomOptionTriggersParams = {
5
+ addCustomOptionTriggers?: FieldSelectMultipleAddCustomOptionTrigger[];
6
+ addOptionByEnter: boolean;
7
+ };
8
+ type UseFieldSelectMultipleCustomOptionParams = UseResolvedAddCustomOptionTriggersParams & {
9
+ inputValue: string;
10
+ value: SelectionSingleValueType[] | undefined;
11
+ setValue: Handler;
12
+ updateInputValue: () => void;
13
+ };
14
+ export declare function useFieldSelectMultipleCustomOption({ addCustomOptionTriggers, addOptionByEnter, inputValue, value, setValue, updateInputValue, }: UseFieldSelectMultipleCustomOptionParams): {
15
+ resolvedAddCustomOptionTriggers: FieldSelectMultipleAddCustomOptionTrigger[];
16
+ tryCommitCustomOptionFromInput: (trigger: FieldSelectMultipleAddCustomOptionTrigger) => void;
17
+ };
18
+ type UseFieldSelectSingleCustomOptionParams = UseResolvedAddCustomOptionTriggersParams & {
19
+ inputValue: string;
20
+ handleSelectionChange: (value: SelectionSingleValueType) => void;
21
+ };
22
+ export declare function useFieldSelectSingleCustomOption({ addCustomOptionTriggers, addOptionByEnter, inputValue, handleSelectionChange, }: UseFieldSelectSingleCustomOptionParams): {
23
+ resolvedAddCustomOptionTriggers: FieldSelectMultipleAddCustomOptionTrigger[];
24
+ tryCommitCustomOptionFromInput: (trigger: FieldSelectMultipleAddCustomOptionTrigger) => void;
25
+ };
26
+ export {};
@@ -0,0 +1,38 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ function useResolvedAddCustomOptionTriggers({ addCustomOptionTriggers, addOptionByEnter, }) {
3
+ return useMemo(() => {
4
+ if (addCustomOptionTriggers !== undefined) {
5
+ return addCustomOptionTriggers;
6
+ }
7
+ return addOptionByEnter ? ['enter'] : [];
8
+ }, [addCustomOptionTriggers, addOptionByEnter]);
9
+ }
10
+ export function useFieldSelectMultipleCustomOption({ addCustomOptionTriggers, addOptionByEnter, inputValue, value, setValue, updateInputValue, }) {
11
+ const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
12
+ addCustomOptionTriggers,
13
+ addOptionByEnter,
14
+ });
15
+ const tryCommitCustomOptionFromInput = useCallback((trigger) => {
16
+ if (!resolvedAddCustomOptionTriggers.includes(trigger) || inputValue === '') {
17
+ return;
18
+ }
19
+ if (!(value !== null && value !== void 0 ? value : []).includes(inputValue)) {
20
+ setValue((prev) => (prev !== null && prev !== void 0 ? prev : []).concat(inputValue));
21
+ updateInputValue();
22
+ }
23
+ }, [resolvedAddCustomOptionTriggers, inputValue, value, setValue, updateInputValue]);
24
+ return { resolvedAddCustomOptionTriggers, tryCommitCustomOptionFromInput };
25
+ }
26
+ export function useFieldSelectSingleCustomOption({ addCustomOptionTriggers, addOptionByEnter, inputValue, handleSelectionChange, }) {
27
+ const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
28
+ addCustomOptionTriggers,
29
+ addOptionByEnter,
30
+ });
31
+ const tryCommitCustomOptionFromInput = useCallback((trigger) => {
32
+ if (!resolvedAddCustomOptionTriggers.includes(trigger) || inputValue === '') {
33
+ return;
34
+ }
35
+ handleSelectionChange(inputValue);
36
+ }, [resolvedAddCustomOptionTriggers, inputValue, handleSelectionChange]);
37
+ return { resolvedAddCustomOptionTriggers, tryCommitCustomOptionFromInput };
38
+ }
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './customOption';
@@ -0,0 +1,2 @@
1
+ export * from './common';
2
+ export * from './customOption';
@@ -1,2 +1,2 @@
1
1
  export { FieldSelect } from './FieldSelect';
2
- export type { FieldSelectSingleProps, FieldSelectMultipleProps, FieldSelectProps, OptionProps, BaseOptionProps, AccordionOptionProps, NestListOptionProps, GroupOptionProps, SelectedOptionFormatter, } from './types';
2
+ export type { FieldSelectMultipleAddCustomOptionTrigger, FieldSelectSingleAddCustomOptionTrigger, FieldSelectSingleProps, FieldSelectMultipleProps, FieldSelectProps, OptionProps, BaseOptionProps, AccordionOptionProps, NestListOptionProps, GroupOptionProps, SelectedOptionFormatter, } from './types';
@@ -31,9 +31,11 @@ export type SearchState = {
31
31
  defaultValue?: string;
32
32
  onChange?(value: string): void;
33
33
  };
34
+ /** События, по которым произвольное значение из строки поиска фиксируется в значении поля */
35
+ export type FieldSelectMultipleAddCustomOptionTrigger = 'enter' | 'blur' | 'space' | 'comma';
36
+ export type FieldSelectSingleAddCustomOptionTrigger = Extract<FieldSelectMultipleAddCustomOptionTrigger, 'enter' | 'blur'>;
34
37
  export type FieldSelectPrivateProps = InputProps & WrapperProps & {
35
38
  options: OptionProps[];
36
- /** Отображать ли состояние загрузки данных в поле и списке */
37
39
  loading?: boolean;
38
40
  /** Произвольный префикс для поля */
39
41
  prefix?: ReactNode;
@@ -65,6 +67,9 @@ type FiledSelectCommonProps = WithSupportProps<{
65
67
  widthStrategy?: DroplistProps['widthStrategy'];
66
68
  search?: SearchState;
67
69
  autocomplete?: boolean;
70
+ /**
71
+ * @deprecated Используйте `addCustomOptionTriggers`
72
+ */
68
73
  addOptionByEnter?: boolean;
69
74
  open?: boolean;
70
75
  /** Включить нечеткий поиск */
@@ -76,10 +81,22 @@ type FiledSelectCommonProps = WithSupportProps<{
76
81
  onOpenChange?(open: boolean): void;
77
82
  selectedOptionFormatter?: SelectedOptionFormatter;
78
83
  }> & Pick<DroplistProps, 'dataError' | 'noDataState' | 'noResultsState' | 'errorDataState' | 'dataFiltered' | 'untouchableScrollbars' | 'scrollToSelectedItem' | 'virtualized' | 'scrollRef' | 'scrollContainerRef' | 'onScroll'>;
79
- export type FieldSelectSingleProps = FieldSelectPrivateProps & Omit<SelectionSingleState, 'mode'> & WrapperProps & FiledSelectCommonProps;
84
+ export type FieldSelectSingleProps = FieldSelectPrivateProps & Omit<SelectionSingleState, 'mode'> & WrapperProps & FiledSelectCommonProps & {
85
+ /**
86
+ * Триггеры фиксации произвольного значения из строки поиска в режиме `single`.
87
+ * Если передан, имеет приоритет над устаревшим `addOptionByEnter`.
88
+ */
89
+ addCustomOptionTriggers?: FieldSelectSingleAddCustomOptionTrigger[];
90
+ };
80
91
  export type FieldSelectMultipleProps = FieldSelectPrivateProps & {
81
92
  removeByBackspace?: boolean;
82
- } & Omit<SelectionMultipleState, 'mode'> & Omit<FiledSelectCommonProps, 'showCopyButton' | 'onCopyButtonClick'>;
93
+ } & Omit<SelectionMultipleState, 'mode'> & Omit<FiledSelectCommonProps, 'showCopyButton' | 'onCopyButtonClick'> & {
94
+ /**
95
+ * Триггеры фиксации произвольного значения из строки поиска в режиме `multiple`.
96
+ * Если передан, имеет приоритет над устаревшим `addOptionByEnter`.
97
+ */
98
+ addCustomOptionTriggers?: FieldSelectMultipleAddCustomOptionTrigger[];
99
+ };
83
100
  export type FieldSelectProps = (FieldSelectSingleProps & {
84
101
  selection?: 'single';
85
102
  }) | (FieldSelectMultipleProps & {
@@ -0,0 +1,4 @@
1
+ import { KeyboardEvent } from 'react';
2
+ import { FieldSelectMultipleAddCustomOptionTrigger } from '../types';
3
+ export declare const getCustomOptionTriggerByCode: (code: KeyboardEvent<HTMLInputElement>["code"]) => FieldSelectMultipleAddCustomOptionTrigger | undefined;
4
+ export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectMultipleAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectMultipleAddCustomOptionTrigger[]) => trigger is FieldSelectMultipleAddCustomOptionTrigger;