@snack-uikit/fields 0.28.0 → 0.29.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 +16 -0
- package/README.md +9 -0
- package/dist/components/FieldColor/FieldColor.d.ts +1 -1
- package/dist/components/FieldColor/FieldColor.js +3 -3
- package/dist/components/FieldDate/FieldDate.js +11 -5
- package/dist/components/FieldSecure/FieldSecure.d.ts +1 -1
- package/dist/components/FieldSecure/FieldSecure.js +3 -3
- package/dist/components/FieldSelect/FieldSelectMultiple.d.ts +3 -1
- package/dist/components/FieldSelect/FieldSelectMultiple.js +7 -5
- package/dist/components/FieldSelect/FieldSelectSingle.d.ts +3 -1
- package/dist/components/FieldSelect/FieldSelectSingle.js +8 -6
- package/dist/components/FieldSelect/hooks.d.ts +1 -1
- package/dist/components/FieldSelect/hooks.js +3 -3
- package/dist/components/FieldSelect/types.d.ts +5 -1
- package/dist/components/FieldSlider/FieldSlider.d.ts +6 -2
- package/dist/components/FieldSlider/FieldSlider.js +13 -11
- package/dist/components/FieldStepper/FieldStepper.d.ts +5 -1
- package/dist/components/FieldStepper/FieldStepper.js +6 -4
- package/dist/components/FieldText/FieldText.d.ts +9 -2
- package/dist/components/FieldText/FieldText.js +46 -8
- package/dist/components/FieldText/helpers.d.ts +4 -0
- package/dist/components/FieldText/helpers.js +9 -0
- package/dist/components/FieldTextArea/FieldTextArea.d.ts +1 -1
- package/dist/components/FieldTextArea/FieldTextArea.js +3 -3
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +6 -0
- package/dist/helperComponents/ButtonField/ButtonField.d.ts +18 -0
- package/dist/helperComponents/ButtonField/ButtonField.js +10 -0
- package/dist/helperComponents/ButtonField/index.d.ts +1 -0
- package/dist/helperComponents/ButtonField/index.js +1 -0
- package/dist/helperComponents/ButtonField/styles.module.css +96 -0
- package/dist/helperComponents/ButtonFieldList/ButtonFieldList.d.ts +4 -0
- package/dist/helperComponents/ButtonFieldList/ButtonFieldList.js +27 -0
- package/dist/helperComponents/ButtonFieldList/helpers.d.ts +5 -0
- package/dist/helperComponents/ButtonFieldList/helpers.js +8 -0
- package/dist/helperComponents/ButtonFieldList/index.d.ts +1 -0
- package/dist/helperComponents/ButtonFieldList/index.js +1 -0
- package/dist/helperComponents/ButtonFieldList/styles.module.css +3 -0
- package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.d.ts +5 -4
- package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.js +2 -2
- package/dist/helperComponents/FieldContainerPrivate/styles.module.css +56 -5
- package/dist/helperComponents/index.d.ts +2 -0
- package/dist/helperComponents/index.js +2 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/styles.module.css +13 -0
- package/dist/hooks/useCopyButton.d.ts +3 -1
- package/dist/hooks/useCopyButton.js +4 -3
- package/dist/hooks/useHideButton.js +1 -0
- package/dist/hooks/usePostfix.d.ts +6 -0
- package/dist/hooks/usePostfix.js +11 -0
- package/dist/hooks/usePostfixButton.d.ts +11 -0
- package/dist/hooks/usePostfixButton.js +28 -0
- package/dist/hooks/usePrefix.d.ts +6 -0
- package/dist/hooks/usePrefix.js +11 -0
- package/dist/hooks/usePrefixButton.d.ts +11 -0
- package/dist/hooks/usePrefixButton.js +28 -0
- package/dist/types.d.ts +12 -1
- package/package.json +6 -5
- package/src/components/FieldColor/FieldColor.tsx +6 -3
- package/src/components/FieldDate/FieldDate.tsx +17 -10
- package/src/components/FieldSecure/FieldSecure.tsx +3 -3
- package/src/components/FieldSelect/FieldSelectMultiple.tsx +17 -4
- package/src/components/FieldSelect/FieldSelectSingle.tsx +17 -4
- package/src/components/FieldSelect/hooks.ts +3 -3
- package/src/components/FieldSelect/types.ts +10 -2
- package/src/components/FieldSlider/FieldSlider.tsx +30 -14
- package/src/components/FieldStepper/FieldStepper.tsx +40 -23
- package/src/components/FieldText/FieldText.tsx +78 -10
- package/src/components/FieldText/helpers.tsx +13 -0
- package/src/components/FieldTextArea/FieldTextArea.tsx +6 -3
- package/src/constants.ts +7 -0
- package/src/helperComponents/ButtonField/ButtonField.tsx +73 -0
- package/src/helperComponents/ButtonField/index.ts +1 -0
- package/src/helperComponents/ButtonField/styles.module.scss +57 -0
- package/src/helperComponents/ButtonFieldList/ButtonFieldList.tsx +36 -0
- package/src/helperComponents/ButtonFieldList/helpers.tsx +13 -0
- package/src/helperComponents/ButtonFieldList/index.ts +1 -0
- package/src/helperComponents/ButtonFieldList/styles.module.scss +5 -0
- package/src/helperComponents/FieldContainerPrivate/FieldContainerPrivate.tsx +6 -3
- package/src/helperComponents/FieldContainerPrivate/styles.module.scss +14 -8
- package/src/helperComponents/index.ts +2 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/styles.module.scss +17 -0
- package/src/hooks/useCopyButton.tsx +7 -2
- package/src/hooks/useHideButton.tsx +1 -0
- package/src/hooks/usePostfix.tsx +21 -0
- package/src/hooks/usePostfixButton.tsx +74 -0
- package/src/hooks/usePrefix.tsx +21 -0
- package/src/hooks/usePrefixButton.tsx +74 -0
- package/src/types.ts +16 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 0.29.0 (2024-09-27)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **PDS-199:** ajust components according to new useButtonNavigation api ([4e9b58b](https://github.com/cloud-ru-tech/snack-uikit/commit/4e9b58b2345e4e630aee94679c9831c9861a4548))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **PDS-199:** add button prop - to field-text; add prefix and postfix props - to field-text, field-slider, field-stepper, field-select ([8bfb5eb](https://github.com/cloud-ru-tech/snack-uikit/commit/8bfb5ebc9320a451cb3765b8377e022115b4a371))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
# 0.28.0 (2024-09-26)
|
|
7
23
|
|
|
8
24
|
|
package/README.md
CHANGED
|
@@ -214,6 +214,9 @@ FieldStepper в основном предназначен для работы с
|
|
|
214
214
|
| showClearButton | `boolean` | true | Отображение кнопки очистки поля |
|
|
215
215
|
| allowMoreThanMaxLength | `boolean` | - | Можно ли вводить больше разрешённого кол-ва символов |
|
|
216
216
|
| prefixIcon | `ReactElement<any, string \| JSXElementConstructor<any>>` | - | Иконка-префикс для поля |
|
|
217
|
+
| prefix | `ReactNode` | - | Произвольный префикс для поля |
|
|
218
|
+
| postfix | `ReactNode` | - | Произвольный постфикс для поля |
|
|
219
|
+
| button | `Button` | - | Кнопка действия внутри поля |
|
|
217
220
|
| value | `string` | - | Значение input |
|
|
218
221
|
| onChange | `(value: string, e?: ChangeEvent<HTMLInputElement>) => void` | - | Колбек смены значения |
|
|
219
222
|
| disabled | `boolean` | - | Является ли поле деактивированным |
|
|
@@ -365,6 +368,8 @@ FieldStepper в основном предназначен для работы с
|
|
|
365
368
|
| validationState | enum ValidationState: `"default"`, `"error"`, `"warning"`, `"success"` | - | Состояние валидации |
|
|
366
369
|
| showHintIcon | `boolean` | - | Отображать иконку подсказки |
|
|
367
370
|
| loading | `boolean` | - | |
|
|
371
|
+
| prefix | `ReactNode` | - | Произвольный префикс для поля |
|
|
372
|
+
| postfix | `ReactNode` | - | Произвольный постфикс для поля |
|
|
368
373
|
| value | `ItemId \| ItemId[]` | - | Controlled состояние |
|
|
369
374
|
| onChange | `OnChangeHandler<any>` | - | Controlled обработчик измения состояния |
|
|
370
375
|
| defaultValue | `ItemId \| ItemId[]` | - | Начальное состояние |
|
|
@@ -402,6 +407,8 @@ FieldStepper в основном предназначен для работы с
|
|
|
402
407
|
| onChange | `(value: number, e?: ChangeEvent<HTMLInputElement>) => void` | - | Колбек смены значения |
|
|
403
408
|
| step | `number` | 1 | Шаг поля |
|
|
404
409
|
| allowMoreThanLimits | `boolean` | true | Можно ли вводить c клавиатуры числа, выходящие за пределы min/max |
|
|
410
|
+
| prefix | `ReactNode` | - | Произвольный префикс для поля |
|
|
411
|
+
| postfix | `ReactNode` | - | Произвольный постфикс для поля |
|
|
405
412
|
| disabled | `boolean` | - | Является ли поле деактивированным |
|
|
406
413
|
| readonly | `boolean` | - | Является ли поле доступным только для чтения |
|
|
407
414
|
| id | `string` | - | Значение html-атрибута id |
|
|
@@ -431,6 +438,8 @@ FieldStepper в основном предназначен для работы с
|
|
|
431
438
|
| showScaleBar | `boolean` | true | Отображение линейки |
|
|
432
439
|
| textInputFormatter | `TextInputFormatter` | - | Функция для форматирования значений в текстовом поле |
|
|
433
440
|
| unbindInputFromMarks | `boolean` | - | Отвязать текстовое поле от значений на линейке |
|
|
441
|
+
| prefix | `ReactNode` | - | Произвольный префикс для поля |
|
|
442
|
+
| postfix | `ReactNode` | - | Произвольный постфикс для поля |
|
|
434
443
|
| disabled | `boolean` | - | Является ли поле деактивированным |
|
|
435
444
|
| readonly | `boolean` | - | Является ли поле доступным только для чтения |
|
|
436
445
|
| id | `string` | - | Значение html-атрибута id |
|
|
@@ -36,5 +36,5 @@ export declare const FieldColor: import("react").ForwardRefExoticComponent<{
|
|
|
36
36
|
showClearButton?: boolean;
|
|
37
37
|
value?: string;
|
|
38
38
|
onChange?(value: string): void;
|
|
39
|
-
} & Omit<ColorPickerProps, "
|
|
39
|
+
} & Omit<ColorPickerProps, "value" | "onChange"> & InputProps & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
40
40
|
export {};
|
|
@@ -44,9 +44,9 @@ export const FieldColor = forwardRef((_a, ref) => {
|
|
|
44
44
|
};
|
|
45
45
|
const clearButtonSettings = useClearButton({ clearButtonRef, showClearButton, size, onClear });
|
|
46
46
|
const copyButtonSettings = useCopyButton({ copyButtonRef, showCopyButton, size, valueToCopy: value });
|
|
47
|
-
const {
|
|
47
|
+
const { postfixButtons, inputTabIndex, onInputKeyDown } = useButtonNavigation({
|
|
48
48
|
inputRef: localRef,
|
|
49
|
-
|
|
49
|
+
postfixButtons: useMemo(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
|
|
50
50
|
readonly,
|
|
51
51
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
52
52
|
});
|
|
@@ -65,7 +65,7 @@ export const FieldColor = forwardRef((_a, ref) => {
|
|
|
65
65
|
setValue === null || setValue === void 0 ? void 0 : setValue(hex || '');
|
|
66
66
|
}, colorMode: {
|
|
67
67
|
hex: false,
|
|
68
|
-
} }), children: _jsx(FieldContainerPrivate, { className: styles.container, size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, focused: showDropList, inputRef: localRef, postfix:
|
|
68
|
+
} }), children: _jsx(FieldContainerPrivate, { className: styles.container, size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, focused: showDropList, inputRef: localRef, postfix: postfixButtons, prefix: _jsx("div", { className: styles.colorPreview, style: {
|
|
69
69
|
'--color': value,
|
|
70
70
|
} }), children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value, onChange: onChange, onFocus: onFocus, onBlur: onBlur, tabIndex: inputTabIndex, onKeyDown: onInputKeyDown, disabled: disabled, readonly: readonly, placeholder: placeholder, type: 'text', id: id, name: name, "data-test-id": 'field-color__input' }) }) })) })));
|
|
71
71
|
});
|
|
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import mergeRefs from 'merge-refs';
|
|
14
14
|
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
15
15
|
import { useUncontrolledProp } from 'uncontrollable';
|
|
@@ -70,7 +70,13 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
70
70
|
}, [onChange, required, setIsOpen]);
|
|
71
71
|
const clearButtonSettings = useClearButton({ clearButtonRef, showClearButton, size, onClear: handleClear });
|
|
72
72
|
const copyButtonSettings = useCopyButton({ copyButtonRef, showCopyButton, size, valueToCopy: valueProp || '' });
|
|
73
|
-
const
|
|
73
|
+
const calendarIcon = useMemo(() => ({
|
|
74
|
+
active: false,
|
|
75
|
+
show: true,
|
|
76
|
+
id: 'calendarIcon',
|
|
77
|
+
render: props => (_jsx(CalendarSVG, Object.assign({}, props, { size: calendarIconSize, className: styles.calendarIcon, "data-size": size }))),
|
|
78
|
+
}), [calendarIconSize, size]);
|
|
79
|
+
const memorizedButtons = useMemo(() => [clearButtonSettings, copyButtonSettings, calendarIcon], [clearButtonSettings, copyButtonSettings, calendarIcon]);
|
|
74
80
|
const { value, handleChange, handleClick: dateInputClickHandler, handleKeyDown: dateInputKeyDownHandler, handleBlur: dateInputBlurHandler, mask, setInputFocus, } = useDateField({
|
|
75
81
|
inputRef: localRef,
|
|
76
82
|
onChange,
|
|
@@ -79,10 +85,10 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
79
85
|
setIsOpen,
|
|
80
86
|
});
|
|
81
87
|
const setInputFocusFromButtons = useCallback(() => setInputFocus(SlotKey.Year), [setInputFocus]);
|
|
82
|
-
const {
|
|
88
|
+
const { postfixButtons, inputTabIndex, onInputKeyDown: navigationInputKeyDownHandler, setInitialTabIndices, } = useButtonNavigation({
|
|
83
89
|
setInputFocus: setInputFocusFromButtons,
|
|
84
90
|
inputRef: localRef,
|
|
85
|
-
|
|
91
|
+
postfixButtons: memorizedButtons,
|
|
86
92
|
onButtonKeyDown: checkForLeavingFocus,
|
|
87
93
|
readonly,
|
|
88
94
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
@@ -145,5 +151,5 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
145
151
|
element === null || element === void 0 ? void 0 : element.focus();
|
|
146
152
|
setPickerAutofocus(false);
|
|
147
153
|
}
|
|
148
|
-
}, onFocusLeave: handleCalendarFocusLeave, locale: locale, "data-test-id": 'field-date__calendar' }) }), children: _jsx(FieldContainerPrivate, { className: styles.container, size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, focused: showDropList, inputRef: localRef, postfix:
|
|
154
|
+
}, onFocusLeave: handleCalendarFocusLeave, locale: locale, "data-test-id": 'field-date__calendar' }) }), children: _jsx(FieldContainerPrivate, { className: styles.container, size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, focused: showDropList, inputRef: localRef, postfix: postfixButtons, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value || '', placeholder: mask, onChange: handleChange, onFocus: inputHandlers.onFocus, onMouseDown: inputHandlers.onMouseDown, onBlur: onBlur, onKeyDown: handleInputKeyDown, onClick: onClick, disabled: disabled, readonly: readonly, tabIndex: inputTabIndex, type: 'text', id: id, name: name, "data-test-id": 'field-date__input' }) }) })) })));
|
|
149
155
|
});
|
|
@@ -21,5 +21,5 @@ type FieldSecureOwnProps = {
|
|
|
21
21
|
export type FieldSecureProps = WithSupportProps<FieldSecureOwnProps & InputProps & WrapperProps>;
|
|
22
22
|
export declare const FieldSecure: import("react").ForwardRefExoticComponent<{
|
|
23
23
|
'data-test-id'?: string;
|
|
24
|
-
} & import("react").AriaAttributes & FieldSecureOwnProps & Pick<Partial<InputPrivateProps>, "
|
|
24
|
+
} & import("react").AriaAttributes & FieldSecureOwnProps & Pick<Partial<InputPrivateProps>, "value" | "onChange"> & Pick<InputPrivateProps, "onFocus" | "onBlur" | "id" | "disabled" | "readonly" | "name" | "placeholder" | "autoComplete" | "maxLength"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
25
25
|
export {};
|
|
@@ -104,11 +104,11 @@ export const FieldSecure = forwardRef((_a, ref) => {
|
|
|
104
104
|
hidden,
|
|
105
105
|
disabled: disabled || isLoading,
|
|
106
106
|
});
|
|
107
|
-
const {
|
|
107
|
+
const { postfixButtons, inputTabIndex, onInputKeyDown } = useButtonNavigation({
|
|
108
108
|
inputRef: localRef,
|
|
109
|
-
|
|
109
|
+
postfixButtons: useMemo(() => [copyButtonSettings, hideButtonSettings], [copyButtonSettings, hideButtonSettings]),
|
|
110
110
|
readonly,
|
|
111
111
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
112
112
|
});
|
|
113
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState: fieldValidationState }, extractSupportProps(rest), { children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: localRef, prefix: prefixIcon, postfix:
|
|
113
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState: fieldValidationState }, extractSupportProps(rest), { children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: localRef, prefix: prefixIcon, postfix: postfixButtons, children: _jsx(WithSkeleton, { skeleton: _jsx(Skeleton, { width: '100%', borderRadius: 2 }), loading: isLoading, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value, onChange: onChange, onFocus: onFocus, onBlur: onBlur, onKeyDown: onInputKeyDown, tabIndex: inputTabIndex, placeholder: placeholder, disabled: disabled, readonly: readonly, type: hidden ? 'password' : 'text', maxLength: allowMoreThanMaxLength ? undefined : maxLength || undefined, id: id, name: name, "data-test-id": 'field-secure__input', autoComplete: autoComplete }) }) }) })));
|
|
114
114
|
});
|
|
@@ -2,6 +2,8 @@ import { SelectedOptionFormatter } from './types';
|
|
|
2
2
|
export declare const FieldSelectMultiple: import("react").ForwardRefExoticComponent<import("./types").InputProps & import("./types").WrapperProps & {
|
|
3
3
|
options: import("./types").OptionProps[];
|
|
4
4
|
loading?: boolean;
|
|
5
|
+
prefix?: import("react").ReactNode;
|
|
6
|
+
postfix?: import("react").ReactNode;
|
|
5
7
|
} & {
|
|
6
8
|
removeByBackspace?: boolean;
|
|
7
9
|
} & Omit<import("@snack-uikit/list").SelectionMultipleState, "mode"> & Omit<{
|
|
@@ -25,4 +27,4 @@ export declare const FieldSelectMultiple: import("react").ForwardRefExoticCompon
|
|
|
25
27
|
resetSearchOnOptionSelection?: boolean;
|
|
26
28
|
onOpenChange?(open: boolean): void;
|
|
27
29
|
selectedOptionFormatter?: SelectedOptionFormatter;
|
|
28
|
-
} & Pick<import("@snack-uikit/list").DroplistProps, "untouchableScrollbars" | "
|
|
30
|
+
} & Pick<import("@snack-uikit/list").DroplistProps, "untouchableScrollbars" | "dataFiltered" | "dataError" | "noDataState" | "noResultsState" | "errorDataState">, "showCopyButton"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -18,7 +18,7 @@ import { Droplist } from '@snack-uikit/list';
|
|
|
18
18
|
import { Tag } from '@snack-uikit/tag';
|
|
19
19
|
import { extractSupportProps, isBrowser, useLayoutEffect } from '@snack-uikit/utils';
|
|
20
20
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
21
|
-
import { useValueControl } from '../../hooks';
|
|
21
|
+
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';
|
|
@@ -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, removeByBackspace = false, addOptionByEnter = false, untouchableScrollbars = false, open: openProp, enableFuzzySearch = true, resetSearchOnOptionSelection = true, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showClearButton", "onKeyDown", "validationState", "search", "autocomplete", "prefixIcon", "removeByBackspace", "addOptionByEnter", "untouchableScrollbars", "open", "enableFuzzySearch", "resetSearchOnOptionSelection", "onOpenChange", "selectedOptionFormatter"]);
|
|
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 } = 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"]);
|
|
36
36
|
const localRef = useRef(null);
|
|
37
37
|
const inputPlugRef = useRef(null);
|
|
38
38
|
const contentRef = useRef(null);
|
|
@@ -45,6 +45,8 @@ 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 prefixSettings = usePrefix({ prefix, disabled });
|
|
49
|
+
const postfixSettings = usePostfix({ postfix, disabled });
|
|
48
50
|
useLayoutEffect(() => {
|
|
49
51
|
setItems(({ selectedItems }) => updateMultipleItems({ options, value, selectedItems }));
|
|
50
52
|
}, [options, value]);
|
|
@@ -57,7 +59,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
57
59
|
}
|
|
58
60
|
};
|
|
59
61
|
const { ArrowIcon, arrowIconSize } = getArrowIcon({ size, open });
|
|
60
|
-
const {
|
|
62
|
+
const { postfixButtons, inputKeyDownNavigationHandler, buttonsRefs } = useButtons({
|
|
61
63
|
readonly,
|
|
62
64
|
size,
|
|
63
65
|
showClearButton: showClearButton && !disabled && !readonly && Boolean(selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems.find(item => !item.disabled)),
|
|
@@ -135,7 +137,7 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
135
137
|
},
|
|
136
138
|
}, dataFiltered: (_a = rest.dataFiltered) !== null && _a !== void 0 ? _a : Boolean(inputValue.length), untouchableScrollbars: untouchableScrollbars, size: size, open: !disabled && !readonly && open, onOpenChange: handleOpenChange, children: ({ onKeyDown }) => {
|
|
137
139
|
var _a, _b, _c, _d;
|
|
138
|
-
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, children: _jsxs(_Fragment, { children: [_jsxs("div", { className: styles.contentWrapper, ref: contentRef, children: [selectedItems &&
|
|
140
|
+
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 &&
|
|
139
141
|
selectedItems.map(option => {
|
|
140
142
|
var _a;
|
|
141
143
|
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 }, option.id));
|
|
@@ -145,6 +147,6 @@ export const FieldSelectMultiple = forwardRef((props, ref) => {
|
|
|
145
147
|
: '100%',
|
|
146
148
|
}, children: _jsx(InputPrivate, { id: id, name: name, type: 'text', disabled: disabled, placeholder: !selectedItems || !selectedItems.length ? placeholder : undefined, ref: mergeRefs(ref, localRef), onChange: searchable ? setInputValue : undefined, value: searchable ? inputValue : '', readonly: !searchable || readonly, "data-test-id": 'field-select__input', onKeyDown: handleOnKeyDown(onKeyDown), onBlur: handleBlur, className: cn({
|
|
147
149
|
[styles.readonlyCursor]: !searchable,
|
|
148
|
-
}) }) })] }), _jsxs("div", { className: styles.postfix, children: [
|
|
150
|
+
}) }) })] }), _jsxs("div", { className: styles.postfix, children: [postfixButtons, postfixSettings.show && postfixSettings.render({ key: postfixSettings.id }), _jsx(ArrowIcon, { size: arrowIconSize, className: styles.arrowIcon })] }), _jsx("span", { ref: inputPlugRef, className: styles.inputPlug, children: inputValue })] }) }));
|
|
149
151
|
} })) })));
|
|
150
152
|
});
|
|
@@ -2,6 +2,8 @@ import { SelectedOptionFormatter } from './types';
|
|
|
2
2
|
export declare const FieldSelectSingle: import("react").ForwardRefExoticComponent<import("./types").InputProps & import("./types").WrapperProps & {
|
|
3
3
|
options: import("./types").OptionProps[];
|
|
4
4
|
loading?: boolean;
|
|
5
|
+
prefix?: import("react").ReactNode;
|
|
6
|
+
postfix?: import("react").ReactNode;
|
|
5
7
|
} & Omit<import("@snack-uikit/list").SelectionSingleState, "mode"> & Omit<{
|
|
6
8
|
'data-test-id'?: string;
|
|
7
9
|
} & import("react").AriaAttributes & {
|
|
@@ -23,4 +25,4 @@ export declare const FieldSelectSingle: import("react").ForwardRefExoticComponen
|
|
|
23
25
|
resetSearchOnOptionSelection?: boolean;
|
|
24
26
|
onOpenChange?(open: boolean): void;
|
|
25
27
|
selectedOptionFormatter?: SelectedOptionFormatter;
|
|
26
|
-
} & Pick<import("@snack-uikit/list").DroplistProps, "untouchableScrollbars" | "
|
|
28
|
+
} & Pick<import("@snack-uikit/list").DroplistProps, "untouchableScrollbars" | "dataFiltered" | "dataError" | "noDataState" | "noResultsState" | "errorDataState">, "resetSearchOnOptionSelection"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
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
15
|
import { forwardRef, useCallback, useEffect, useRef, useState, } from 'react';
|
|
@@ -17,7 +17,7 @@ import { InputPrivate } from '@snack-uikit/input-private';
|
|
|
17
17
|
import { Droplist } from '@snack-uikit/list';
|
|
18
18
|
import { extractSupportProps, isBrowser, useLayoutEffect } from '@snack-uikit/utils';
|
|
19
19
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
20
|
-
import { useValueControl } from '../../hooks';
|
|
20
|
+
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';
|
|
@@ -29,7 +29,7 @@ const defaultSelectedOptionFormatter = item =>
|
|
|
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, addOptionByEnter = false, untouchableScrollbars = false, open: openProp, onOpenChange, selectedOptionFormatter = defaultSelectedOptionFormatter, enableFuzzySearch = true } = props, rest = __rest(props, ["id", "name", "placeholder", "size", "options", "value", "defaultValue", "onChange", "disabled", "readonly", "searchable", "showCopyButton", "showClearButton", "onKeyDown", "required", "validationState", "search", "autocomplete", "prefixIcon", "addOptionByEnter", "untouchableScrollbars", "open", "onOpenChange", "selectedOptionFormatter", "enableFuzzySearch"]);
|
|
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 } = 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"]);
|
|
33
33
|
const localRef = useRef(null);
|
|
34
34
|
const [open = false, setOpen] = useValueControl({ value: openProp, onChange: onOpenChange });
|
|
35
35
|
const [value, setValue] = useValueControl({
|
|
@@ -40,6 +40,8 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
|
|
|
40
40
|
const [{ selectedItem, items = [] }, setItems] = useState(() => updateItems({ options, value, currentItems: [], selectedItem: undefined }));
|
|
41
41
|
const { inputValue, setInputValue, prevInputValue, updateInputValue } = useSearchInput(Object.assign(Object.assign({}, search), { defaultValue: selectedOptionFormatter(selectedItem), selectedOptionFormatter }));
|
|
42
42
|
const prevSelectedItem = useRef(selectedItem);
|
|
43
|
+
const prefixSettings = usePrefix({ prefix, disabled });
|
|
44
|
+
const postfixSettings = usePostfix({ postfix, disabled });
|
|
43
45
|
useLayoutEffect(() => {
|
|
44
46
|
setItems(({ selectedItem }) => updateItems({ options, value, selectedItem }));
|
|
45
47
|
}, [options, value]);
|
|
@@ -64,7 +66,7 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
|
|
|
64
66
|
}
|
|
65
67
|
}, [required, setOpen, setValue]);
|
|
66
68
|
const { ArrowIcon, arrowIconSize } = getArrowIcon({ size, open });
|
|
67
|
-
const {
|
|
69
|
+
const { postfixButtons, inputKeyDownNavigationHandler, buttonsRefs } = useButtons({
|
|
68
70
|
readonly,
|
|
69
71
|
size,
|
|
70
72
|
showClearButton: showClearButton && !disabled && !readonly && value !== undefined,
|
|
@@ -126,7 +128,7 @@ export const FieldSelectSingle = forwardRef((props, ref) => {
|
|
|
126
128
|
mode: 'single',
|
|
127
129
|
value: value,
|
|
128
130
|
onChange: handleSelectionChange,
|
|
129
|
-
}, size: size, open: open, onOpenChange: handleOpenChange, trigger: 'click', triggerElemRef: localRef, untouchableScrollbars: untouchableScrollbars, children: ({ onKeyDown }) => (_jsxs(FieldContainerPrivate, { className: styles.container, validationState: fieldValidationState, disabled: disabled, readonly: readonly, focused: open, variant: 'single-line-container', inputRef: localRef, size: size, prefix: prefixIcon, children: [_jsx(InputPrivate, { id: id, name: name, type: 'text', disabled: disabled, placeholder: placeholder, ref: mergeRefs(ref, localRef), onChange: searchable ? setInputValue : undefined, value: searchable ? inputValue : selectedOptionFormatter(selectedItem), readonly: readonly, "data-test-id": 'field-select__input', onKeyDown: handleOnKeyDown(onKeyDown), onBlur: handleBlur, className: cn({
|
|
131
|
+
}, size: size, open: open, onOpenChange: handleOpenChange, trigger: 'click', triggerElemRef: localRef, untouchableScrollbars: untouchableScrollbars, children: ({ onKeyDown }) => (_jsxs(FieldContainerPrivate, { className: styles.container, 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: [_jsx(InputPrivate, { id: id, name: name, type: 'text', disabled: disabled, placeholder: placeholder, ref: mergeRefs(ref, localRef), onChange: searchable ? setInputValue : undefined, value: searchable ? inputValue : selectedOptionFormatter(selectedItem), readonly: readonly, "data-test-id": 'field-select__input', onKeyDown: handleOnKeyDown(onKeyDown), onBlur: handleBlur, className: cn({
|
|
130
132
|
[styles.readonlyCursor]: !searchable,
|
|
131
|
-
}) }), _jsxs("div", { className: styles.postfix, children: [
|
|
133
|
+
}) }), _jsxs("div", { className: styles.postfix, children: [postfixButtons, postfixSettings.show && postfixSettings.render({ key: postfixSettings.id }), _jsx(ArrowIcon, { size: arrowIconSize, className: styles.arrowIcon })] })] })) })) })));
|
|
132
134
|
});
|
|
@@ -18,7 +18,7 @@ type UseButtonsProps = {
|
|
|
18
18
|
valueToCopy?: string;
|
|
19
19
|
};
|
|
20
20
|
export declare function useButtons({ readonly, showClearButton, showCopyButton, size, onClear, inputRef, valueToCopy, }: UseButtonsProps): {
|
|
21
|
-
|
|
21
|
+
postfixButtons: import("react/jsx-runtime").JSX.Element | undefined;
|
|
22
22
|
inputKeyDownNavigationHandler: KeyboardEventHandler<HTMLInputElement>;
|
|
23
23
|
buttonsRefs: (Element | null)[];
|
|
24
24
|
};
|
|
@@ -42,14 +42,14 @@ export function useButtons({ readonly, showClearButton, showCopyButton, size, on
|
|
|
42
42
|
size,
|
|
43
43
|
valueToCopy,
|
|
44
44
|
});
|
|
45
|
-
const { onInputKeyDown: inputKeyDownNavigationHandler,
|
|
45
|
+
const { onInputKeyDown: inputKeyDownNavigationHandler, postfixButtons } = useButtonNavigation({
|
|
46
46
|
inputRef,
|
|
47
|
-
|
|
47
|
+
postfixButtons: useMemo(() => [clearButtonSettings, copyButtonSettings], [clearButtonSettings, copyButtonSettings]),
|
|
48
48
|
onButtonKeyDown: undefined,
|
|
49
49
|
readonly,
|
|
50
50
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
51
51
|
});
|
|
52
|
-
return {
|
|
52
|
+
return { postfixButtons, inputKeyDownNavigationHandler, buttonsRefs };
|
|
53
53
|
}
|
|
54
54
|
export function useSearchInput({ value, onChange, defaultValue, selectedOptionFormatter, resetSearchOnOptionSelection = true, }) {
|
|
55
55
|
const [inputValue = '', setInputValue] = useValueControl({ value, onChange, defaultValue });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { InputPrivateProps } from '@snack-uikit/input-private';
|
|
3
3
|
import { AccordionItemProps, BaseItemProps, DroplistProps, GroupItemProps, ItemContentProps, NextListItemProps, SelectionMultipleState, SelectionSingleState } from '@snack-uikit/list';
|
|
4
4
|
import { TagProps } from '@snack-uikit/tag';
|
|
@@ -34,6 +34,10 @@ export type SearchState = {
|
|
|
34
34
|
export type FieldSelectPrivateProps = InputProps & WrapperProps & {
|
|
35
35
|
options: OptionProps[];
|
|
36
36
|
loading?: boolean;
|
|
37
|
+
/** Произвольный префикс для поля */
|
|
38
|
+
prefix?: ReactNode;
|
|
39
|
+
/** Произвольный постфикс для поля */
|
|
40
|
+
postfix?: ReactNode;
|
|
37
41
|
};
|
|
38
42
|
type FiledSelectCommonProps = WithSupportProps<{
|
|
39
43
|
options: OptionProps[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { InputPrivateProps } from '@snack-uikit/input-private';
|
|
3
3
|
import { SliderProps as SliderComponentProps } from '@snack-uikit/slider';
|
|
4
4
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
@@ -15,9 +15,13 @@ type FieldSliderOwnProps = {
|
|
|
15
15
|
textInputFormatter?: TextInputFormatter;
|
|
16
16
|
/** Отвязать текстовое поле от значений на линейке */
|
|
17
17
|
unbindInputFromMarks?: boolean;
|
|
18
|
+
/** Произвольный префикс для поля */
|
|
19
|
+
prefix?: ReactNode;
|
|
20
|
+
/** Произвольный постфикс для поля */
|
|
21
|
+
postfix?: ReactNode;
|
|
18
22
|
};
|
|
19
23
|
export type FieldSliderProps = WithSupportProps<FieldSliderOwnProps & SliderProps & WrapperProps>;
|
|
20
24
|
export declare const FieldSlider: import("react").ForwardRefExoticComponent<{
|
|
21
25
|
'data-test-id'?: string;
|
|
22
|
-
} & import("react").AriaAttributes & FieldSliderOwnProps & Pick<InputPrivateProps, "
|
|
26
|
+
} & import("react").AriaAttributes & FieldSliderOwnProps & Pick<InputPrivateProps, "onFocus" | "onBlur" | "id" | "disabled" | "readonly" | "name"> & Pick<SliderComponentProps, "value" | "onChange" | "range" | "tipFormatter"> & Required<Pick<SliderComponentProps, "max" | "min" | "step" | "marks">> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
23
27
|
export {};
|
|
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import mergeRefs from 'merge-refs';
|
|
14
14
|
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
15
15
|
import { InputPrivate, SIZE } from '@snack-uikit/input-private';
|
|
@@ -17,7 +17,7 @@ import { Slider } from '@snack-uikit/slider';
|
|
|
17
17
|
import { extractSupportProps, useEventHandler } from '@snack-uikit/utils';
|
|
18
18
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
19
19
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
20
|
-
import { useValueControl } from '../../hooks';
|
|
20
|
+
import { usePostfix, usePrefix, useValueControl } from '../../hooks';
|
|
21
21
|
import { FieldDecorator } from '../FieldDecorator';
|
|
22
22
|
import { generateAllowedValues, getClosestMark, getTextFieldValue, isMarkObject } from './helpers';
|
|
23
23
|
import styles from './styles.module.css';
|
|
@@ -31,7 +31,16 @@ const getDefaultValue = (range, min, max, value) => {
|
|
|
31
31
|
return value !== null && value !== void 0 ? value : min;
|
|
32
32
|
};
|
|
33
33
|
export const FieldSlider = forwardRef((_a, ref) => {
|
|
34
|
-
var { id, name, min, max, step, marks, showScaleBar = true, value: valueProp, range = false, disabled = false, readonly = false, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required, caption, hint, showHintIcon, size = SIZE.S, postfixIcon,
|
|
34
|
+
var { id, name, min, max, step, marks, showScaleBar = true, value: valueProp, range = false, disabled = false, readonly = false, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required, caption, hint, showHintIcon, size = SIZE.S, textInputFormatter, unbindInputFromMarks, postfixIcon, prefix, postfix } = _a, rest = __rest(_a, ["id", "name", "min", "max", "step", "marks", "showScaleBar", "value", "range", "disabled", "readonly", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "textInputFormatter", "unbindInputFromMarks", "postfixIcon", "prefix", "postfix"]);
|
|
35
|
+
const [value = getDefaultValue(range, min, max, valueProp), onChange] = useValueControl({
|
|
36
|
+
value: valueProp,
|
|
37
|
+
defaultValue: getDefaultValue(range, min, max, valueProp),
|
|
38
|
+
onChange: onChangeProp,
|
|
39
|
+
});
|
|
40
|
+
const [textFieldInputValue, setTextFieldInputValue] = useState(getTextFieldValue(value, textInputFormatter));
|
|
41
|
+
const localRef = useRef(null);
|
|
42
|
+
const prefixSettings = usePrefix({ prefix, disabled });
|
|
43
|
+
const postfixSettings = usePostfix({ postfix, disabled });
|
|
35
44
|
const getMarkValue = useCallback((key) => {
|
|
36
45
|
const mark = marks[key];
|
|
37
46
|
if (isMarkObject(mark)) {
|
|
@@ -40,13 +49,6 @@ export const FieldSlider = forwardRef((_a, ref) => {
|
|
|
40
49
|
return mark;
|
|
41
50
|
}, [marks]);
|
|
42
51
|
const hasMarksEqualToValues = useMemo(() => Object.keys(marks).every(key => key === getMarkValue(key)), [getMarkValue, marks]);
|
|
43
|
-
const [value = getDefaultValue(range, min, max, valueProp), onChange] = useValueControl({
|
|
44
|
-
value: valueProp,
|
|
45
|
-
defaultValue: getDefaultValue(range, min, max, valueProp),
|
|
46
|
-
onChange: onChangeProp,
|
|
47
|
-
});
|
|
48
|
-
const [textFieldInputValue, setTextFieldInputValue] = useState(getTextFieldValue(value, textInputFormatter));
|
|
49
|
-
const localRef = useRef(null);
|
|
50
52
|
const onTextFieldChange = (textFieldValue) => {
|
|
51
53
|
const numValue = parseInt(textFieldValue);
|
|
52
54
|
if (textFieldValue && Number.isNaN(numValue)) {
|
|
@@ -146,5 +148,5 @@ export const FieldSlider = forwardRef((_a, ref) => {
|
|
|
146
148
|
useEffect(() => {
|
|
147
149
|
handleTextValueChange();
|
|
148
150
|
}, [marks, min, max, handleTextValueChange]);
|
|
149
|
-
return (_jsxs(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, disabled: disabled, required: required, caption: caption, hint: hint, showHintIcon: showHintIcon, readonly: readonly, size: size }, extractSupportProps(rest), { children: [_jsx(FieldContainerPrivate, { className: styles.fieldContainer, size: size, validationState: VALIDATION_STATE.Default, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: localRef, postfix: postfixIcon, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: textFieldInputValue, onChange: range ? undefined : onTextFieldChange, onFocus: onFocus, onBlur: range ? onBlur : onTextFieldBlur, onKeyDown: handleTextFieldKeyChange, disabled: disabled, readonly: range ? true : readonly, type: 'text', id: id, name: name, "data-test-id": 'field-slider__input' }) }), _jsx("div", { className: styles.sliderWrapper, children: _jsx("div", { className: styles.slider, "data-size": size, children: _jsx(Slider, { range: range, min: min, max: max, step: step, value: value, onChange: onChange, marks: showScaleBar ? marks : undefined, disabled: readonly || disabled, "data-test-id": 'field-slider__slider' }) }) })] })));
|
|
151
|
+
return (_jsxs(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, disabled: disabled, required: required, caption: caption, hint: hint, showHintIcon: showHintIcon, readonly: readonly, size: size }, extractSupportProps(rest), { children: [_jsx(FieldContainerPrivate, { className: styles.fieldContainer, size: size, validationState: VALIDATION_STATE.Default, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: localRef, prefix: prefixSettings.show && prefixSettings.render({ key: prefixSettings.id }), postfix: _jsxs(_Fragment, { children: [postfixSettings.show && postfixSettings.render({ key: postfixSettings.id }), postfixIcon] }), children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: textFieldInputValue, onChange: range ? undefined : onTextFieldChange, onFocus: onFocus, onBlur: range ? onBlur : onTextFieldBlur, onKeyDown: handleTextFieldKeyChange, disabled: disabled, readonly: range ? true : readonly, type: 'text', id: id, name: name, "data-test-id": 'field-slider__input' }) }), _jsx("div", { className: styles.sliderWrapper, children: _jsx("div", { className: styles.slider, "data-size": size, children: _jsx(Slider, { range: range, min: min, max: max, step: step, value: value, onChange: onChange, marks: showScaleBar ? marks : undefined, disabled: readonly || disabled, "data-test-id": 'field-slider__slider' }) }) })] })));
|
|
150
152
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeEvent } from 'react';
|
|
1
|
+
import { ChangeEvent, ReactNode } from 'react';
|
|
2
2
|
import { InputPrivateProps } from '@snack-uikit/input-private';
|
|
3
3
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
4
|
import { FieldDecoratorProps } from '../FieldDecorator';
|
|
@@ -13,6 +13,10 @@ type FieldStepperOwnProps = {
|
|
|
13
13
|
step?: number;
|
|
14
14
|
/** Можно ли вводить c клавиатуры числа, выходящие за пределы min/max */
|
|
15
15
|
allowMoreThanLimits?: boolean;
|
|
16
|
+
/** Произвольный префикс для поля */
|
|
17
|
+
prefix?: ReactNode;
|
|
18
|
+
/** Произвольный постфикс для поля */
|
|
19
|
+
postfix?: ReactNode;
|
|
16
20
|
};
|
|
17
21
|
export type FieldStepperProps = WithSupportProps<FieldStepperOwnProps & InputProps & WrapperProps>;
|
|
18
22
|
export declare const FieldStepper: import("react").ForwardRefExoticComponent<{
|
|
@@ -9,7 +9,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import mergeRefs from 'merge-refs';
|
|
14
14
|
import { forwardRef, useEffect, useRef, useState, } from 'react';
|
|
15
15
|
import { ButtonFunction } from '@snack-uikit/button';
|
|
@@ -20,7 +20,7 @@ import { Tooltip } from '@snack-uikit/tooltip';
|
|
|
20
20
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
21
21
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
22
22
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
23
|
-
import { useValueControl } from '../../hooks';
|
|
23
|
+
import { usePostfix, usePrefix, useValueControl } from '../../hooks';
|
|
24
24
|
import { getValidationState } from '../../utils/getValidationState';
|
|
25
25
|
import { FieldDecorator } from '../FieldDecorator';
|
|
26
26
|
import styles from './styles.module.css';
|
|
@@ -35,7 +35,7 @@ const getDefaultValue = (min, max) => {
|
|
|
35
35
|
return 0;
|
|
36
36
|
};
|
|
37
37
|
export const FieldStepper = forwardRef((_a, ref) => {
|
|
38
|
-
var { id, name, value: valueProp, min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY, step = 1, disabled = false, readonly = false, allowMoreThanLimits = true, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required = false, caption, hint, showHintIcon, size = SIZE.S, validationState = VALIDATION_STATE.Default, error } = _a, rest = __rest(_a, ["id", "name", "value", "min", "max", "step", "disabled", "readonly", "allowMoreThanLimits", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error"]);
|
|
38
|
+
var { id, name, value: valueProp, min = Number.NEGATIVE_INFINITY, max = Number.POSITIVE_INFINITY, step = 1, disabled = false, readonly = false, allowMoreThanLimits = true, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required = false, caption, hint, showHintIcon, size = SIZE.S, validationState = VALIDATION_STATE.Default, error, prefix, postfix } = _a, rest = __rest(_a, ["id", "name", "value", "min", "max", "step", "disabled", "readonly", "allowMoreThanLimits", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "caption", "hint", "showHintIcon", "size", "validationState", "error", "prefix", "postfix"]);
|
|
39
39
|
const { t } = useLocale('Fields');
|
|
40
40
|
const [value = 0, setValue] = useValueControl({
|
|
41
41
|
value: valueProp,
|
|
@@ -50,6 +50,8 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
50
50
|
const plusButtonRef = useRef(null);
|
|
51
51
|
const isMinusButtonDisabled = (typeof min === 'number' && value <= min) || readonly || disabled;
|
|
52
52
|
const isPlusButtonDisabled = (typeof max === 'number' && value >= max) || readonly || disabled;
|
|
53
|
+
const prefixSettings = usePrefix({ prefix, disabled });
|
|
54
|
+
const postfixSettings = usePostfix({ postfix, disabled });
|
|
53
55
|
const fieldValidationState = getValidationState({ validationState, error });
|
|
54
56
|
const adjustValue = (value) => {
|
|
55
57
|
setValue(value);
|
|
@@ -124,5 +126,5 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
124
126
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
125
127
|
}
|
|
126
128
|
};
|
|
127
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState: fieldValidationState, error: error }, extractSupportProps(rest), { children: _jsx(Tooltip, { tip: tooltip, open: allowMoreThanLimits ? false : tooltipOpen, "data-test-id": 'field-stepper__limit-tooltip', children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: inputRef, prefix: _jsx(ButtonFunction, { tabIndex: -1, ref: minusButtonRef, size: 'xs', className: styles.button, icon: _jsx(MinusSVG, {}), onClick: handleMinusButtonClick, onKeyDown: handleMinusButtonKeyDown, disabled: isMinusButtonDisabled, "data-test-id": 'field-stepper__minus-button' }), postfix: _jsx(ButtonFunction, { ref: plusButtonRef, tabIndex: -1, size: 'xs', className: styles.button, icon: _jsx(PlusSVG, {}), onClick: handlePlusButtonClick, onKeyDown: handlePlusButtonKeyDown, disabled: isPlusButtonDisabled, "data-test-id": 'field-stepper__plus-button' }), children: _jsx(InputPrivate, { ref: mergeRefs(ref, inputRef), className: styles.stepper, "data-size": size, value: String(value), tabIndex: 0, onKeyDown: handleInputKeyDown, onChange: handleInputChange, onBlur: handleInputBlur, onFocus: handleInputFocus, disabled: disabled, readonly: readonly, type: 'number', id: id, name: name, min: min, max: max, "data-test-id": 'field-stepper__input' }) }) }) })));
|
|
129
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, caption: caption, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState: fieldValidationState, error: error }, extractSupportProps(rest), { children: _jsx(Tooltip, { tip: tooltip, open: allowMoreThanLimits ? false : tooltipOpen, "data-test-id": 'field-stepper__limit-tooltip', children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: inputRef, prefix: _jsxs(_Fragment, { children: [_jsx(ButtonFunction, { tabIndex: -1, ref: minusButtonRef, size: 'xs', className: styles.button, icon: _jsx(MinusSVG, {}), onClick: handleMinusButtonClick, onKeyDown: handleMinusButtonKeyDown, disabled: isMinusButtonDisabled, "data-test-id": 'field-stepper__minus-button' }), prefixSettings.show && prefixSettings.render({ key: prefixSettings.id })] }), postfix: _jsxs(_Fragment, { children: [postfixSettings.show && postfixSettings.render({ key: postfixSettings.id }), _jsx(ButtonFunction, { ref: plusButtonRef, tabIndex: -1, size: 'xs', className: styles.button, icon: _jsx(PlusSVG, {}), onClick: handlePlusButtonClick, onKeyDown: handlePlusButtonKeyDown, disabled: isPlusButtonDisabled, "data-test-id": 'field-stepper__plus-button' })] }), children: _jsx(InputPrivate, { ref: mergeRefs(ref, inputRef), className: styles.stepper, "data-size": size, value: String(value), tabIndex: 0, onKeyDown: handleInputKeyDown, onChange: handleInputChange, onBlur: handleInputBlur, onFocus: handleInputFocus, disabled: disabled, readonly: readonly, type: 'number', id: id, name: name, min: min, max: max, "data-test-id": 'field-stepper__input' }) }) }) })));
|
|
128
130
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { InputPrivateProps } from '@snack-uikit/input-private';
|
|
3
3
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
|
+
import { Button } from '../../types';
|
|
4
5
|
import { FieldDecoratorProps } from '../FieldDecorator';
|
|
5
6
|
type InputProps = Pick<Partial<InputPrivateProps>, 'value' | 'onChange'> & Pick<InputPrivateProps, 'id' | 'name' | 'placeholder' | 'maxLength' | 'disabled' | 'readonly' | 'onFocus' | 'onBlur' | 'autoComplete'>;
|
|
6
7
|
type WrapperProps = Pick<FieldDecoratorProps, 'className' | 'label' | 'labelTooltip' | 'required' | 'caption' | 'hint' | 'showHintIcon' | 'size' | 'validationState' | 'labelTooltipPlacement' | 'error'>;
|
|
@@ -16,9 +17,15 @@ type FieldTextOwnProps = {
|
|
|
16
17
|
allowMoreThanMaxLength?: boolean;
|
|
17
18
|
/** Иконка-префикс для поля */
|
|
18
19
|
prefixIcon?: ReactElement;
|
|
20
|
+
/** Произвольный префикс для поля */
|
|
21
|
+
prefix?: ReactNode;
|
|
22
|
+
/** Произвольный постфикс для поля */
|
|
23
|
+
postfix?: ReactNode;
|
|
24
|
+
/** Кнопка действия внутри поля */
|
|
25
|
+
button?: Button;
|
|
19
26
|
};
|
|
20
27
|
export type FieldTextProps = WithSupportProps<FieldTextOwnProps & InputProps & WrapperProps>;
|
|
21
28
|
export declare const FieldText: import("react").ForwardRefExoticComponent<{
|
|
22
29
|
'data-test-id'?: string;
|
|
23
|
-
} & import("react").AriaAttributes & FieldTextOwnProps & Pick<Partial<InputPrivateProps>, "
|
|
30
|
+
} & import("react").AriaAttributes & FieldTextOwnProps & Pick<Partial<InputPrivateProps>, "value" | "onChange"> & Pick<InputPrivateProps, "onFocus" | "onBlur" | "id" | "disabled" | "readonly" | "name" | "placeholder" | "autoComplete" | "maxLength"> & WrapperProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
24
31
|
export {};
|