@snack-uikit/fields 0.19.0 → 0.19.2
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 +24 -0
- package/README.md +406 -31
- package/dist/components/FieldDate/FieldDate.js +4 -2
- package/dist/components/FieldDecorator/FieldDecorator.d.ts +1 -1
- package/dist/components/FieldDecorator/FieldDecorator.js +4 -3
- package/dist/components/FieldSecure/FieldSecure.js +3 -1
- package/dist/components/FieldSelect/FieldSelectMultiple.d.ts +2 -2
- package/dist/components/FieldSelect/FieldSelectMultiple.js +4 -2
- package/dist/components/FieldSelect/FieldSelectSingle.d.ts +2 -2
- package/dist/components/FieldSelect/FieldSelectSingle.js +4 -2
- package/dist/components/FieldSelect/types.d.ts +2 -2
- package/dist/components/FieldSlider/FieldSlider.js +63 -19
- package/dist/components/FieldSlider/helpers/getClosestMark.d.ts +2 -2
- package/dist/components/FieldSlider/helpers/getClosestMark.js +3 -3
- package/dist/components/FieldSlider/helpers/index.d.ts +1 -0
- package/dist/components/FieldSlider/helpers/index.js +1 -0
- package/dist/components/FieldSlider/helpers/isMarkObject.d.ts +8 -0
- package/dist/components/FieldSlider/helpers/isMarkObject.js +3 -0
- package/dist/components/FieldStepper/FieldStepper.js +3 -1
- package/dist/components/FieldText/FieldText.js +3 -1
- package/dist/components/FieldTextArea/FieldTextArea.js +3 -1
- package/dist/utils/getValidationState.d.ts +5 -0
- package/dist/utils/getValidationState.js +4 -0
- package/package.json +5 -5
- package/src/components/FieldDate/FieldDate.tsx +4 -2
- package/src/components/FieldDecorator/FieldDecorator.tsx +4 -3
- package/src/components/FieldSecure/FieldSecure.tsx +5 -2
- package/src/components/FieldSelect/FieldSelectMultiple.tsx +5 -2
- package/src/components/FieldSelect/FieldSelectSingle.tsx +5 -2
- package/src/components/FieldSelect/types.ts +2 -2
- package/src/components/FieldSlider/FieldSlider.tsx +93 -19
- package/src/components/FieldSlider/helpers/getClosestMark.ts +7 -3
- package/src/components/FieldSlider/helpers/index.ts +1 -0
- package/src/components/FieldSlider/helpers/isMarkObject.ts +13 -0
- package/src/components/FieldStepper/FieldStepper.tsx +5 -2
- package/src/components/FieldText/FieldText.tsx +4 -2
- package/src/components/FieldTextArea/FieldTextArea.tsx +5 -2
- package/src/utils/getValidationState.ts +6 -0
|
@@ -21,6 +21,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
21
21
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
22
22
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
23
23
|
import { useCopyButton } from '../../hooks';
|
|
24
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
24
25
|
import { FieldDecorator } from '../FieldDecorator';
|
|
25
26
|
import { DEFAULT_LOCALE, SlotKey } from './constants';
|
|
26
27
|
import { useDateField } from './hooks';
|
|
@@ -45,6 +46,7 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
45
46
|
const showAdditionalButton = Boolean(valueProp && !disabled);
|
|
46
47
|
const showClearButton = showClearButtonProp && showAdditionalButton && !readonly;
|
|
47
48
|
const showCopyButton = showCopyButtonProp && showAdditionalButton && readonly;
|
|
49
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
48
50
|
const checkForLeavingFocus = useCallback((event) => {
|
|
49
51
|
if (event.key === 'ArrowDown') {
|
|
50
52
|
setPickerAutofocus(true);
|
|
@@ -133,7 +135,7 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
133
135
|
e.stopPropagation();
|
|
134
136
|
}
|
|
135
137
|
}, [dateInputClickHandler, isOpen]);
|
|
136
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState:
|
|
138
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState: fieldValidationState }, extractSupportProps(rest), { children: _jsx(Dropdown, Object.assign({ trigger: 'click', triggerClassName: styles.triggerClassName, widthStrategy: 'gte' }, (readonly || disabled
|
|
137
139
|
? { open: false }
|
|
138
140
|
: {
|
|
139
141
|
open: showDropList,
|
|
@@ -143,5 +145,5 @@ export const FieldDate = forwardRef((_a, ref) => {
|
|
|
143
145
|
element === null || element === void 0 ? void 0 : element.focus();
|
|
144
146
|
setPickerAutofocus(false);
|
|
145
147
|
}
|
|
146
|
-
}, onFocusLeave: handleCalendarFocusLeave, locale: locale, "data-test-id": 'field-date__calendar' }) }), children: _jsx(FieldContainerPrivate, { className: styles.container, size: size, validationState:
|
|
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: _jsxs(_Fragment, { children: [buttons, _jsx(CalendarSVG, { size: calendarIconSize, className: styles.calendarIcon, "data-size": size })] }), 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' }) }) })) })));
|
|
147
149
|
});
|
|
@@ -12,4 +12,4 @@ export type FieldDecoratorProps = WithSupportProps<{
|
|
|
12
12
|
readonly?: boolean;
|
|
13
13
|
error?: string;
|
|
14
14
|
} & HeaderProps & FooterProps>;
|
|
15
|
-
export declare function FieldDecorator({ children, className, label, labelTooltip, required, labelFor, length, hint, disabled, readonly, showHintIcon, labelTooltipPlacement, size, error, validationState
|
|
15
|
+
export declare function FieldDecorator({ children, className, label, labelTooltip, required, labelFor, length, hint, disabled, readonly, showHintIcon, labelTooltipPlacement, size, error, validationState, ...rest }: FieldDecoratorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,12 +14,13 @@ import cn from 'classnames';
|
|
|
14
14
|
import { SIZE } from '@snack-uikit/input-private';
|
|
15
15
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
16
16
|
import { VALIDATION_STATE } from '../../constants';
|
|
17
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
17
18
|
import { Footer } from './Footer';
|
|
18
19
|
import { Header } from './Header';
|
|
19
20
|
import styles from './styles.module.css';
|
|
20
21
|
export function FieldDecorator(_a) {
|
|
21
|
-
var { children, className, label, labelTooltip, required, labelFor, length, hint, disabled, readonly, showHintIcon, labelTooltipPlacement, size = SIZE.S, error, validationState
|
|
22
|
+
var { children, className, label, labelTooltip, required, labelFor, length, hint, disabled, readonly, showHintIcon, labelTooltipPlacement, size = SIZE.S, error, validationState = VALIDATION_STATE.Default } = _a, rest = __rest(_a, ["children", "className", "label", "labelTooltip", "required", "labelFor", "length", "hint", "disabled", "readonly", "showHintIcon", "labelTooltipPlacement", "size", "error", "validationState"]);
|
|
22
23
|
const isFieldActive = !disabled && !readonly;
|
|
23
|
-
const
|
|
24
|
-
return (_jsxs("div", Object.assign({ className: cn(styles.decorator, className) }, extractSupportProps(rest), { "data-size": size, children: [label && (_jsx(Header, { labelTooltipPlacement: labelTooltipPlacement, required: required, label: label, labelTooltip: labelTooltip, labelFor: labelFor, size: size })), children, _jsx(Footer, { length: isFieldActive ? length : undefined, hint: error || hint, showHintIcon: showHintIcon, size: size, validationState: isFieldActive ?
|
|
24
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
25
|
+
return (_jsxs("div", Object.assign({ className: cn(styles.decorator, className) }, extractSupportProps(rest), { "data-size": size, children: [label && (_jsx(Header, { labelTooltipPlacement: labelTooltipPlacement, required: required, label: label, labelTooltip: labelTooltip, labelFor: labelFor, size: size })), children, _jsx(Footer, { length: isFieldActive ? length : undefined, hint: error || hint, showHintIcon: showHintIcon, size: size, validationState: isFieldActive ? fieldValidationState : VALIDATION_STATE.Default })] })));
|
|
25
26
|
}
|
|
@@ -17,6 +17,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
17
17
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
18
18
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
19
19
|
import { useCopyButton, useHideButton, useValueControl } from '../../hooks';
|
|
20
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
20
21
|
import { FieldDecorator } from '../FieldDecorator';
|
|
21
22
|
export const FieldSecure = forwardRef((_a, ref) => {
|
|
22
23
|
var { id, name, value: valueProp, placeholder, maxLength, disabled = false, readonly = false, showCopyButton: showCopyButtonProp = true, allowMoreThanMaxLength = false, hidden: hiddenProp, onHiddenChange, showHintIcon, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required = false, hint, size = SIZE.S, validationState = VALIDATION_STATE.Default, prefixIcon, error } = _a, rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "allowMoreThanMaxLength", "hidden", "onHiddenChange", "showHintIcon", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "hint", "size", "validationState", "prefixIcon", "error"]);
|
|
@@ -35,6 +36,7 @@ export const FieldSecure = forwardRef((_a, ref) => {
|
|
|
35
36
|
});
|
|
36
37
|
const showCopyButton = showCopyButtonProp && Boolean(value) && readonly && !disabled;
|
|
37
38
|
const showHideButton = !(readonly && !value);
|
|
39
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
38
40
|
const toggleHidden = () => {
|
|
39
41
|
setHidden(!hidden);
|
|
40
42
|
if (!readonly) {
|
|
@@ -53,5 +55,5 @@ export const FieldSecure = forwardRef((_a, ref) => {
|
|
|
53
55
|
readonly,
|
|
54
56
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
55
57
|
});
|
|
56
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState:
|
|
58
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, 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: buttons, 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' }) }) })));
|
|
57
59
|
});
|
|
@@ -9,8 +9,8 @@ export declare const FieldSelectMultiple: import("react").ForwardRefExoticCompon
|
|
|
9
9
|
'data-test-id'?: string | undefined;
|
|
10
10
|
} & import("react").AriaAttributes & {
|
|
11
11
|
options: import("./types").OptionProps[];
|
|
12
|
-
pinTop
|
|
13
|
-
pinBottom
|
|
12
|
+
pinTop?: import("./types").OptionProps[] | undefined;
|
|
13
|
+
pinBottom?: import("./types").OptionProps[] | undefined;
|
|
14
14
|
searchable?: boolean | undefined;
|
|
15
15
|
showCopyButton?: boolean | undefined;
|
|
16
16
|
showClearButton?: boolean | undefined;
|
|
@@ -19,6 +19,7 @@ import { Tag } from '@snack-uikit/tag';
|
|
|
19
19
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
20
20
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
21
21
|
import { useValueControl } from '../../hooks';
|
|
22
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
22
23
|
import { FieldDecorator } from '../FieldDecorator';
|
|
23
24
|
import { extractFieldDecoratorProps } from '../FieldDecorator/utils';
|
|
24
25
|
import { useButtons, useHandleDeleteItem, useHandleOnKeyDown, useSearchInput } from './hooks';
|
|
@@ -115,7 +116,8 @@ export const FieldSelectMultiple = forwardRef((_a, ref) => {
|
|
|
115
116
|
};
|
|
116
117
|
const fuzzySearch = useFuzzySearch(items);
|
|
117
118
|
const result = autocomplete || !searchable || prevInputValue.current === inputValue ? items : fuzzySearch(inputValue);
|
|
118
|
-
|
|
119
|
+
const fieldValidationState = getValidationState({ validationState, error: rest.error });
|
|
120
|
+
return (_jsx(FieldDecorator, Object.assign({}, extractSupportProps(rest), extractFieldDecoratorProps(rest), { labelFor: id, size: size, validationState: fieldValidationState, children: _jsx(Droplist, Object.assign({}, extractListProps(rest), { items: result, triggerElemRef: localRef, selection: {
|
|
119
121
|
mode: 'multiple',
|
|
120
122
|
value: value,
|
|
121
123
|
onChange: value => {
|
|
@@ -124,7 +126,7 @@ export const FieldSelectMultiple = forwardRef((_a, ref) => {
|
|
|
124
126
|
},
|
|
125
127
|
}, dataFiltered: (_b = rest.dataFiltered) !== null && _b !== void 0 ? _b : Boolean(inputValue.length), size: size, open: !disabled && !readonly && open, onOpenChange: handleOpenChange, children: ({ onKeyDown }) => {
|
|
126
128
|
var _a, _b, _c, _d;
|
|
127
|
-
return (_jsx(FieldContainerPrivate, { className: cn(styles.container, styles.tagContainer), validationState:
|
|
129
|
+
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 &&
|
|
128
130
|
selectedItems.map(option => {
|
|
129
131
|
var _a;
|
|
130
132
|
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));
|
|
@@ -7,8 +7,8 @@ export declare const FieldSelectSingle: import("react").ForwardRefExoticComponen
|
|
|
7
7
|
'data-test-id'?: string | undefined;
|
|
8
8
|
} & import("react").AriaAttributes & {
|
|
9
9
|
options: import("./types").OptionProps[];
|
|
10
|
-
pinTop
|
|
11
|
-
pinBottom
|
|
10
|
+
pinTop?: import("./types").OptionProps[] | undefined;
|
|
11
|
+
pinBottom?: import("./types").OptionProps[] | undefined;
|
|
12
12
|
searchable?: boolean | undefined;
|
|
13
13
|
showCopyButton?: boolean | undefined;
|
|
14
14
|
showClearButton?: boolean | undefined;
|
|
@@ -18,6 +18,7 @@ import { Droplist } from '@snack-uikit/list';
|
|
|
18
18
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
19
19
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
20
20
|
import { useValueControl } from '../../hooks';
|
|
21
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
21
22
|
import { FieldDecorator } from '../FieldDecorator';
|
|
22
23
|
import { extractFieldDecoratorProps } from '../FieldDecorator/utils';
|
|
23
24
|
import { useButtons, useHandleOnKeyDown, useSearchInput } from './hooks';
|
|
@@ -122,11 +123,12 @@ export const FieldSelectSingle = forwardRef((_a, ref) => {
|
|
|
122
123
|
const result = autocomplete || !searchable || selectedOptionFormatter(selectedItem) === inputValue
|
|
123
124
|
? items
|
|
124
125
|
: fuzzySearch(inputValue);
|
|
125
|
-
|
|
126
|
+
const fieldValidationState = getValidationState({ validationState, error: rest.error });
|
|
127
|
+
return (_jsx(FieldDecorator, Object.assign({}, extractSupportProps(rest), extractFieldDecoratorProps(rest), { validationState: fieldValidationState, required: required, readonly: readonly, labelFor: id, disabled: disabled, size: size, children: _jsx(Droplist, Object.assign({}, extractListProps(rest), { items: result, selection: {
|
|
126
128
|
mode: 'single',
|
|
127
129
|
value: value,
|
|
128
130
|
onChange: handleSelectionChange,
|
|
129
|
-
}, size: size, open: open, onOpenChange: handleOpenChange, triggerElemRef: localRef, children: ({ onKeyDown }) => (_jsxs(FieldContainerPrivate, { className: styles.container, validationState:
|
|
131
|
+
}, size: size, open: open, onOpenChange: handleOpenChange, triggerElemRef: localRef, 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({
|
|
130
132
|
[styles.readonlyCursor]: !searchable,
|
|
131
133
|
}) }), _jsxs("div", { className: styles.postfix, children: [buttons, _jsx(ArrowIcon, { size: arrowIconSize, className: styles.arrowIcon })] })] })) })) })));
|
|
132
134
|
});
|
|
@@ -37,8 +37,8 @@ export type FieldSelectPrivateProps = InputProps & WrapperProps & {
|
|
|
37
37
|
};
|
|
38
38
|
type FiledSelectCommonProps = WithSupportProps<{
|
|
39
39
|
options: OptionProps[];
|
|
40
|
-
pinTop
|
|
41
|
-
pinBottom
|
|
40
|
+
pinTop?: OptionProps[];
|
|
41
|
+
pinBottom?: OptionProps[];
|
|
42
42
|
searchable?: boolean;
|
|
43
43
|
/** Отображение кнопки Копировать для поля (актуально только для `readonly = true`) */
|
|
44
44
|
showCopyButton?: boolean;
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
13
|
import mergeRefs from 'merge-refs';
|
|
14
|
-
import { forwardRef, useEffect, useRef, useState } from 'react';
|
|
14
|
+
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
15
15
|
import { InputPrivate, SIZE } from '@snack-uikit/input-private';
|
|
16
16
|
import { Slider } from '@snack-uikit/slider';
|
|
17
17
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
@@ -19,7 +19,7 @@ import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
|
19
19
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
20
20
|
import { useValueControl } from '../../hooks';
|
|
21
21
|
import { FieldDecorator } from '../FieldDecorator';
|
|
22
|
-
import { generateAllowedValues, getClosestMark, getTextFieldValue } from './helpers';
|
|
22
|
+
import { generateAllowedValues, getClosestMark, getTextFieldValue, isMarkObject } from './helpers';
|
|
23
23
|
import styles from './styles.module.css';
|
|
24
24
|
const getDefaultValue = (range, min, max, value) => {
|
|
25
25
|
if (range) {
|
|
@@ -32,6 +32,14 @@ const getDefaultValue = (range, min, max, value) => {
|
|
|
32
32
|
};
|
|
33
33
|
export const FieldSlider = forwardRef((_a, ref) => {
|
|
34
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, hint, showHintIcon, size = SIZE.S, postfixIcon, textInputFormatter } = _a, rest = __rest(_a, ["id", "name", "min", "max", "step", "marks", "showScaleBar", "value", "range", "disabled", "readonly", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "hint", "showHintIcon", "size", "postfixIcon", "textInputFormatter"]);
|
|
35
|
+
const getMarkValue = useCallback((key) => {
|
|
36
|
+
const mark = marks[key];
|
|
37
|
+
if (isMarkObject(mark)) {
|
|
38
|
+
return mark.label;
|
|
39
|
+
}
|
|
40
|
+
return mark;
|
|
41
|
+
}, [marks]);
|
|
42
|
+
const hasMarksEqualToValues = useMemo(() => Object.keys(marks).every(key => key === getMarkValue(key)), [getMarkValue, marks]);
|
|
35
43
|
const [value = getDefaultValue(range, min, max, valueProp), onChange] = useValueControl({
|
|
36
44
|
value: valueProp,
|
|
37
45
|
defaultValue: getDefaultValue(range, min, max, valueProp),
|
|
@@ -40,46 +48,82 @@ export const FieldSlider = forwardRef((_a, ref) => {
|
|
|
40
48
|
const [textFieldInputValue, setTextFieldInputValue] = useState(getTextFieldValue(value, textInputFormatter));
|
|
41
49
|
const localRef = useRef(null);
|
|
42
50
|
const onTextFieldChange = (textFieldValue) => {
|
|
43
|
-
const numValue =
|
|
44
|
-
if (Number.isNaN(numValue)) {
|
|
51
|
+
const numValue = parseInt(textFieldValue);
|
|
52
|
+
if (textFieldValue && Number.isNaN(numValue)) {
|
|
45
53
|
return;
|
|
46
54
|
}
|
|
47
55
|
setTextFieldInputValue(textFieldValue);
|
|
48
56
|
};
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
57
|
+
const handleNonEqualMarksSliderChange = (textFieldNumValue) => {
|
|
58
|
+
const handleChange = (key) => {
|
|
59
|
+
setTextFieldInputValue(String(getMarkValue(key)));
|
|
60
|
+
onChange(Number(key));
|
|
61
|
+
};
|
|
62
|
+
const allowedValues = Object.keys(marks).map(key => ({
|
|
63
|
+
key,
|
|
64
|
+
value: parseInt(String(getMarkValue(key))),
|
|
65
|
+
}));
|
|
66
|
+
const suitableEntry = allowedValues.find(entry => entry.value === textFieldNumValue);
|
|
67
|
+
if (suitableEntry) {
|
|
68
|
+
handleChange(suitableEntry.key);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const actualMin = parseInt(String(getMarkValue(min)));
|
|
72
|
+
const actualMax = parseInt(String(getMarkValue(max)));
|
|
73
|
+
if (textFieldNumValue < actualMin) {
|
|
74
|
+
handleChange(min);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (textFieldNumValue > actualMax) {
|
|
78
|
+
handleChange(max);
|
|
52
79
|
return;
|
|
53
80
|
}
|
|
81
|
+
const { mark } = getClosestMark(textFieldNumValue, allowedValues, mark => mark.value);
|
|
82
|
+
handleChange(mark.key);
|
|
83
|
+
};
|
|
84
|
+
const handleEqualMarksSliderChange = (textFieldNumValue) => {
|
|
85
|
+
const handleChange = (value) => {
|
|
86
|
+
setTextFieldInputValue(String(value));
|
|
87
|
+
onChange(value);
|
|
88
|
+
};
|
|
54
89
|
if (textFieldNumValue < min) {
|
|
55
|
-
|
|
56
|
-
onChange(min);
|
|
90
|
+
handleChange(min);
|
|
57
91
|
return;
|
|
58
92
|
}
|
|
59
93
|
if (textFieldNumValue > max) {
|
|
60
|
-
|
|
61
|
-
onChange(max);
|
|
94
|
+
handleChange(max);
|
|
62
95
|
return;
|
|
63
96
|
}
|
|
64
97
|
if (step === null) {
|
|
65
98
|
const allowedValues = Object.keys(marks).map(Number);
|
|
66
99
|
if (allowedValues.includes(textFieldNumValue)) {
|
|
67
|
-
|
|
100
|
+
setTextFieldInputValue(String(textFieldNumValue));
|
|
101
|
+
handleChange(textFieldNumValue);
|
|
68
102
|
return;
|
|
69
103
|
}
|
|
70
|
-
const { mark } = getClosestMark(textFieldNumValue, allowedValues);
|
|
71
|
-
|
|
72
|
-
onChange(mark);
|
|
104
|
+
const { mark } = getClosestMark(textFieldNumValue, allowedValues, mark => mark);
|
|
105
|
+
handleChange(mark);
|
|
73
106
|
return;
|
|
74
107
|
}
|
|
75
108
|
const allowedValues = generateAllowedValues(min, max, step);
|
|
76
109
|
if (allowedValues.includes(textFieldNumValue)) {
|
|
77
|
-
|
|
110
|
+
handleChange(textFieldNumValue);
|
|
78
111
|
return;
|
|
79
112
|
}
|
|
80
|
-
const { mark } = getClosestMark(textFieldNumValue, allowedValues);
|
|
81
|
-
|
|
82
|
-
|
|
113
|
+
const { mark } = getClosestMark(textFieldNumValue, allowedValues, mark => mark);
|
|
114
|
+
handleChange(mark);
|
|
115
|
+
};
|
|
116
|
+
const handleTextValueChange = () => {
|
|
117
|
+
const textFieldNumValue = parseInt(textFieldInputValue);
|
|
118
|
+
if (Number.isNaN(textFieldNumValue)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (hasMarksEqualToValues) {
|
|
122
|
+
handleEqualMarksSliderChange(textFieldNumValue);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
handleNonEqualMarksSliderChange(textFieldNumValue);
|
|
126
|
+
}
|
|
83
127
|
};
|
|
84
128
|
const onTextFieldBlur = (e) => {
|
|
85
129
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const getDiff = (value, mark) => Math.abs(mark - value);
|
|
2
|
-
export const getClosestMark = (value, marks) => marks.reduce((accResult, mark) => {
|
|
3
|
-
const diff = getDiff(value, mark);
|
|
2
|
+
export const getClosestMark = (value, marks, getMarkValue) => marks.reduce((accResult, mark) => {
|
|
3
|
+
const diff = getDiff(value, getMarkValue(mark));
|
|
4
4
|
if (diff < accResult.lowestDiff) {
|
|
5
5
|
return {
|
|
6
6
|
lowestDiff: diff,
|
|
@@ -9,6 +9,6 @@ export const getClosestMark = (value, marks) => marks.reduce((accResult, mark) =
|
|
|
9
9
|
}
|
|
10
10
|
return accResult;
|
|
11
11
|
}, {
|
|
12
|
-
lowestDiff: getDiff(value, marks[0]),
|
|
12
|
+
lowestDiff: getDiff(value, getMarkValue(marks[0])),
|
|
13
13
|
mark: marks[0],
|
|
14
14
|
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { SliderProps as SliderComponentProps } from '@snack-uikit/slider';
|
|
3
|
+
type Marks = NonNullable<SliderComponentProps['marks']>;
|
|
4
|
+
type MarkObject = {
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
};
|
|
7
|
+
export declare function isMarkObject(mark: Marks[keyof Marks]): mark is MarkObject;
|
|
8
|
+
export {};
|
|
@@ -21,6 +21,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
21
21
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
22
22
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
23
23
|
import { useValueControl } from '../../hooks';
|
|
24
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
24
25
|
import { FieldDecorator } from '../FieldDecorator';
|
|
25
26
|
import styles from './styles.module.css';
|
|
26
27
|
const TOOLTIP_TIMEOUT = 2000;
|
|
@@ -49,6 +50,7 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
49
50
|
const plusButtonRef = useRef(null);
|
|
50
51
|
const isMinusButtonDisabled = (typeof min === 'number' && value <= min) || readonly || disabled;
|
|
51
52
|
const isPlusButtonDisabled = (typeof max === 'number' && value >= max) || readonly || disabled;
|
|
53
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
52
54
|
const adjustValue = (value) => {
|
|
53
55
|
setValue(value);
|
|
54
56
|
setTooltipOpen(true);
|
|
@@ -122,5 +124,5 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
122
124
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
123
125
|
}
|
|
124
126
|
};
|
|
125
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState:
|
|
127
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, 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' }) }) }) })));
|
|
126
128
|
});
|
|
@@ -17,6 +17,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
17
17
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
18
18
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
19
19
|
import { useCopyButton, useValueControl } from '../../hooks';
|
|
20
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
20
21
|
import { FieldDecorator } from '../FieldDecorator';
|
|
21
22
|
export const FieldText = forwardRef((_a, ref) => {
|
|
22
23
|
var { id, name, value: valueProp, placeholder, maxLength, disabled = false, readonly = false, showCopyButton: showCopyButtonProp = true, showClearButton: showClearButtonProp = true, allowMoreThanMaxLength = false, onChange: onChangeProp, onFocus, onBlur, className, label, labelTooltip, labelTooltipPlacement, required = false, hint, showHintIcon, size = SIZE.S, validationState = VALIDATION_STATE.Default, prefixIcon, error } = _a, rest = __rest(_a, ["id", "name", "value", "placeholder", "maxLength", "disabled", "readonly", "showCopyButton", "showClearButton", "allowMoreThanMaxLength", "onChange", "onFocus", "onBlur", "className", "label", "labelTooltip", "labelTooltipPlacement", "required", "hint", "showHintIcon", "size", "validationState", "prefixIcon", "error"]);
|
|
@@ -31,6 +32,7 @@ export const FieldText = forwardRef((_a, ref) => {
|
|
|
31
32
|
const showAdditionalButton = Boolean(value && !disabled);
|
|
32
33
|
const showClearButton = showClearButtonProp && showAdditionalButton && !readonly;
|
|
33
34
|
const showCopyButton = showCopyButtonProp && showAdditionalButton && readonly;
|
|
35
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
34
36
|
const onClear = () => {
|
|
35
37
|
var _a;
|
|
36
38
|
onChange('');
|
|
@@ -46,5 +48,5 @@ export const FieldText = forwardRef((_a, ref) => {
|
|
|
46
48
|
readonly,
|
|
47
49
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
48
50
|
});
|
|
49
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState:
|
|
51
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, validationState: fieldValidationState, error: error }, extractSupportProps(rest), { children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: localRef, prefix: prefixIcon, postfix: buttons, children: _jsx(InputPrivate, { ref: mergeRefs(ref, localRef), "data-size": size, value: value, onChange: onChange, onFocus: onFocus, onBlur: onBlur, tabIndex: inputTabIndex, onKeyDown: onInputKeyDown, placeholder: placeholder, disabled: disabled, readonly: readonly, type: 'text', maxLength: allowMoreThanMaxLength ? undefined : maxLength || undefined, id: id, name: name, "data-test-id": 'field-text__input' }) }) })));
|
|
50
52
|
});
|
|
@@ -18,6 +18,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
18
18
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
19
19
|
import { FieldContainerPrivate, TextArea } from '../../helperComponents';
|
|
20
20
|
import { useCopyButton, useValueControl } from '../../hooks';
|
|
21
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
21
22
|
import { FieldDecorator } from '../FieldDecorator';
|
|
22
23
|
import styles from './styles.module.css';
|
|
23
24
|
export const FieldTextArea = forwardRef((_a, ref) => {
|
|
@@ -33,6 +34,7 @@ export const FieldTextArea = forwardRef((_a, ref) => {
|
|
|
33
34
|
});
|
|
34
35
|
const showCopyButton = showCopyButtonProp && Boolean(value) && !disabled && readonly;
|
|
35
36
|
const showClearButton = showClearButtonProp && Boolean(value) && !disabled && !readonly;
|
|
37
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
36
38
|
const onClear = () => {
|
|
37
39
|
var _a;
|
|
38
40
|
onChange('');
|
|
@@ -48,5 +50,5 @@ export const FieldTextArea = forwardRef((_a, ref) => {
|
|
|
48
50
|
readonly,
|
|
49
51
|
submitKeys: ['Enter', 'Space', 'Tab'],
|
|
50
52
|
});
|
|
51
|
-
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, length: maxLength ? { max: maxLength, current: value.length } : undefined, hint: hint, disabled: disabled, readonly: readonly, showHintIcon: showHintIcon, size: size, error: error, validationState:
|
|
53
|
+
return (_jsx(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, required: required, 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, { className: styles.container, size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, "data-resizable": isResizable || undefined, variant: CONTAINER_VARIANT.MultiLine, style: { '--max-rows': maxRows }, inputRef: localRef, postfix: _jsx("span", { className: styles.postfix, children: buttons }), children: _jsx(Scroll, { className: styles.scrollContainer, size: 's', barHideStrategy: 'never', resize: isResizable ? 'vertical' : 'none', "data-test-id": 'field-textarea__scroll-area', children: _jsx(TextArea, { className: styles.textarea, "data-size": size, value: value, onChange: onChange, placeholder: placeholder, disabled: disabled, readonly: readonly, id: id, name: name, ref: mergeRefs(ref, localRef), onFocus: onFocus, onBlur: onBlur, onKeyDown: onInputKeyDown, tabIndex: inputTabIndex, maxLength: allowMoreThanMaxLength ? undefined : maxLength || undefined, "data-test-id": 'field-textarea__input' }) }) }) })));
|
|
52
54
|
});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Fields",
|
|
7
|
-
"version": "0.19.
|
|
7
|
+
"version": "0.19.2",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
"scripts": {},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@snack-uikit/button": "0.17.1",
|
|
36
|
-
"@snack-uikit/calendar": "0.7.
|
|
36
|
+
"@snack-uikit/calendar": "0.7.8",
|
|
37
37
|
"@snack-uikit/dropdown": "0.2.2",
|
|
38
38
|
"@snack-uikit/icons": "0.20.1",
|
|
39
39
|
"@snack-uikit/input-private": "3.1.2",
|
|
40
|
-
"@snack-uikit/list": "0.11.
|
|
40
|
+
"@snack-uikit/list": "0.11.2",
|
|
41
41
|
"@snack-uikit/scroll": "0.5.3",
|
|
42
|
-
"@snack-uikit/slider": "0.1.
|
|
42
|
+
"@snack-uikit/slider": "0.1.9",
|
|
43
43
|
"@snack-uikit/tag": "0.9.1",
|
|
44
44
|
"@snack-uikit/tooltip": "0.13.2",
|
|
45
45
|
"@snack-uikit/truncate-string": "0.4.13",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@snack-uikit/locale": "*"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "17bfcf1150776cd35c77d9cca8f45dde97472bf1"
|
|
62
62
|
}
|
|
@@ -30,6 +30,7 @@ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
|
30
30
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
31
31
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
32
32
|
import { useCopyButton } from '../../hooks';
|
|
33
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
33
34
|
import { FieldDecorator, FieldDecoratorProps } from '../FieldDecorator';
|
|
34
35
|
import { DEFAULT_LOCALE, SlotKey } from './constants';
|
|
35
36
|
import { useDateField } from './hooks';
|
|
@@ -122,6 +123,7 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
|
|
|
122
123
|
const showAdditionalButton = Boolean(valueProp && !disabled);
|
|
123
124
|
const showClearButton = showClearButtonProp && showAdditionalButton && !readonly;
|
|
124
125
|
const showCopyButton = showCopyButtonProp && showAdditionalButton && readonly;
|
|
126
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
125
127
|
|
|
126
128
|
const checkForLeavingFocus = useCallback(
|
|
127
129
|
<T extends HTMLInputElement | HTMLButtonElement>(event: KeyboardEvent<T>) => {
|
|
@@ -263,7 +265,7 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
|
|
|
263
265
|
showHintIcon={showHintIcon}
|
|
264
266
|
size={size}
|
|
265
267
|
error={error}
|
|
266
|
-
validationState={
|
|
268
|
+
validationState={fieldValidationState}
|
|
267
269
|
{...extractSupportProps(rest)}
|
|
268
270
|
>
|
|
269
271
|
<Dropdown
|
|
@@ -300,7 +302,7 @@ export const FieldDate = forwardRef<HTMLInputElement, FieldDateProps>(
|
|
|
300
302
|
<FieldContainerPrivate
|
|
301
303
|
className={styles.container}
|
|
302
304
|
size={size}
|
|
303
|
-
validationState={
|
|
305
|
+
validationState={fieldValidationState}
|
|
304
306
|
disabled={disabled}
|
|
305
307
|
readonly={readonly}
|
|
306
308
|
variant={CONTAINER_VARIANT.SingleLine}
|
|
@@ -5,6 +5,7 @@ import { SIZE } from '@snack-uikit/input-private';
|
|
|
5
5
|
import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
6
6
|
|
|
7
7
|
import { VALIDATION_STATE } from '../../constants';
|
|
8
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
8
9
|
import { Footer, FooterProps } from './Footer';
|
|
9
10
|
import { Header, HeaderProps } from './Header';
|
|
10
11
|
import styles from './styles.module.scss';
|
|
@@ -39,11 +40,11 @@ export function FieldDecorator({
|
|
|
39
40
|
labelTooltipPlacement,
|
|
40
41
|
size = SIZE.S,
|
|
41
42
|
error,
|
|
42
|
-
validationState
|
|
43
|
+
validationState = VALIDATION_STATE.Default,
|
|
43
44
|
...rest
|
|
44
45
|
}: FieldDecoratorProps) {
|
|
45
46
|
const isFieldActive = !disabled && !readonly;
|
|
46
|
-
const
|
|
47
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
47
48
|
|
|
48
49
|
return (
|
|
49
50
|
<div className={cn(styles.decorator, className)} {...extractSupportProps(rest)} data-size={size}>
|
|
@@ -63,7 +64,7 @@ export function FieldDecorator({
|
|
|
63
64
|
hint={error || hint}
|
|
64
65
|
showHintIcon={showHintIcon}
|
|
65
66
|
size={size}
|
|
66
|
-
validationState={isFieldActive ?
|
|
67
|
+
validationState={isFieldActive ? fieldValidationState : VALIDATION_STATE.Default}
|
|
67
68
|
/>
|
|
68
69
|
</div>
|
|
69
70
|
);
|
|
@@ -14,6 +14,7 @@ import { extractSupportProps, WithSupportProps } from '@snack-uikit/utils';
|
|
|
14
14
|
import { CONTAINER_VARIANT, VALIDATION_STATE } from '../../constants';
|
|
15
15
|
import { FieldContainerPrivate } from '../../helperComponents';
|
|
16
16
|
import { useCopyButton, useHideButton, useValueControl } from '../../hooks';
|
|
17
|
+
import { getValidationState } from '../../utils/getValidationState';
|
|
17
18
|
import { FieldDecorator, FieldDecoratorProps } from '../FieldDecorator';
|
|
18
19
|
|
|
19
20
|
type InputProps = Pick<Partial<InputPrivateProps>, 'value' | 'onChange'> &
|
|
@@ -96,6 +97,8 @@ export const FieldSecure = forwardRef<HTMLInputElement, FieldSecureProps>(
|
|
|
96
97
|
const showCopyButton = showCopyButtonProp && Boolean(value) && readonly && !disabled;
|
|
97
98
|
const showHideButton = !(readonly && !value);
|
|
98
99
|
|
|
100
|
+
const fieldValidationState = getValidationState({ validationState, error });
|
|
101
|
+
|
|
99
102
|
const toggleHidden = () => {
|
|
100
103
|
setHidden(!hidden);
|
|
101
104
|
|
|
@@ -131,12 +134,12 @@ export const FieldSecure = forwardRef<HTMLInputElement, FieldSecureProps>(
|
|
|
131
134
|
showHintIcon={showHintIcon}
|
|
132
135
|
size={size}
|
|
133
136
|
error={error}
|
|
134
|
-
validationState={
|
|
137
|
+
validationState={fieldValidationState}
|
|
135
138
|
{...extractSupportProps(rest)}
|
|
136
139
|
>
|
|
137
140
|
<FieldContainerPrivate
|
|
138
141
|
size={size}
|
|
139
|
-
validationState={
|
|
142
|
+
validationState={fieldValidationState}
|
|
140
143
|
disabled={disabled}
|
|
141
144
|
readonly={readonly}
|
|
142
145
|
variant={CONTAINER_VARIANT.SingleLine}
|