@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.
- package/CHANGELOG.md +11 -0
- package/README.md +28 -130
- package/dist/cjs/components/FieldSecure/FieldSecure.d.ts +1 -1
- package/dist/cjs/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
- package/dist/cjs/components/FieldSelect/FieldSelectMultiple.js +28 -7
- package/dist/cjs/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
- package/dist/cjs/components/FieldSelect/FieldSelectSingle.js +25 -12
- package/dist/cjs/components/FieldSelect/{hooks.d.ts → hooks/common.d.ts} +1 -1
- package/dist/cjs/components/FieldSelect/{hooks.js → hooks/common.js} +4 -5
- package/dist/cjs/components/FieldSelect/hooks/customOption.d.ts +26 -0
- package/dist/cjs/components/FieldSelect/hooks/customOption.js +69 -0
- package/dist/cjs/components/FieldSelect/hooks/index.d.ts +2 -0
- package/dist/cjs/components/FieldSelect/hooks/index.js +26 -0
- package/dist/cjs/components/FieldSelect/index.d.ts +1 -1
- package/dist/cjs/components/FieldSelect/types.d.ts +20 -3
- package/dist/cjs/components/FieldSelect/utils/customOption.d.ts +4 -0
- package/dist/cjs/components/FieldSelect/utils/customOption.js +21 -0
- package/dist/cjs/components/FieldSelect/utils/index.d.ts +2 -0
- package/dist/cjs/components/FieldSelect/utils/index.js +3 -1
- package/dist/cjs/components/FieldText/FieldText.d.ts +1 -1
- package/dist/cjs/components/FieldTextArea/FieldTextArea.d.ts +1 -1
- package/dist/cjs/components/index.d.ts +0 -1
- package/dist/cjs/components/index.js +0 -1
- package/dist/cjs/helperComponents/ButtonFieldList/ButtonFieldList.d.ts +1 -1
- package/dist/esm/components/FieldSecure/FieldSecure.d.ts +1 -1
- package/dist/esm/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
- package/dist/esm/components/FieldSelect/FieldSelectMultiple.js +27 -9
- package/dist/esm/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
- package/dist/esm/components/FieldSelect/FieldSelectSingle.js +24 -14
- package/dist/esm/components/FieldSelect/{hooks.d.ts → hooks/common.d.ts} +1 -1
- package/dist/esm/components/FieldSelect/{hooks.js → hooks/common.js} +3 -4
- package/dist/esm/components/FieldSelect/hooks/customOption.d.ts +26 -0
- package/dist/esm/components/FieldSelect/hooks/customOption.js +38 -0
- package/dist/esm/components/FieldSelect/hooks/index.d.ts +2 -0
- package/dist/esm/components/FieldSelect/hooks/index.js +2 -0
- package/dist/esm/components/FieldSelect/index.d.ts +1 -1
- package/dist/esm/components/FieldSelect/types.d.ts +20 -3
- package/dist/esm/components/FieldSelect/utils/customOption.d.ts +4 -0
- package/dist/esm/components/FieldSelect/utils/customOption.js +13 -0
- package/dist/esm/components/FieldSelect/utils/index.d.ts +2 -0
- package/dist/esm/components/FieldSelect/utils/index.js +2 -0
- package/dist/esm/components/FieldText/FieldText.d.ts +1 -1
- package/dist/esm/components/FieldTextArea/FieldTextArea.d.ts +1 -1
- package/dist/esm/components/index.d.ts +0 -1
- package/dist/esm/components/index.js +0 -1
- package/dist/esm/helperComponents/ButtonFieldList/ButtonFieldList.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/FieldSelect/FieldSelectMultiple.tsx +55 -10
- package/src/components/FieldSelect/FieldSelectSingle.tsx +33 -15
- package/src/components/FieldSelect/{hooks.ts → hooks/common.ts} +4 -5
- package/src/components/FieldSelect/hooks/customOption.ts +90 -0
- package/src/components/FieldSelect/hooks/index.ts +2 -0
- package/src/components/FieldSelect/index.ts +2 -0
- package/src/components/FieldSelect/types.ts +24 -3
- package/src/components/FieldSelect/utils/customOption.ts +23 -0
- package/src/components/FieldSelect/utils/index.ts +2 -0
- package/src/components/index.ts +0 -1
- package/dist/cjs/components/FieldAdd/FieldAdd.d.ts +0 -52
- package/dist/cjs/components/FieldAdd/FieldAdd.js +0 -216
- package/dist/cjs/components/FieldAdd/index.d.ts +0 -2
- package/dist/cjs/components/FieldAdd/index.js +0 -13
- package/dist/cjs/components/FieldAdd/styles.module.css +0 -51
- package/dist/esm/components/FieldAdd/FieldAdd.d.ts +0 -52
- package/dist/esm/components/FieldAdd/FieldAdd.js +0 -31
- package/dist/esm/components/FieldAdd/index.d.ts +0 -2
- package/dist/esm/components/FieldAdd/index.js +0 -1
- package/dist/esm/components/FieldAdd/styles.module.css +0 -51
- package/src/components/FieldAdd/FieldAdd.tsx +0 -215
- package/src/components/FieldAdd/index.ts +0 -3
- 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,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;
|
|
@@ -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" | "
|
|
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" | "
|
|
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 {};
|
|
@@ -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" | "
|
|
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" | "
|
|
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"> &
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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 ?
|
|
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"> &
|
|
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 '
|
|
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 '
|
|
6
|
-
import { extractChildIds } from '
|
|
7
|
-
import { getValueByPath, isBaseOptionProps } from '
|
|
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
|
+
}
|
|
@@ -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;
|