@snack-uikit/fields 0.53.2-preview-74573911.0 → 0.53.2-preview-0be0d183.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/dist/cjs/components/FieldSelect/FieldSelectMultiple.js +16 -9
- package/dist/cjs/components/FieldSelect/FieldSelectSingle.js +2 -4
- package/dist/cjs/components/FieldSelect/utils/getCustomOptionTriggerByCode.d.ts +1 -1
- package/dist/cjs/components/FieldSelect/utils/getCustomOptionTriggerByCode.js +10 -19
- package/dist/esm/components/FieldSelect/FieldSelectMultiple.js +16 -8
- package/dist/esm/components/FieldSelect/FieldSelectSingle.js +3 -5
- package/dist/esm/components/FieldSelect/utils/getCustomOptionTriggerByCode.d.ts +1 -1
- package/dist/esm/components/FieldSelect/utils/getCustomOptionTriggerByCode.js +10 -18
- package/package.json +2 -2
- package/src/components/FieldSelect/FieldSelectMultiple.tsx +19 -10
- package/src/components/FieldSelect/FieldSelectSingle.tsx +10 -5
- package/src/components/FieldSelect/utils/getCustomOptionTriggerByCode.ts +10 -24
|
@@ -62,7 +62,7 @@ exports.FieldSelectMultiple = (0, react_1.forwardRef)((props, ref) => {
|
|
|
62
62
|
postfix,
|
|
63
63
|
removeByBackspace = false,
|
|
64
64
|
addOptionByEnter = false,
|
|
65
|
-
addCustomOptionTriggers
|
|
65
|
+
addCustomOptionTriggers,
|
|
66
66
|
untouchableScrollbars = false,
|
|
67
67
|
open: openProp,
|
|
68
68
|
enableFuzzySearch = true,
|
|
@@ -104,7 +104,7 @@ exports.FieldSelectMultiple = (0, react_1.forwardRef)((props, ref) => {
|
|
|
104
104
|
resetSearchOnOptionSelection
|
|
105
105
|
}));
|
|
106
106
|
const resolvedAddCustomOptionTriggers = (0, hooks_2.useResolvedAddCustomOptionTriggers)({
|
|
107
|
-
addCustomOptionTriggers
|
|
107
|
+
addCustomOptionTriggers,
|
|
108
108
|
addOptionByEnter
|
|
109
109
|
});
|
|
110
110
|
const tryCommitCustomOptionFromInput = (0, react_1.useCallback)(trigger => {
|
|
@@ -169,6 +169,12 @@ exports.FieldSelectMultiple = (0, react_1.forwardRef)((props, ref) => {
|
|
|
169
169
|
setOpen
|
|
170
170
|
});
|
|
171
171
|
const handleItemDelete = (0, hooks_2.useHandleDeleteItem)(setValue);
|
|
172
|
+
const handleTagDelete = (0, react_1.useCallback)(option => () => {
|
|
173
|
+
var _a;
|
|
174
|
+
const deleteItemHandler = handleItemDelete(option);
|
|
175
|
+
deleteItemHandler();
|
|
176
|
+
(_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
177
|
+
}, [handleItemDelete]);
|
|
172
178
|
const handleOnKeyDown = onKeyDown => e => {
|
|
173
179
|
if (removeByBackspace && e.code === 'Backspace' && inputValue === '') {
|
|
174
180
|
if ((selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) && !selectedItems.slice(-1)[0].disabled) {
|
|
@@ -179,12 +185,13 @@ exports.FieldSelectMultiple = (0, react_1.forwardRef)((props, ref) => {
|
|
|
179
185
|
e.stopPropagation();
|
|
180
186
|
e.preventDefault();
|
|
181
187
|
tryCommitCustomOptionFromInput('enter');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
} else {
|
|
189
|
+
const customOptionTrigger = (0, utils_3.getCustomOptionTriggerByCode)(e.code);
|
|
190
|
+
if ((0, utils_3.shouldHandleCustomOptionTrigger)(customOptionTrigger, resolvedAddCustomOptionTriggers)) {
|
|
191
|
+
e.stopPropagation();
|
|
192
|
+
e.preventDefault();
|
|
193
|
+
tryCommitCustomOptionFromInput(customOptionTrigger);
|
|
194
|
+
}
|
|
188
195
|
}
|
|
189
196
|
if (!open && prevInputValue.current !== inputValue) {
|
|
190
197
|
setOpen(true);
|
|
@@ -294,7 +301,7 @@ exports.FieldSelectMultiple = (0, react_1.forwardRef)((props, ref) => {
|
|
|
294
301
|
tabIndex: -1,
|
|
295
302
|
label: selectedOptionFormatter(option),
|
|
296
303
|
appearance: (_a = option.appearance) !== null && _a !== void 0 ? _a : 'neutral',
|
|
297
|
-
onDelete: !option.disabled && !disabled && !readonly ?
|
|
304
|
+
onDelete: !option.disabled && !disabled && !readonly ? handleTagDelete(option) : undefined,
|
|
298
305
|
className: styles_module_scss_1.default.tag,
|
|
299
306
|
"data-disabled": disabled || undefined
|
|
300
307
|
}, option.id);
|
|
@@ -187,10 +187,8 @@ exports.FieldSelectSingle = (0, react_1.forwardRef)((props, ref) => {
|
|
|
187
187
|
const handleBlur = e => {
|
|
188
188
|
var _a;
|
|
189
189
|
if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
|
|
190
|
-
const commitOnBlur =
|
|
190
|
+
const commitOnBlur = (0, utils_3.shouldHandleCustomOptionTrigger)('blur', resolvedAddCustomOptionTriggers) && inputValue !== '';
|
|
191
191
|
if (commitOnBlur) {
|
|
192
|
-
// При commit обновление input происходит реактивно после смены value/selectedItem.
|
|
193
|
-
// Здесь нельзя вызывать updateInputValue(selectedItem), чтобы не использовать устаревший selectedItem.
|
|
194
192
|
tryCommitCustomOptionFromInput('blur');
|
|
195
193
|
} else {
|
|
196
194
|
updateInputValue(selectedItem);
|
|
@@ -212,7 +210,7 @@ exports.FieldSelectSingle = (0, react_1.forwardRef)((props, ref) => {
|
|
|
212
210
|
const handleOpenChange = open => {
|
|
213
211
|
if ((0, utils_1.isBrowser)() && !readonly && !disabled && !buttonsRefs.includes(document.activeElement)) {
|
|
214
212
|
setOpen(open);
|
|
215
|
-
if (!open && !
|
|
213
|
+
if (!open && !(0, utils_3.shouldHandleCustomOptionTrigger)('blur', resolvedAddCustomOptionTriggers)) {
|
|
216
214
|
updateInputValue(selectedItem);
|
|
217
215
|
}
|
|
218
216
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { KeyboardEvent } from 'react';
|
|
2
2
|
import { FieldSelectAddCustomOptionTrigger } from '../types';
|
|
3
3
|
export declare const getCustomOptionTriggerByCode: (code: KeyboardEvent<HTMLInputElement>["code"]) => FieldSelectAddCustomOptionTrigger | undefined;
|
|
4
|
-
export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectAddCustomOptionTrigger[]
|
|
4
|
+
export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectAddCustomOptionTrigger[]) => trigger is FieldSelectAddCustomOptionTrigger;
|
|
@@ -5,26 +5,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.shouldHandleCustomOptionTrigger = exports.getCustomOptionTriggerByCode = void 0;
|
|
7
7
|
const getCustomOptionTriggerByCode = code => {
|
|
8
|
-
|
|
9
|
-
|
|
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;
|
|
10
17
|
}
|
|
11
|
-
if (code === 'Space') {
|
|
12
|
-
return 'space';
|
|
13
|
-
}
|
|
14
|
-
if (code === 'Comma') {
|
|
15
|
-
return 'comma';
|
|
16
|
-
}
|
|
17
|
-
return undefined;
|
|
18
18
|
};
|
|
19
19
|
exports.getCustomOptionTriggerByCode = getCustomOptionTriggerByCode;
|
|
20
|
-
const shouldHandleCustomOptionTrigger =
|
|
21
|
-
let ignoredTriggers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
|
|
22
|
-
if (!trigger) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
if (ignoredTriggers.includes(trigger)) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
return availableTriggers.includes(trigger);
|
|
29
|
-
};
|
|
20
|
+
const shouldHandleCustomOptionTrigger = (trigger, availableTriggers) => trigger ? availableTriggers.includes(trigger) : false;
|
|
30
21
|
exports.shouldHandleCustomOptionTrigger = shouldHandleCustomOptionTrigger;
|
|
@@ -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, addCustomOptionTriggers
|
|
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);
|
|
@@ -46,7 +46,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
46
46
|
const { inputValue, setInputValue, prevInputValue, updateInputValue } = useSearchInput(Object.assign(Object.assign({}, search), { defaultValue: '', selectedOptionFormatter,
|
|
47
47
|
resetSearchOnOptionSelection }));
|
|
48
48
|
const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
|
|
49
|
-
addCustomOptionTriggers
|
|
49
|
+
addCustomOptionTriggers,
|
|
50
50
|
addOptionByEnter,
|
|
51
51
|
});
|
|
52
52
|
const tryCommitCustomOptionFromInput = useCallback((trigger) => {
|
|
@@ -86,6 +86,12 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
86
86
|
setOpen,
|
|
87
87
|
});
|
|
88
88
|
const handleItemDelete = useHandleDeleteItem(setValue);
|
|
89
|
+
const handleTagDelete = useCallback((option) => () => {
|
|
90
|
+
var _a;
|
|
91
|
+
const deleteItemHandler = handleItemDelete(option);
|
|
92
|
+
deleteItemHandler();
|
|
93
|
+
(_a = localRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
94
|
+
}, [handleItemDelete]);
|
|
89
95
|
const handleOnKeyDown = (onKeyDown) => (e) => {
|
|
90
96
|
if (removeByBackspace && e.code === 'Backspace' && inputValue === '') {
|
|
91
97
|
if ((selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.length) && !selectedItems.slice(-1)[0].disabled) {
|
|
@@ -97,11 +103,13 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
97
103
|
e.preventDefault();
|
|
98
104
|
tryCommitCustomOptionFromInput('enter');
|
|
99
105
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
else {
|
|
107
|
+
const customOptionTrigger = getCustomOptionTriggerByCode(e.code);
|
|
108
|
+
if (shouldHandleCustomOptionTrigger(customOptionTrigger, resolvedAddCustomOptionTriggers)) {
|
|
109
|
+
e.stopPropagation();
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
tryCommitCustomOptionFromInput(customOptionTrigger);
|
|
112
|
+
}
|
|
105
113
|
}
|
|
106
114
|
if (!open && prevInputValue.current !== inputValue) {
|
|
107
115
|
setOpen(true);
|
|
@@ -169,7 +177,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
169
177
|
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 &&
|
|
170
178
|
selectedItems.map(option => {
|
|
171
179
|
var _a;
|
|
172
|
-
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 ?
|
|
180
|
+
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));
|
|
173
181
|
}), _jsx("div", { className: styles.inputWrapper, style: {
|
|
174
182
|
minWidth: value
|
|
175
183
|
? 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)
|
|
@@ -23,7 +23,7 @@ import { FieldDecorator } from '../FieldDecorator';
|
|
|
23
23
|
import { extractFieldDecoratorProps } from '../FieldDecorator/utils';
|
|
24
24
|
import { useButtons, useHandleOnKeyDown, useResolvedAddCustomOptionTriggers, 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
|
|
@@ -103,10 +103,8 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
|
|
|
103
103
|
const handleBlur = (e) => {
|
|
104
104
|
var _a;
|
|
105
105
|
if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
|
|
106
|
-
const commitOnBlur =
|
|
106
|
+
const commitOnBlur = shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers) && inputValue !== '';
|
|
107
107
|
if (commitOnBlur) {
|
|
108
|
-
// При commit обновление input происходит реактивно после смены value/selectedItem.
|
|
109
|
-
// Здесь нельзя вызывать updateInputValue(selectedItem), чтобы не использовать устаревший selectedItem.
|
|
110
108
|
tryCommitCustomOptionFromInput('blur');
|
|
111
109
|
}
|
|
112
110
|
else {
|
|
@@ -129,7 +127,7 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
|
|
|
129
127
|
const handleOpenChange = (open) => {
|
|
130
128
|
if (isBrowser() && !readonly && !disabled && !buttonsRefs.includes(document.activeElement)) {
|
|
131
129
|
setOpen(open);
|
|
132
|
-
if (!open && !
|
|
130
|
+
if (!open && !shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers)) {
|
|
133
131
|
updateInputValue(selectedItem);
|
|
134
132
|
}
|
|
135
133
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { KeyboardEvent } from 'react';
|
|
2
2
|
import { FieldSelectAddCustomOptionTrigger } from '../types';
|
|
3
3
|
export declare const getCustomOptionTriggerByCode: (code: KeyboardEvent<HTMLInputElement>["code"]) => FieldSelectAddCustomOptionTrigger | undefined;
|
|
4
|
-
export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectAddCustomOptionTrigger[]
|
|
4
|
+
export declare const shouldHandleCustomOptionTrigger: (trigger: FieldSelectAddCustomOptionTrigger | undefined, availableTriggers: FieldSelectAddCustomOptionTrigger[]) => trigger is FieldSelectAddCustomOptionTrigger;
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
export const getCustomOptionTriggerByCode = (code) => {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
switch (code) {
|
|
3
|
+
case 'Enter':
|
|
4
|
+
return 'enter';
|
|
5
|
+
case 'Space':
|
|
6
|
+
return 'space';
|
|
7
|
+
case 'Comma':
|
|
8
|
+
return 'comma';
|
|
9
|
+
default:
|
|
10
|
+
return undefined;
|
|
4
11
|
}
|
|
5
|
-
if (code === 'Space') {
|
|
6
|
-
return 'space';
|
|
7
|
-
}
|
|
8
|
-
if (code === 'Comma') {
|
|
9
|
-
return 'comma';
|
|
10
|
-
}
|
|
11
|
-
return undefined;
|
|
12
|
-
};
|
|
13
|
-
export const shouldHandleCustomOptionTrigger = (trigger, availableTriggers, ignoredTriggers = []) => {
|
|
14
|
-
if (!trigger) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
if (ignoredTriggers.includes(trigger)) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
return availableTriggers.includes(trigger);
|
|
21
12
|
};
|
|
13
|
+
export const shouldHandleCustomOptionTrigger = (trigger, availableTriggers) => (trigger ? availableTriggers.includes(trigger) : false);
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Fields",
|
|
7
|
-
"version": "0.53.2-preview-
|
|
7
|
+
"version": "0.53.2-preview-0be0d183.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"@snack-uikit/locale": "*"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "5eb2aad3219d953d4e2ea540da79a84bb03ee4c1"
|
|
70
70
|
}
|
|
@@ -75,7 +75,7 @@ export const FieldSelectMultiple = forwardRef<HTMLInputElement, FieldSelectMulti
|
|
|
75
75
|
postfix,
|
|
76
76
|
removeByBackspace = false,
|
|
77
77
|
addOptionByEnter = false,
|
|
78
|
-
addCustomOptionTriggers
|
|
78
|
+
addCustomOptionTriggers,
|
|
79
79
|
untouchableScrollbars = false,
|
|
80
80
|
open: openProp,
|
|
81
81
|
enableFuzzySearch = true,
|
|
@@ -110,7 +110,7 @@ export const FieldSelectMultiple = forwardRef<HTMLInputElement, FieldSelectMulti
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
const resolvedAddCustomOptionTriggers = useResolvedAddCustomOptionTriggers({
|
|
113
|
-
addCustomOptionTriggers
|
|
113
|
+
addCustomOptionTriggers,
|
|
114
114
|
addOptionByEnter,
|
|
115
115
|
});
|
|
116
116
|
|
|
@@ -162,6 +162,15 @@ export const FieldSelectMultiple = forwardRef<HTMLInputElement, FieldSelectMulti
|
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
const handleItemDelete = useHandleDeleteItem(setValue);
|
|
165
|
+
const handleTagDelete = useCallback(
|
|
166
|
+
(option: BaseItemProps) => () => {
|
|
167
|
+
const deleteItemHandler = handleItemDelete(option);
|
|
168
|
+
deleteItemHandler();
|
|
169
|
+
localRef.current?.focus();
|
|
170
|
+
},
|
|
171
|
+
[handleItemDelete],
|
|
172
|
+
);
|
|
173
|
+
|
|
165
174
|
const handleOnKeyDown = (onKeyDown?: KeyboardEventHandler<HTMLElement>) => (e: KeyboardEvent<HTMLInputElement>) => {
|
|
166
175
|
if (removeByBackspace && e.code === 'Backspace' && inputValue === '') {
|
|
167
176
|
if (selectedItems?.length && !selectedItems.slice(-1)[0].disabled) {
|
|
@@ -173,14 +182,14 @@ export const FieldSelectMultiple = forwardRef<HTMLInputElement, FieldSelectMulti
|
|
|
173
182
|
e.stopPropagation();
|
|
174
183
|
e.preventDefault();
|
|
175
184
|
tryCommitCustomOptionFromInput('enter');
|
|
176
|
-
}
|
|
185
|
+
} else {
|
|
186
|
+
const customOptionTrigger = getCustomOptionTriggerByCode(e.code);
|
|
177
187
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
tryCommitCustomOptionFromInput(customOptionTrigger);
|
|
188
|
+
if (shouldHandleCustomOptionTrigger(customOptionTrigger, resolvedAddCustomOptionTriggers)) {
|
|
189
|
+
e.stopPropagation();
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
tryCommitCustomOptionFromInput(customOptionTrigger);
|
|
192
|
+
}
|
|
184
193
|
}
|
|
185
194
|
|
|
186
195
|
if (!open && prevInputValue.current !== inputValue) {
|
|
@@ -302,7 +311,7 @@ export const FieldSelectMultiple = forwardRef<HTMLInputElement, FieldSelectMulti
|
|
|
302
311
|
label={selectedOptionFormatter(option)}
|
|
303
312
|
key={option.id}
|
|
304
313
|
appearance={option.appearance ?? 'neutral'}
|
|
305
|
-
onDelete={!option.disabled && !disabled && !readonly ?
|
|
314
|
+
onDelete={!option.disabled && !disabled && !readonly ? handleTagDelete(option) : undefined}
|
|
306
315
|
className={styles.tag}
|
|
307
316
|
data-disabled={disabled || undefined}
|
|
308
317
|
/>
|
|
@@ -28,7 +28,13 @@ import {
|
|
|
28
28
|
ItemWithId,
|
|
29
29
|
SelectedOptionFormatter,
|
|
30
30
|
} from './types';
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
checkisSearchUnavailable,
|
|
33
|
+
extractListProps,
|
|
34
|
+
getArrowIcon,
|
|
35
|
+
shouldHandleCustomOptionTrigger,
|
|
36
|
+
updateItems,
|
|
37
|
+
} from './utils';
|
|
32
38
|
|
|
33
39
|
const defaultSelectedOptionFormatter: SelectedOptionFormatter = item =>
|
|
34
40
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
@@ -173,11 +179,10 @@ export const FieldSelectSingle = forwardRef<HTMLInputElement, FieldSelectSingleP
|
|
|
173
179
|
|
|
174
180
|
const handleBlur = (e: FocusEvent<HTMLInputElement>) => {
|
|
175
181
|
if (!open && !buttonsRefs.filter(Boolean).includes(e.relatedTarget)) {
|
|
176
|
-
const commitOnBlur =
|
|
182
|
+
const commitOnBlur =
|
|
183
|
+
shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers) && inputValue !== '';
|
|
177
184
|
|
|
178
185
|
if (commitOnBlur) {
|
|
179
|
-
// При commit обновление input происходит реактивно после смены value/selectedItem.
|
|
180
|
-
// Здесь нельзя вызывать updateInputValue(selectedItem), чтобы не использовать устаревший selectedItem.
|
|
181
186
|
tryCommitCustomOptionFromInput('blur');
|
|
182
187
|
} else {
|
|
183
188
|
updateInputValue(selectedItem);
|
|
@@ -205,7 +210,7 @@ export const FieldSelectSingle = forwardRef<HTMLInputElement, FieldSelectSingleP
|
|
|
205
210
|
if (isBrowser() && !readonly && !disabled && !buttonsRefs.includes(document.activeElement)) {
|
|
206
211
|
setOpen(open);
|
|
207
212
|
|
|
208
|
-
if (!open && !
|
|
213
|
+
if (!open && !shouldHandleCustomOptionTrigger('blur', resolvedAddCustomOptionTriggers)) {
|
|
209
214
|
updateInputValue(selectedItem);
|
|
210
215
|
}
|
|
211
216
|
}
|
|
@@ -5,33 +5,19 @@ import { FieldSelectAddCustomOptionTrigger } from '../types';
|
|
|
5
5
|
export const getCustomOptionTriggerByCode = (
|
|
6
6
|
code: KeyboardEvent<HTMLInputElement>['code'],
|
|
7
7
|
): FieldSelectAddCustomOptionTrigger | undefined => {
|
|
8
|
-
|
|
9
|
-
|
|
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;
|
|
10
17
|
}
|
|
11
|
-
|
|
12
|
-
if (code === 'Space') {
|
|
13
|
-
return 'space';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (code === 'Comma') {
|
|
17
|
-
return 'comma';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return undefined;
|
|
21
18
|
};
|
|
22
19
|
|
|
23
20
|
export const shouldHandleCustomOptionTrigger = (
|
|
24
21
|
trigger: FieldSelectAddCustomOptionTrigger | undefined,
|
|
25
22
|
availableTriggers: FieldSelectAddCustomOptionTrigger[],
|
|
26
|
-
|
|
27
|
-
): trigger is FieldSelectAddCustomOptionTrigger => {
|
|
28
|
-
if (!trigger) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
if (ignoredTriggers.includes(trigger)) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return availableTriggers.includes(trigger);
|
|
37
|
-
};
|
|
23
|
+
): trigger is FieldSelectAddCustomOptionTrigger => (trigger ? availableTriggers.includes(trigger) : false);
|