@snack-uikit/fields 0.21.5 → 0.22.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 +20 -0
- package/README.md +30 -8
- package/dist/components/FieldDate/FieldDate.js +1 -1
- package/dist/components/FieldDecorator/Header.d.ts +2 -1
- package/dist/components/FieldDecorator/styles.module.css +1 -0
- package/dist/components/FieldDecorator/utils.d.ts +2 -1
- package/dist/components/FieldSelect/FieldSelectMultiple.js +1 -1
- package/dist/components/FieldSelect/FieldSelectSingle.js +1 -1
- package/dist/components/FieldSelect/legacy/hooks.js +3 -3
- package/dist/components/FieldSlider/FieldSlider.js +5 -0
- package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.d.ts +2 -3
- package/dist/helperComponents/FieldContainerPrivate/FieldContainerPrivate.js +2 -2
- package/package.json +3 -3
- package/src/components/FieldDate/FieldDate.tsx +1 -1
- package/src/components/FieldDecorator/Header.tsx +3 -1
- package/src/components/FieldDecorator/styles.module.scss +1 -0
- package/src/components/FieldSelect/FieldSelectMultiple.tsx +1 -0
- package/src/components/FieldSelect/FieldSelectSingle.tsx +1 -0
- package/src/components/FieldSelect/legacy/hooks.ts +3 -7
- package/src/components/FieldSlider/FieldSlider.tsx +6 -0
- package/src/helperComponents/FieldContainerPrivate/FieldContainerPrivate.tsx +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,26 @@
|
|
|
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.22.0 (2024-06-24)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **PDS-131:** break-word for hint ([cb403c0](https://github.com/cloud-ru-tech/snack-uikit/commit/cb403c0ec104a7cdc600455b73d626523866140f))
|
|
12
|
+
* **PDS-131:** field-select: should close when clicking on arrow ([626aff1](https://github.com/cloud-ru-tech/snack-uikit/commit/626aff15ef75ae414cbfe8b48a13ef38766376a6))
|
|
13
|
+
* **PDS-131:** field-select: start search from first symbol ([4f228d0](https://github.com/cloud-ru-tech/snack-uikit/commit/4f228d0bbe4a941ae209ddb12ef60cba24c188ba))
|
|
14
|
+
* **PDS-131:** field-slider: re-render value when marks, min or max are changed ([c4e7f77](https://github.com/cloud-ru-tech/snack-uikit/commit/c4e7f77991519095312f84bdbad0992ba58fae60))
|
|
15
|
+
* **PDS-353:** field date: reset visual label when value is cleared from outside ([79247a9](https://github.com/cloud-ru-tech/snack-uikit/commit/79247a9821dbd2ec4833e389ccea6ba42291dc7b))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **PDS-131:** allow to pass ReactNode for labelTooltip ([2d3efc2](https://github.com/cloud-ru-tech/snack-uikit/commit/2d3efc2c787ef5a69957bacbe04b12b31fcbfa58))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
6
26
|
## 0.21.5 (2024-06-20)
|
|
7
27
|
|
|
8
28
|
### Only dependencies have been changed
|
package/README.md
CHANGED
|
@@ -160,6 +160,28 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
160
160
|
prefixIcon={<PlaceholderSVG />}
|
|
161
161
|
/>;
|
|
162
162
|
```
|
|
163
|
+
## Особенности работы FieldStepper-a
|
|
164
|
+
|
|
165
|
+
FieldStepper в основном предназначен для работы с небольшими числами,
|
|
166
|
+
которые изменяются с помощью кнопок увеличения и уменьшения значения.
|
|
167
|
+
Для обеспечения консистентности в компонент была добавлена возможность ввода значений с клавиатуры,
|
|
168
|
+
однако это требует валидации пользовательского ввода.
|
|
169
|
+
|
|
170
|
+
Существует два способа ограничения ввода:
|
|
171
|
+
1. Исправление значения после завершения ввода пользователем:
|
|
172
|
+
* Такой способ есть, он активируется с помощью пропсы `allowMoreThanLimits = false`.
|
|
173
|
+
Однако, это плохой UX-паттерн, так как пользователь может не заметить,
|
|
174
|
+
что значение было изменено.
|
|
175
|
+
|
|
176
|
+
2. Запрет ввода чисел, превышающих максимальное или минимальное значение:
|
|
177
|
+
* Такой способ можно было бы реализовать либо исправлением значения на max/min,
|
|
178
|
+
либо просто не изменяя значение в поле. Однако, это ещё более плохой UX-паттерн,
|
|
179
|
+
так как может быть воспринят пользователем как неисправность.
|
|
180
|
+
|
|
181
|
+
Правильным подходом будет позволить пользователю ввести желаемое значение и, при необходимости,
|
|
182
|
+
подсветить его некорректность с помощью свойств validationState и hint.
|
|
183
|
+
Это можно сделать по событию blur или при отправке формы.
|
|
184
|
+
|
|
163
185
|
|
|
164
186
|
[//]: DOCUMENTATION_SECTION_START
|
|
165
187
|
[//]: THIS_SECTION_IS_AUTOGENERATED_PLEASE_DONT_EDIT_IT
|
|
@@ -173,7 +195,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
173
195
|
| readonly | `boolean` | - | Является ли поле доступным только на чтение Доступно ли поле только на чтение |
|
|
174
196
|
| error | `string` | - | |
|
|
175
197
|
| label | `string` | - | Лейбл |
|
|
176
|
-
| labelTooltip | `
|
|
198
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
177
199
|
| labelFor | `string` | - | Аттрибут for |
|
|
178
200
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
179
201
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
@@ -203,7 +225,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
203
225
|
| error | `string` | - | |
|
|
204
226
|
| className | `string` | - | CSS-класс |
|
|
205
227
|
| label | `string` | - | Лейбл |
|
|
206
|
-
| labelTooltip | `
|
|
228
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
207
229
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
208
230
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
209
231
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -235,7 +257,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
235
257
|
| error | `string` | - | |
|
|
236
258
|
| className | `string` | - | CSS-класс |
|
|
237
259
|
| label | `string` | - | Лейбл |
|
|
238
|
-
| labelTooltip | `
|
|
260
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
239
261
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
240
262
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
241
263
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -267,7 +289,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
267
289
|
| error | `string` | - | |
|
|
268
290
|
| className | `string` | - | CSS-класс |
|
|
269
291
|
| label | `string` | - | Лейбл |
|
|
270
|
-
| labelTooltip | `
|
|
292
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
271
293
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
272
294
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
273
295
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -301,7 +323,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
301
323
|
| error | `string` | - | |
|
|
302
324
|
| className | `string` | - | CSS-класс |
|
|
303
325
|
| label | `string` | - | Лейбл |
|
|
304
|
-
| labelTooltip | `
|
|
326
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
305
327
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
306
328
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
307
329
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -326,7 +348,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
326
348
|
| error | `string` | - | |
|
|
327
349
|
| className | `string` | - | CSS-класс |
|
|
328
350
|
| label | `string` | - | Лейбл |
|
|
329
|
-
| labelTooltip | `
|
|
351
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
330
352
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
331
353
|
| size | enum Size: `"s"`, `"m"`, `"l"` | - | Размер |
|
|
332
354
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -379,7 +401,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
379
401
|
| error | `string` | - | |
|
|
380
402
|
| className | `string` | - | CSS-класс |
|
|
381
403
|
| label | `string` | - | Лейбл |
|
|
382
|
-
| labelTooltip | `
|
|
404
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
383
405
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
384
406
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
385
407
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -411,7 +433,7 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
411
433
|
| marks | `Record<string \| number, ReactNode \| MarkObj>` | - | |
|
|
412
434
|
| className | `string` | - | CSS-класс |
|
|
413
435
|
| label | `string` | - | Лейбл |
|
|
414
|
-
| labelTooltip | `
|
|
436
|
+
| labelTooltip | `ReactNode` | - | Всплывающая подсказка лейбла |
|
|
415
437
|
| required | `boolean` | - | Является ли поле обязательным |
|
|
416
438
|
| size | enum Size: `"s"`, `"m"`, `"l"` | SIZE.S | Размер |
|
|
417
439
|
| labelTooltipPlacement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Расположение подсказки лейбла |
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
1
2
|
import { Size } from '@snack-uikit/input-private';
|
|
2
3
|
import { TooltipProps } from '@snack-uikit/tooltip';
|
|
3
4
|
export type HeaderProps = {
|
|
4
5
|
/** Лейбл */
|
|
5
6
|
label?: string;
|
|
6
7
|
/** Всплывающая подсказка лейбла */
|
|
7
|
-
labelTooltip?:
|
|
8
|
+
labelTooltip?: ReactNode;
|
|
8
9
|
/** Аттрибут for */
|
|
9
10
|
labelFor?: string;
|
|
10
11
|
/** Является ли поле обязательным */
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import { FieldDecoratorProps } from './FieldDecorator';
|
|
2
3
|
export declare function extractFieldDecoratorProps<T extends Partial<FieldDecoratorProps>>({ error, required, readonly, label, labelTooltip, labelTooltipPlacement, labelFor, hint, disabled, showHintIcon, size, validationState, className, }: T): {
|
|
3
4
|
error: string | undefined;
|
|
4
5
|
required: boolean | undefined;
|
|
5
6
|
readonly: boolean | undefined;
|
|
6
7
|
label: string | undefined;
|
|
7
|
-
labelTooltip:
|
|
8
|
+
labelTooltip: import("react").ReactNode;
|
|
8
9
|
labelTooltipPlacement: import("@snack-uikit/popover-private/dist/types").Placement | undefined;
|
|
9
10
|
labelFor: string | undefined;
|
|
10
11
|
hint: string | undefined;
|
|
@@ -117,7 +117,7 @@ export const FieldSelectMultiple = forwardRef((_a, ref) => {
|
|
|
117
117
|
const fuzzySearch = useFuzzySearch(items);
|
|
118
118
|
const result = autocomplete || !searchable || prevInputValue.current === inputValue ? items : fuzzySearch(inputValue);
|
|
119
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: {
|
|
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, trigger: 'click', selection: {
|
|
121
121
|
mode: 'multiple',
|
|
122
122
|
value: value,
|
|
123
123
|
onChange: value => {
|
|
@@ -128,7 +128,7 @@ export const FieldSelectSingle = forwardRef((_a, ref) => {
|
|
|
128
128
|
mode: 'single',
|
|
129
129
|
value: value,
|
|
130
130
|
onChange: handleSelectionChange,
|
|
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({
|
|
131
|
+
}, size: size, open: open, onOpenChange: handleOpenChange, trigger: 'click', 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({
|
|
132
132
|
[styles.readonlyCursor]: !searchable,
|
|
133
133
|
}) }), _jsxs("div", { className: styles.postfix, children: [buttons, _jsx(ArrowIcon, { size: arrowIconSize, className: styles.arrowIcon })] })] })) })) })));
|
|
134
134
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import FuzzySearch from 'fuzzy-search';
|
|
2
2
|
import { useCallback, useMemo } from 'react';
|
|
3
3
|
import { kindFlattenItems } from '@snack-uikit/list';
|
|
4
|
-
const DEFAULT_MIN_SEARCH_INPUT_LENGTH =
|
|
4
|
+
const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 1;
|
|
5
5
|
/**
|
|
6
6
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
7
7
|
*/
|
|
@@ -11,8 +11,8 @@ export function useFuzzySearch(items, minSearchInputLength) {
|
|
|
11
11
|
return Object.values(flattenItems);
|
|
12
12
|
}, [items]);
|
|
13
13
|
return useCallback((search) => {
|
|
14
|
-
const searcher = new FuzzySearch(flattenItems, ['content.option', 'content.caption', 'content.description'
|
|
15
|
-
return search.length
|
|
14
|
+
const searcher = new FuzzySearch(flattenItems, ['content.option', 'content.caption', 'content.description'], {});
|
|
15
|
+
return search.length >= (minSearchInputLength !== null && minSearchInputLength !== void 0 ? minSearchInputLength : DEFAULT_MIN_SEARCH_INPUT_LENGTH)
|
|
16
16
|
? searcher.search(search)
|
|
17
17
|
: items;
|
|
18
18
|
}, [flattenItems, items, minSearchInputLength]);
|
|
@@ -140,5 +140,10 @@ export const FieldSlider = forwardRef((_a, ref) => {
|
|
|
140
140
|
useEffect(() => {
|
|
141
141
|
setTextFieldInputValue(getTextFieldValue(value, textInputFormatter));
|
|
142
142
|
}, [value, textInputFormatter]);
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
handleTextValueChange();
|
|
145
|
+
// update value only when marks, min or max are changed
|
|
146
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
147
|
+
}, [marks, min, max]);
|
|
143
148
|
return (_jsxs(FieldDecorator, Object.assign({ className: className, label: label, labelTooltip: labelTooltip, labelTooltipPlacement: labelTooltipPlacement, labelFor: id, disabled: disabled, required: required, 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' }) }) })] })));
|
|
144
149
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties,
|
|
1
|
+
import { CSSProperties, ReactElement, ReactNode, RefObject } from 'react';
|
|
2
2
|
import { Size } from '@snack-uikit/input-private';
|
|
3
3
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
4
|
import { ContainerVariant, ValidationState } from '../../types';
|
|
@@ -16,6 +16,5 @@ export type FieldContainerPrivateProps = WithSupportProps<{
|
|
|
16
16
|
prefix?: ReactElement;
|
|
17
17
|
postfix?: ReactElement;
|
|
18
18
|
inputRef: RefObject<HTMLElement>;
|
|
19
|
-
onMouseDown?: MouseEventHandler<HTMLElement>;
|
|
20
19
|
}>;
|
|
21
|
-
export declare function FieldContainerPrivate({ className, children, size, validationState, variant, disabled, readonly, focused, selectable, style, prefix, postfix, inputRef,
|
|
20
|
+
export declare function FieldContainerPrivate({ className, children, size, validationState, variant, disabled, readonly, focused, selectable, style, prefix, postfix, inputRef, ...rest }: FieldContainerPrivateProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,7 +15,7 @@ import { extractSupportProps } from '@snack-uikit/utils';
|
|
|
15
15
|
import { VALIDATION_STATE } from '../../constants';
|
|
16
16
|
import styles from './styles.module.css';
|
|
17
17
|
export function FieldContainerPrivate(_a) {
|
|
18
|
-
var { className, children, size, validationState, variant, disabled, readonly, focused, selectable, style, prefix, postfix, inputRef
|
|
18
|
+
var { className, children, size, validationState, variant, disabled, readonly, focused, selectable, style, prefix, postfix, inputRef } = _a, rest = __rest(_a, ["className", "children", "size", "validationState", "variant", "disabled", "readonly", "focused", "selectable", "style", "prefix", "postfix", "inputRef"]);
|
|
19
19
|
const handleContainerClick = () => {
|
|
20
20
|
var _a;
|
|
21
21
|
if (disabled) {
|
|
@@ -23,5 +23,5 @@ export function FieldContainerPrivate(_a) {
|
|
|
23
23
|
}
|
|
24
24
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
25
25
|
};
|
|
26
|
-
return (_jsxs("div", Object.assign({ className: cn(className, styles.container), style: style, "data-size": size, "data-validation": disabled || readonly ? VALIDATION_STATE.Default : validationState, "data-variant": variant, "data-disabled": disabled || undefined, "data-readonly": readonly || undefined, "data-focused": focused || undefined, "data-selectable": selectable || undefined, "data-test-id": 'field-container-private', onClick: handleContainerClick,
|
|
26
|
+
return (_jsxs("div", Object.assign({ className: cn(className, styles.container), style: style, "data-size": size, "data-validation": disabled || readonly ? VALIDATION_STATE.Default : validationState, "data-variant": variant, "data-disabled": disabled || undefined, "data-readonly": readonly || undefined, "data-focused": focused || undefined, "data-selectable": selectable || undefined, "data-test-id": 'field-container-private', onClick: handleContainerClick, role: 'textbox', tabIndex: -1 }, extractSupportProps(rest), { children: [prefix && (_jsx("span", { className: styles.prefix, "data-test-id": 'field-container-private__prefix-icon', children: prefix })), children, postfix && _jsx("span", { className: styles.postfix, children: postfix })] })));
|
|
27
27
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Fields",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.22.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@snack-uikit/list": "0.13.8",
|
|
41
41
|
"@snack-uikit/scroll": "0.6.0",
|
|
42
42
|
"@snack-uikit/skeleton": "0.3.4",
|
|
43
|
-
"@snack-uikit/slider": "0.1.
|
|
43
|
+
"@snack-uikit/slider": "0.1.13",
|
|
44
44
|
"@snack-uikit/tag": "0.9.4",
|
|
45
45
|
"@snack-uikit/tooltip": "0.13.5",
|
|
46
46
|
"@snack-uikit/truncate-string": "0.4.18",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@snack-uikit/locale": "*"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "72e23a04c481b7e3e7becf8ed3d34b785083ba59"
|
|
63
63
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
1
3
|
import { QuestionSVG } from '@snack-uikit/icons';
|
|
2
4
|
import { Size } from '@snack-uikit/input-private';
|
|
3
5
|
import { Tooltip, TooltipProps } from '@snack-uikit/tooltip';
|
|
@@ -9,7 +11,7 @@ export type HeaderProps = {
|
|
|
9
11
|
/** Лейбл */
|
|
10
12
|
label?: string;
|
|
11
13
|
/** Всплывающая подсказка лейбла */
|
|
12
|
-
labelTooltip?:
|
|
14
|
+
labelTooltip?: ReactNode;
|
|
13
15
|
/** Аттрибут for */
|
|
14
16
|
labelFor?: string;
|
|
15
17
|
/** Является ли поле обязательным */
|
|
@@ -3,7 +3,7 @@ import { useCallback, useMemo } from 'react';
|
|
|
3
3
|
|
|
4
4
|
import { ItemProps, kindFlattenItems } from '@snack-uikit/list';
|
|
5
5
|
|
|
6
|
-
const DEFAULT_MIN_SEARCH_INPUT_LENGTH =
|
|
6
|
+
const DEFAULT_MIN_SEARCH_INPUT_LENGTH = 1;
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Нечеткий поиск среди айтемов по полям 'content.option', 'content.caption', 'content.description', 'label'
|
|
@@ -17,13 +17,9 @@ export function useFuzzySearch(items: ItemProps[], minSearchInputLength?: number
|
|
|
17
17
|
|
|
18
18
|
return useCallback(
|
|
19
19
|
(search: string) => {
|
|
20
|
-
const searcher = new FuzzySearch(
|
|
21
|
-
flattenItems,
|
|
22
|
-
['content.option', 'content.caption', 'content.description', 'label'],
|
|
23
|
-
{},
|
|
24
|
-
);
|
|
20
|
+
const searcher = new FuzzySearch(flattenItems, ['content.option', 'content.caption', 'content.description'], {});
|
|
25
21
|
|
|
26
|
-
return search.length
|
|
22
|
+
return search.length >= (minSearchInputLength ?? DEFAULT_MIN_SEARCH_INPUT_LENGTH)
|
|
27
23
|
? searcher.search(search)
|
|
28
24
|
: items;
|
|
29
25
|
},
|
|
@@ -236,6 +236,12 @@ export const FieldSlider = forwardRef<HTMLInputElement, FieldSliderProps>(
|
|
|
236
236
|
setTextFieldInputValue(getTextFieldValue(value, textInputFormatter));
|
|
237
237
|
}, [value, textInputFormatter]);
|
|
238
238
|
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
handleTextValueChange();
|
|
241
|
+
// update value only when marks, min or max are changed
|
|
242
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
243
|
+
}, [marks, min, max]);
|
|
244
|
+
|
|
239
245
|
return (
|
|
240
246
|
<FieldDecorator
|
|
241
247
|
className={className}
|
|
@@ -22,7 +22,6 @@ export type FieldContainerPrivateProps = WithSupportProps<{
|
|
|
22
22
|
prefix?: ReactElement;
|
|
23
23
|
postfix?: ReactElement;
|
|
24
24
|
inputRef: RefObject<HTMLElement>;
|
|
25
|
-
onMouseDown?: MouseEventHandler<HTMLElement>;
|
|
26
25
|
}>;
|
|
27
26
|
|
|
28
27
|
export function FieldContainerPrivate({
|
|
@@ -39,7 +38,6 @@ export function FieldContainerPrivate({
|
|
|
39
38
|
prefix,
|
|
40
39
|
postfix,
|
|
41
40
|
inputRef,
|
|
42
|
-
onMouseDown,
|
|
43
41
|
...rest
|
|
44
42
|
}: FieldContainerPrivateProps) {
|
|
45
43
|
const handleContainerClick: MouseEventHandler<HTMLDivElement> = () => {
|
|
@@ -62,7 +60,6 @@ export function FieldContainerPrivate({
|
|
|
62
60
|
data-selectable={selectable || undefined}
|
|
63
61
|
data-test-id='field-container-private'
|
|
64
62
|
onClick={handleContainerClick}
|
|
65
|
-
onMouseDown={onMouseDown}
|
|
66
63
|
role='textbox'
|
|
67
64
|
tabIndex={-1}
|
|
68
65
|
{...extractSupportProps(rest)}
|