@snack-uikit/fields 0.34.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/cjs/components/FieldStepper/FieldStepper.js +70 -68
- package/dist/cjs/components/FieldStepper/styles.module.css +19 -0
- package/dist/esm/components/FieldStepper/FieldStepper.js +14 -24
- package/dist/esm/components/FieldStepper/styles.module.css +19 -0
- package/package.json +6 -6
- package/src/components/FieldStepper/FieldStepper.tsx +68 -71
- package/src/components/FieldStepper/styles.module.scss +22 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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.35.0 (2024-11-19)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **FF-5887:** change prefix/postfix for FieldStepper ([b7aca2d](https://github.com/cloud-ru-tech/snack-uikit/commit/b7aca2da5ef613747599ff1cafaaa3de747be717))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# 0.34.0 (2024-11-18)
|
|
7
18
|
|
|
8
19
|
|
|
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
18
18
|
});
|
|
19
19
|
exports.FieldStepper = void 0;
|
|
20
20
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
21
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
21
22
|
const merge_refs_1 = __importDefault(require("merge-refs"));
|
|
22
23
|
const react_1 = require("react");
|
|
23
24
|
const button_1 = require("@snack-uikit/button");
|
|
@@ -42,6 +43,11 @@ const getDefaultValue = (min, max) => {
|
|
|
42
43
|
}
|
|
43
44
|
return 0;
|
|
44
45
|
};
|
|
46
|
+
const SymbolWidth = {
|
|
47
|
+
s: 8,
|
|
48
|
+
m: 9,
|
|
49
|
+
l: 10
|
|
50
|
+
};
|
|
45
51
|
exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
46
52
|
var {
|
|
47
53
|
id,
|
|
@@ -83,8 +89,6 @@ exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
83
89
|
const [tooltip, setTooltip] = (0, react_1.useState)('');
|
|
84
90
|
const timerRef = (0, react_1.useRef)();
|
|
85
91
|
const inputRef = (0, react_1.useRef)(null);
|
|
86
|
-
const minusButtonRef = (0, react_1.useRef)(null);
|
|
87
|
-
const plusButtonRef = (0, react_1.useRef)(null);
|
|
88
92
|
const isMinusButtonDisabled = typeof min === 'number' && value <= min || readonly || disabled;
|
|
89
93
|
const isPlusButtonDisabled = typeof max === 'number' && value >= max || readonly || disabled;
|
|
90
94
|
const prefixSettings = (0, hooks_1.usePrefix)({
|
|
@@ -130,17 +134,10 @@ exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
130
134
|
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
131
135
|
};
|
|
132
136
|
const handleInputChange = (value, event) => setValue(Number(value), event);
|
|
133
|
-
const handleInputKeyDown =
|
|
134
|
-
var _a, _b;
|
|
137
|
+
const handleInputKeyDown = () => {
|
|
135
138
|
if (readonly || disabled) {
|
|
136
139
|
return;
|
|
137
140
|
}
|
|
138
|
-
if (event.key === 'ArrowRight' && !isPlusButtonDisabled) {
|
|
139
|
-
(_a = plusButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
140
|
-
}
|
|
141
|
-
if (event.key === 'ArrowLeft' && !isMinusButtonDisabled) {
|
|
142
|
-
(_b = minusButtonRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
143
|
-
}
|
|
144
141
|
};
|
|
145
142
|
const handleMinusButtonClick = e => {
|
|
146
143
|
e.preventDefault();
|
|
@@ -152,25 +149,15 @@ exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
152
149
|
e.stopPropagation();
|
|
153
150
|
setValue(Math.max(Math.min(max, value + step), min));
|
|
154
151
|
};
|
|
155
|
-
const handleMinusButtonKeyDown =
|
|
156
|
-
var _a;
|
|
152
|
+
const handleMinusButtonKeyDown = () => {
|
|
157
153
|
if (readonly || disabled) {
|
|
158
154
|
return;
|
|
159
155
|
}
|
|
160
|
-
if (event.key === 'ArrowRight') {
|
|
161
|
-
event.preventDefault();
|
|
162
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
163
|
-
}
|
|
164
156
|
};
|
|
165
|
-
const handlePlusButtonKeyDown =
|
|
166
|
-
var _a;
|
|
157
|
+
const handlePlusButtonKeyDown = () => {
|
|
167
158
|
if (readonly || disabled) {
|
|
168
159
|
return;
|
|
169
160
|
}
|
|
170
|
-
if (event.key === 'ArrowLeft') {
|
|
171
|
-
event.preventDefault();
|
|
172
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
173
|
-
}
|
|
174
161
|
};
|
|
175
162
|
return (0, jsx_runtime_1.jsx)(FieldDecorator_1.FieldDecorator, Object.assign({
|
|
176
163
|
className: className,
|
|
@@ -192,6 +179,7 @@ exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
192
179
|
tip: tooltip,
|
|
193
180
|
open: allowMoreThanLimits ? false : tooltipOpen,
|
|
194
181
|
"data-test-id": 'field-stepper__limit-tooltip',
|
|
182
|
+
triggerClassName: styles_module_scss_1.default.trigger,
|
|
195
183
|
children: (0, jsx_runtime_1.jsx)(helperComponents_1.FieldContainerPrivate, {
|
|
196
184
|
size: size,
|
|
197
185
|
validationState: fieldValidationState,
|
|
@@ -199,54 +187,68 @@ exports.FieldStepper = (0, react_1.forwardRef)((_a, ref) => {
|
|
|
199
187
|
readonly: readonly,
|
|
200
188
|
variant: constants_1.CONTAINER_VARIANT.SingleLine,
|
|
201
189
|
inputRef: inputRef,
|
|
202
|
-
prefix: (0, jsx_runtime_1.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
disabled: isMinusButtonDisabled,
|
|
212
|
-
"data-test-id": 'field-stepper__minus-button'
|
|
213
|
-
}), prefixSettings.show && prefixSettings.render({
|
|
214
|
-
key: prefixSettings.id
|
|
215
|
-
})]
|
|
190
|
+
prefix: (0, jsx_runtime_1.jsx)(button_1.ButtonFunction, {
|
|
191
|
+
tabIndex: -1,
|
|
192
|
+
size: 'xs',
|
|
193
|
+
className: styles_module_scss_1.default.button,
|
|
194
|
+
icon: (0, jsx_runtime_1.jsx)(icons_1.MinusSVG, {}),
|
|
195
|
+
onClick: handleMinusButtonClick,
|
|
196
|
+
onKeyDown: handleMinusButtonKeyDown,
|
|
197
|
+
disabled: isMinusButtonDisabled,
|
|
198
|
+
"data-test-id": 'field-stepper__minus-button'
|
|
216
199
|
}),
|
|
217
|
-
postfix: (0, jsx_runtime_1.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
onClick: handlePlusButtonClick,
|
|
227
|
-
onKeyDown: handlePlusButtonKeyDown,
|
|
228
|
-
disabled: isPlusButtonDisabled,
|
|
229
|
-
"data-test-id": 'field-stepper__plus-button'
|
|
230
|
-
})]
|
|
200
|
+
postfix: (0, jsx_runtime_1.jsx)(button_1.ButtonFunction, {
|
|
201
|
+
tabIndex: -1,
|
|
202
|
+
size: 'xs',
|
|
203
|
+
className: styles_module_scss_1.default.button,
|
|
204
|
+
icon: (0, jsx_runtime_1.jsx)(icons_1.PlusSVG, {}),
|
|
205
|
+
onClick: handlePlusButtonClick,
|
|
206
|
+
onKeyDown: handlePlusButtonKeyDown,
|
|
207
|
+
disabled: isPlusButtonDisabled,
|
|
208
|
+
"data-test-id": 'field-stepper__plus-button'
|
|
231
209
|
}),
|
|
232
|
-
children: (0, jsx_runtime_1.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
210
|
+
children: (0, jsx_runtime_1.jsxs)("div", {
|
|
211
|
+
className: styles_module_scss_1.default.wrap,
|
|
212
|
+
children: [(0, jsx_runtime_1.jsx)("div", {
|
|
213
|
+
className: (0, classnames_1.default)({
|
|
214
|
+
[styles_module_scss_1.default.prefixWrapper]: prefixSettings.show
|
|
215
|
+
}),
|
|
216
|
+
children: prefixSettings.show && prefixSettings.render({
|
|
217
|
+
key: prefixSettings.id
|
|
218
|
+
})
|
|
219
|
+
}), (0, jsx_runtime_1.jsx)("div", {
|
|
220
|
+
style: {
|
|
221
|
+
width: String(value).length * SymbolWidth[size],
|
|
222
|
+
maxWidth: '100%'
|
|
223
|
+
},
|
|
224
|
+
children: (0, jsx_runtime_1.jsx)(input_private_1.InputPrivate, {
|
|
225
|
+
ref: (0, merge_refs_1.default)(ref, inputRef),
|
|
226
|
+
className: styles_module_scss_1.default.stepper,
|
|
227
|
+
"data-size": size,
|
|
228
|
+
value: String(value),
|
|
229
|
+
tabIndex: 0,
|
|
230
|
+
onKeyDown: handleInputKeyDown,
|
|
231
|
+
onChange: handleInputChange,
|
|
232
|
+
onBlur: handleInputBlur,
|
|
233
|
+
onFocus: handleInputFocus,
|
|
234
|
+
disabled: disabled,
|
|
235
|
+
readonly: readonly,
|
|
236
|
+
type: 'number',
|
|
237
|
+
id: id,
|
|
238
|
+
step: step,
|
|
239
|
+
name: name,
|
|
240
|
+
min: min,
|
|
241
|
+
max: max,
|
|
242
|
+
"data-test-id": 'field-stepper__input'
|
|
243
|
+
})
|
|
244
|
+
}), (0, jsx_runtime_1.jsx)("div", {
|
|
245
|
+
className: (0, classnames_1.default)({
|
|
246
|
+
[styles_module_scss_1.default.postfixWrapper]: postfixSettings.show
|
|
247
|
+
}),
|
|
248
|
+
children: postfixSettings.show && postfixSettings.render({
|
|
249
|
+
key: postfixSettings.id
|
|
250
|
+
})
|
|
251
|
+
})]
|
|
250
252
|
})
|
|
251
253
|
})
|
|
252
254
|
})
|
|
@@ -7,4 +7,23 @@
|
|
|
7
7
|
}
|
|
8
8
|
.button[data-disabled] *{
|
|
9
9
|
cursor:not-allowed;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.trigger{
|
|
13
|
+
min-width:auto;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.wrap{
|
|
17
|
+
overflow:hidden;
|
|
18
|
+
display:flex;
|
|
19
|
+
justify-content:center;
|
|
20
|
+
max-width:100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.prefixWrapper{
|
|
24
|
+
margin-right:var(--space-fields-stepper-content-container, 4px);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.postfixWrapper{
|
|
28
|
+
margin-left:var(--space-fields-stepper-content-container, 4px);
|
|
10
29
|
}
|
|
@@ -9,7 +9,8 @@ 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, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
import cn from 'classnames';
|
|
13
14
|
import mergeRefs from 'merge-refs';
|
|
14
15
|
import { forwardRef, useEffect, useRef, useState, } from 'react';
|
|
15
16
|
import { ButtonFunction } from '@snack-uikit/button';
|
|
@@ -34,6 +35,11 @@ const getDefaultValue = (min, max) => {
|
|
|
34
35
|
}
|
|
35
36
|
return 0;
|
|
36
37
|
};
|
|
38
|
+
const SymbolWidth = {
|
|
39
|
+
s: 8,
|
|
40
|
+
m: 9,
|
|
41
|
+
l: 10,
|
|
42
|
+
};
|
|
37
43
|
export const FieldStepper = forwardRef((_a, ref) => {
|
|
38
44
|
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
45
|
const { t } = useLocale('Fields');
|
|
@@ -46,8 +52,6 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
46
52
|
const [tooltip, setTooltip] = useState('');
|
|
47
53
|
const timerRef = useRef();
|
|
48
54
|
const inputRef = useRef(null);
|
|
49
|
-
const minusButtonRef = useRef(null);
|
|
50
|
-
const plusButtonRef = useRef(null);
|
|
51
55
|
const isMinusButtonDisabled = (typeof min === 'number' && value <= min) || readonly || disabled;
|
|
52
56
|
const isPlusButtonDisabled = (typeof max === 'number' && value >= max) || readonly || disabled;
|
|
53
57
|
const prefixSettings = usePrefix({ prefix, disabled });
|
|
@@ -84,17 +88,10 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
84
88
|
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
85
89
|
};
|
|
86
90
|
const handleInputChange = (value, event) => setValue(Number(value), event);
|
|
87
|
-
const handleInputKeyDown =
|
|
88
|
-
var _a, _b;
|
|
91
|
+
const handleInputKeyDown = () => {
|
|
89
92
|
if (readonly || disabled) {
|
|
90
93
|
return;
|
|
91
94
|
}
|
|
92
|
-
if (event.key === 'ArrowRight' && !isPlusButtonDisabled) {
|
|
93
|
-
(_a = plusButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
94
|
-
}
|
|
95
|
-
if (event.key === 'ArrowLeft' && !isMinusButtonDisabled) {
|
|
96
|
-
(_b = minusButtonRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
97
|
-
}
|
|
98
95
|
};
|
|
99
96
|
const handleMinusButtonClick = (e) => {
|
|
100
97
|
e.preventDefault();
|
|
@@ -106,25 +103,18 @@ export const FieldStepper = forwardRef((_a, ref) => {
|
|
|
106
103
|
e.stopPropagation();
|
|
107
104
|
setValue(Math.max(Math.min(max, value + step), min));
|
|
108
105
|
};
|
|
109
|
-
const handleMinusButtonKeyDown =
|
|
110
|
-
var _a;
|
|
106
|
+
const handleMinusButtonKeyDown = () => {
|
|
111
107
|
if (readonly || disabled) {
|
|
112
108
|
return;
|
|
113
109
|
}
|
|
114
|
-
if (event.key === 'ArrowRight') {
|
|
115
|
-
event.preventDefault();
|
|
116
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
117
|
-
}
|
|
118
110
|
};
|
|
119
|
-
const handlePlusButtonKeyDown =
|
|
120
|
-
var _a;
|
|
111
|
+
const handlePlusButtonKeyDown = () => {
|
|
121
112
|
if (readonly || disabled) {
|
|
122
113
|
return;
|
|
123
114
|
}
|
|
124
|
-
if (event.key === 'ArrowLeft') {
|
|
125
|
-
event.preventDefault();
|
|
126
|
-
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
127
|
-
}
|
|
128
115
|
};
|
|
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:
|
|
116
|
+
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', triggerClassName: styles.trigger, children: _jsx(FieldContainerPrivate, { size: size, validationState: fieldValidationState, disabled: disabled, readonly: readonly, variant: CONTAINER_VARIANT.SingleLine, inputRef: inputRef, prefix: _jsx(ButtonFunction, { tabIndex: -1, size: 'xs', className: styles.button, icon: _jsx(MinusSVG, {}), onClick: handleMinusButtonClick, onKeyDown: handleMinusButtonKeyDown, disabled: isMinusButtonDisabled, "data-test-id": 'field-stepper__minus-button' }), postfix: _jsx(ButtonFunction, { tabIndex: -1, size: 'xs', className: styles.button, icon: _jsx(PlusSVG, {}), onClick: handlePlusButtonClick, onKeyDown: handlePlusButtonKeyDown, disabled: isPlusButtonDisabled, "data-test-id": 'field-stepper__plus-button' }), children: _jsxs("div", { className: styles.wrap, children: [_jsx("div", { className: cn({ [styles.prefixWrapper]: prefixSettings.show }), children: prefixSettings.show && prefixSettings.render({ key: prefixSettings.id }) }), _jsx("div", { style: {
|
|
117
|
+
width: String(value).length * SymbolWidth[size],
|
|
118
|
+
maxWidth: '100%',
|
|
119
|
+
}, 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, step: step, name: name, min: min, max: max, "data-test-id": 'field-stepper__input' }) }), _jsx("div", { className: cn({ [styles.postfixWrapper]: postfixSettings.show }), children: postfixSettings.show && postfixSettings.render({ key: postfixSettings.id }) })] }) }) }) })));
|
|
130
120
|
});
|
|
@@ -7,4 +7,23 @@
|
|
|
7
7
|
}
|
|
8
8
|
.button[data-disabled] *{
|
|
9
9
|
cursor:not-allowed;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.trigger{
|
|
13
|
+
min-width:auto;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.wrap{
|
|
17
|
+
overflow:hidden;
|
|
18
|
+
display:flex;
|
|
19
|
+
justify-content:center;
|
|
20
|
+
max-width:100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.prefixWrapper{
|
|
24
|
+
margin-right:var(--space-fields-stepper-content-container, 4px);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.postfixWrapper{
|
|
28
|
+
margin-left:var(--space-fields-stepper-content-container, 4px);
|
|
10
29
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Fields",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.35.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"scripts": {},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@snack-uikit/button": "0.19.3",
|
|
40
|
-
"@snack-uikit/calendar": "0.11.
|
|
41
|
-
"@snack-uikit/color-picker": "0.3.
|
|
40
|
+
"@snack-uikit/calendar": "0.11.7",
|
|
41
|
+
"@snack-uikit/color-picker": "0.3.4",
|
|
42
42
|
"@snack-uikit/divider": "3.2.1",
|
|
43
43
|
"@snack-uikit/dropdown": "0.4.1",
|
|
44
44
|
"@snack-uikit/icons": "0.24.0",
|
|
45
|
-
"@snack-uikit/input-private": "4.
|
|
46
|
-
"@snack-uikit/list": "0.21.
|
|
45
|
+
"@snack-uikit/input-private": "4.3.0",
|
|
46
|
+
"@snack-uikit/list": "0.21.7",
|
|
47
47
|
"@snack-uikit/scroll": "0.9.1",
|
|
48
48
|
"@snack-uikit/skeleton": "0.5.1",
|
|
49
49
|
"@snack-uikit/slider": "0.3.2",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@snack-uikit/locale": "*"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "dd1825421e5d0964966e39a20bc5e09258acc3c2"
|
|
69
69
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
1
2
|
import mergeRefs from 'merge-refs';
|
|
2
3
|
import {
|
|
3
4
|
ChangeEvent,
|
|
@@ -76,6 +77,12 @@ const getDefaultValue = (min: number, max: number) => {
|
|
|
76
77
|
return 0;
|
|
77
78
|
};
|
|
78
79
|
|
|
80
|
+
const SymbolWidth = {
|
|
81
|
+
s: 8,
|
|
82
|
+
m: 9,
|
|
83
|
+
l: 10,
|
|
84
|
+
};
|
|
85
|
+
|
|
79
86
|
export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
80
87
|
(
|
|
81
88
|
{
|
|
@@ -118,8 +125,7 @@ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
|
118
125
|
const [tooltip, setTooltip] = useState('');
|
|
119
126
|
const timerRef = useRef<ReturnType<typeof setTimeout>>();
|
|
120
127
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
121
|
-
|
|
122
|
-
const plusButtonRef = useRef<HTMLButtonElement>(null);
|
|
128
|
+
|
|
123
129
|
const isMinusButtonDisabled = (typeof min === 'number' && value <= min) || readonly || disabled;
|
|
124
130
|
const isPlusButtonDisabled = (typeof max === 'number' && value >= max) || readonly || disabled;
|
|
125
131
|
|
|
@@ -171,18 +177,10 @@ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
|
171
177
|
|
|
172
178
|
const handleInputChange = (value: string, event: ChangeEvent<HTMLInputElement>) => setValue(Number(value), event);
|
|
173
179
|
|
|
174
|
-
const handleInputKeyDown: KeyboardEventHandler<HTMLInputElement> =
|
|
180
|
+
const handleInputKeyDown: KeyboardEventHandler<HTMLInputElement> = () => {
|
|
175
181
|
if (readonly || disabled) {
|
|
176
182
|
return;
|
|
177
183
|
}
|
|
178
|
-
|
|
179
|
-
if (event.key === 'ArrowRight' && !isPlusButtonDisabled) {
|
|
180
|
-
plusButtonRef.current?.focus();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (event.key === 'ArrowLeft' && !isMinusButtonDisabled) {
|
|
184
|
-
minusButtonRef.current?.focus();
|
|
185
|
-
}
|
|
186
184
|
};
|
|
187
185
|
|
|
188
186
|
const handleMinusButtonClick = (e: MouseEvent) => {
|
|
@@ -197,26 +195,16 @@ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
|
197
195
|
setValue(Math.max(Math.min(max, value + step), min));
|
|
198
196
|
};
|
|
199
197
|
|
|
200
|
-
const handleMinusButtonKeyDown: KeyboardEventHandler<HTMLInputElement> =
|
|
198
|
+
const handleMinusButtonKeyDown: KeyboardEventHandler<HTMLInputElement> = () => {
|
|
201
199
|
if (readonly || disabled) {
|
|
202
200
|
return;
|
|
203
201
|
}
|
|
204
|
-
|
|
205
|
-
if (event.key === 'ArrowRight') {
|
|
206
|
-
event.preventDefault();
|
|
207
|
-
inputRef.current?.focus();
|
|
208
|
-
}
|
|
209
202
|
};
|
|
210
203
|
|
|
211
|
-
const handlePlusButtonKeyDown: KeyboardEventHandler<HTMLInputElement> =
|
|
204
|
+
const handlePlusButtonKeyDown: KeyboardEventHandler<HTMLInputElement> = () => {
|
|
212
205
|
if (readonly || disabled) {
|
|
213
206
|
return;
|
|
214
207
|
}
|
|
215
|
-
|
|
216
|
-
if (event.key === 'ArrowLeft') {
|
|
217
|
-
event.preventDefault();
|
|
218
|
-
inputRef.current?.focus();
|
|
219
|
-
}
|
|
220
208
|
};
|
|
221
209
|
|
|
222
210
|
return (
|
|
@@ -241,6 +229,7 @@ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
|
241
229
|
tip={tooltip}
|
|
242
230
|
open={allowMoreThanLimits ? false : tooltipOpen}
|
|
243
231
|
data-test-id='field-stepper__limit-tooltip'
|
|
232
|
+
triggerClassName={styles.trigger}
|
|
244
233
|
>
|
|
245
234
|
<FieldContainerPrivate
|
|
246
235
|
size={size}
|
|
@@ -250,58 +239,66 @@ export const FieldStepper = forwardRef<HTMLInputElement, FieldStepperProps>(
|
|
|
250
239
|
variant={CONTAINER_VARIANT.SingleLine}
|
|
251
240
|
inputRef={inputRef}
|
|
252
241
|
prefix={
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
data-test-id='field-stepper__minus-button'
|
|
264
|
-
/>
|
|
265
|
-
{prefixSettings.show && prefixSettings.render({ key: prefixSettings.id })}
|
|
266
|
-
</>
|
|
242
|
+
<ButtonFunction
|
|
243
|
+
tabIndex={-1}
|
|
244
|
+
size='xs'
|
|
245
|
+
className={styles.button}
|
|
246
|
+
icon={<MinusSVG />}
|
|
247
|
+
onClick={handleMinusButtonClick}
|
|
248
|
+
onKeyDown={handleMinusButtonKeyDown}
|
|
249
|
+
disabled={isMinusButtonDisabled}
|
|
250
|
+
data-test-id='field-stepper__minus-button'
|
|
251
|
+
/>
|
|
267
252
|
}
|
|
268
253
|
postfix={
|
|
269
|
-
|
|
270
|
-
{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
onKeyDown={handlePlusButtonKeyDown}
|
|
280
|
-
disabled={isPlusButtonDisabled}
|
|
281
|
-
data-test-id='field-stepper__plus-button'
|
|
282
|
-
/>
|
|
283
|
-
</>
|
|
254
|
+
<ButtonFunction
|
|
255
|
+
tabIndex={-1}
|
|
256
|
+
size='xs'
|
|
257
|
+
className={styles.button}
|
|
258
|
+
icon={<PlusSVG />}
|
|
259
|
+
onClick={handlePlusButtonClick}
|
|
260
|
+
onKeyDown={handlePlusButtonKeyDown}
|
|
261
|
+
disabled={isPlusButtonDisabled}
|
|
262
|
+
data-test-id='field-stepper__plus-button'
|
|
263
|
+
/>
|
|
284
264
|
}
|
|
285
265
|
>
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
266
|
+
<div className={styles.wrap}>
|
|
267
|
+
<div className={cn({ [styles.prefixWrapper]: prefixSettings.show })}>
|
|
268
|
+
{prefixSettings.show && prefixSettings.render({ key: prefixSettings.id })}
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<div
|
|
272
|
+
style={{
|
|
273
|
+
width: String(value).length * SymbolWidth[size],
|
|
274
|
+
maxWidth: '100%',
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<InputPrivate
|
|
278
|
+
ref={mergeRefs(ref, inputRef)}
|
|
279
|
+
className={styles.stepper}
|
|
280
|
+
data-size={size}
|
|
281
|
+
value={String(value)}
|
|
282
|
+
tabIndex={0}
|
|
283
|
+
onKeyDown={handleInputKeyDown}
|
|
284
|
+
onChange={handleInputChange}
|
|
285
|
+
onBlur={handleInputBlur}
|
|
286
|
+
onFocus={handleInputFocus}
|
|
287
|
+
disabled={disabled}
|
|
288
|
+
readonly={readonly}
|
|
289
|
+
type='number'
|
|
290
|
+
id={id}
|
|
291
|
+
step={step}
|
|
292
|
+
name={name}
|
|
293
|
+
min={min}
|
|
294
|
+
max={max}
|
|
295
|
+
data-test-id='field-stepper__input'
|
|
296
|
+
/>
|
|
297
|
+
</div>
|
|
298
|
+
<div className={cn({ [styles.postfixWrapper]: postfixSettings.show })}>
|
|
299
|
+
{postfixSettings.show && postfixSettings.render({ key: postfixSettings.id })}
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
305
302
|
</FieldContainerPrivate>
|
|
306
303
|
</Tooltip>
|
|
307
304
|
</FieldDecorator>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-fields' as ft-fields;
|
|
2
|
+
|
|
1
3
|
.stepper {
|
|
2
4
|
text-align: center;
|
|
3
5
|
}
|
|
@@ -10,4 +12,23 @@
|
|
|
10
12
|
&[data-disabled] * {
|
|
11
13
|
cursor: not-allowed;
|
|
12
14
|
}
|
|
13
|
-
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.trigger {
|
|
18
|
+
min-width: auto;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.wrap {
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
display: flex;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.prefixWrapper {
|
|
29
|
+
margin-right: ft-fields.$space-fields-stepper-content-container;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.postfixWrapper {
|
|
33
|
+
margin-left: ft-fields.$space-fields-stepper-content-container;
|
|
34
|
+
}
|