@spaced-out/ui-design-system 0.1.121 → 0.1.122
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 +8 -0
- package/lib/components/Input/Input.js +4 -2
- package/lib/components/Input/Input.js.flow +12 -4
- package/lib/components/Input/Input.module.css +12 -0
- package/lib/components/RangeSlider/RangeSlider.js +43 -4
- package/lib/components/RangeSlider/RangeSlider.js.flow +61 -3
- package/lib/components/RangeSlider/RangeSlider.module.css +19 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.1.122](https://github.com/spaced-out/ui-design-system/compare/v0.1.121...v0.1.122) (2024-08-22)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* ↕️ added option to hide spinner for number input, exposes wrapper classname for input ([05267ee](https://github.com/spaced-out/ui-design-system/commit/05267eeef9dd984d5e6d6030f778ed197d518cf0))
|
|
11
|
+
* 🛝 slider enhancements to add value input in the right slot, min max range indicators as config ([eecd31a](https://github.com/spaced-out/ui-design-system/commit/eecd31ae53dd460f08d7c31ea648d0aa20d3ca1d))
|
|
12
|
+
|
|
5
13
|
### [0.1.121](https://github.com/spaced-out/ui-design-system/compare/v0.1.120...v0.1.121) (2024-08-20)
|
|
6
14
|
|
|
7
15
|
|
|
@@ -59,6 +59,7 @@ const Input_ = (props, ref) => {
|
|
|
59
59
|
boxRef,
|
|
60
60
|
onKeyDown,
|
|
61
61
|
disallowExponents,
|
|
62
|
+
hideNumberSpinner,
|
|
62
63
|
...inputProps
|
|
63
64
|
} = props;
|
|
64
65
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
@@ -84,7 +85,7 @@ const Input_ = (props, ref) => {
|
|
|
84
85
|
className: (0, _classify.classify)(_InputModule.default.wrapper, {
|
|
85
86
|
[_InputModule.default.filled]: controlledInputFilled ?? false,
|
|
86
87
|
[_InputModule.default.withError]: error ?? false
|
|
87
|
-
})
|
|
88
|
+
}, classNames?.wrapper)
|
|
88
89
|
}, Boolean(label) && /*#__PURE__*/React.createElement("div", {
|
|
89
90
|
className: _InputModule.default.info
|
|
90
91
|
}, /*#__PURE__*/React.createElement("div", {
|
|
@@ -99,7 +100,8 @@ const Input_ = (props, ref) => {
|
|
|
99
100
|
[_InputModule.default.medium]: size === 'medium',
|
|
100
101
|
[_InputModule.default.small]: size === 'small',
|
|
101
102
|
[_InputModule.default.locked]: locked,
|
|
102
|
-
[_InputModule.default.color]: type === 'color'
|
|
103
|
+
[_InputModule.default.color]: type === 'color',
|
|
104
|
+
[_InputModule.default.hideNumberSpinner]: hideNumberSpinner
|
|
103
105
|
}, classNames?.box),
|
|
104
106
|
onClick: !(disabled || locked) ? onContainerClick : null,
|
|
105
107
|
ref: boxRef
|
|
@@ -13,6 +13,7 @@ type ClassNames = $ReadOnly<{
|
|
|
13
13
|
box?: string,
|
|
14
14
|
iconLeft?: string,
|
|
15
15
|
iconRight?: string,
|
|
16
|
+
wrapper?: string,
|
|
16
17
|
}>;
|
|
17
18
|
|
|
18
19
|
export const EXPONENT_CHARACTER_LIST = ['E', 'e'];
|
|
@@ -80,6 +81,7 @@ export type InputProps = {
|
|
|
80
81
|
* Only values which are equal to the basis for stepping (min if specified, value otherwise, and an
|
|
81
82
|
* appropriate default value if neither of those is provided) are valid. */
|
|
82
83
|
step?: string,
|
|
84
|
+
hideNumberSpinner?: boolean,
|
|
83
85
|
...
|
|
84
86
|
};
|
|
85
87
|
|
|
@@ -111,6 +113,7 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
111
113
|
boxRef,
|
|
112
114
|
onKeyDown,
|
|
113
115
|
disallowExponents,
|
|
116
|
+
hideNumberSpinner,
|
|
114
117
|
...inputProps
|
|
115
118
|
} = props;
|
|
116
119
|
|
|
@@ -142,10 +145,14 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
142
145
|
|
|
143
146
|
return (
|
|
144
147
|
<div
|
|
145
|
-
className={classify(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
className={classify(
|
|
149
|
+
css.wrapper,
|
|
150
|
+
{
|
|
151
|
+
[css.filled]: controlledInputFilled ?? false,
|
|
152
|
+
[css.withError]: error ?? false,
|
|
153
|
+
},
|
|
154
|
+
classNames?.wrapper,
|
|
155
|
+
)}
|
|
149
156
|
>
|
|
150
157
|
{Boolean(label) && (
|
|
151
158
|
<div className={css.info}>
|
|
@@ -165,6 +172,7 @@ const Input_ = (props: InputProps, ref): React.Node => {
|
|
|
165
172
|
[css.small]: size === 'small',
|
|
166
173
|
[css.locked]: locked,
|
|
167
174
|
[css.color]: type === 'color',
|
|
175
|
+
[css.hideNumberSpinner]: hideNumberSpinner,
|
|
168
176
|
},
|
|
169
177
|
classNames?.box,
|
|
170
178
|
)}
|
|
@@ -172,3 +172,15 @@ input::placeholder {
|
|
|
172
172
|
min-height: size18;
|
|
173
173
|
border-radius: borderRadiusXSmall;
|
|
174
174
|
}
|
|
175
|
+
|
|
176
|
+
.hideNumberSpinner input[type='number']::-webkit-outer-spin-button,
|
|
177
|
+
.hideNumberSpinner input[type='number']::-webkit-inner-spin-button {
|
|
178
|
+
-webkit-appearance: none;
|
|
179
|
+
margin: 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Hide spinner in Firefox */
|
|
183
|
+
.hideNumberSpinner input[type='number'] {
|
|
184
|
+
appearance: textfield;
|
|
185
|
+
-moz-appearance: textfield;
|
|
186
|
+
}
|
|
@@ -8,6 +8,8 @@ var React = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _color = require("../../styles/variables/_color");
|
|
9
9
|
var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
10
10
|
var _Button = require("../Button");
|
|
11
|
+
var _Input = require("../Input");
|
|
12
|
+
var _Text = require("../Text");
|
|
11
13
|
var _RangeSliderModule = _interopRequireDefault(require("./RangeSlider.module.css"));
|
|
12
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
15
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
@@ -30,12 +32,29 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
30
32
|
hideLeftBtn,
|
|
31
33
|
hideRightBtn,
|
|
32
34
|
ariaLabel = 'Slider',
|
|
35
|
+
showRange,
|
|
36
|
+
hideValueInput,
|
|
33
37
|
...restInputProps
|
|
34
38
|
} = _ref;
|
|
35
39
|
const progress = (value - min) / (max - min) * 100;
|
|
36
40
|
const btnLeftDisabled = disabled || value <= min;
|
|
37
41
|
const btnRightDisabled = disabled || value >= max;
|
|
38
42
|
const progressColor = disabled ? _color.colorTextDisabled : _color.colorFillPrimary;
|
|
43
|
+
const handleInputChange = e => {
|
|
44
|
+
let inputValue = parseFloat(e.currentTarget.value);
|
|
45
|
+
|
|
46
|
+
// Validate and adjust the value
|
|
47
|
+
if (isNaN(inputValue) || inputValue < min) {
|
|
48
|
+
inputValue = min;
|
|
49
|
+
} else if (inputValue > max) {
|
|
50
|
+
inputValue = max;
|
|
51
|
+
} else if (step > 0) {
|
|
52
|
+
const nearestStep = Math.round(inputValue / step) * step;
|
|
53
|
+
inputValue = Math.round(nearestStep * 100) / 100; // Adjust to nearest valid step
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onChange?.(inputValue);
|
|
57
|
+
};
|
|
39
58
|
const handleChange = e => {
|
|
40
59
|
emitRoundedValue(e.currentTarget.value);
|
|
41
60
|
};
|
|
@@ -50,14 +69,17 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
50
69
|
className: (0, _classify.default)(_RangeSliderModule.default.wrapper, {
|
|
51
70
|
[_RangeSliderModule.default.disabled]: disabled
|
|
52
71
|
}, classNames?.wrapper)
|
|
53
|
-
}, !hideLeftBtn && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
72
|
+
}, !hideLeftBtn && !showRange && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
54
73
|
type: "ghost",
|
|
55
74
|
iconLeftName: iconLeftName,
|
|
56
75
|
size: btnLeftSize,
|
|
57
76
|
ariaLabel: "Decrease Value",
|
|
58
77
|
disabled: btnLeftDisabled,
|
|
59
78
|
onClick: () => emitRoundedValue(value - step)
|
|
60
|
-
}), /*#__PURE__*/React.createElement(
|
|
79
|
+
}), showRange && /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
80
|
+
className: _RangeSliderModule.default.rangeText,
|
|
81
|
+
color: disabled ? 'disabled' : 'primary'
|
|
82
|
+
}, min), /*#__PURE__*/React.createElement("div", {
|
|
61
83
|
className: _RangeSliderModule.default.sliderContainer
|
|
62
84
|
}, /*#__PURE__*/React.createElement("input", _extends({}, restInputProps, {
|
|
63
85
|
type: "range",
|
|
@@ -80,14 +102,31 @@ const RangeSlider = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
80
102
|
length: (max - min) / step + 1
|
|
81
103
|
}, (_, index) => /*#__PURE__*/React.createElement("option", {
|
|
82
104
|
key: index,
|
|
83
|
-
value: min + index * step
|
|
84
|
-
|
|
105
|
+
value: min + index * step,
|
|
106
|
+
className: (0, _classify.default)({
|
|
107
|
+
[_RangeSliderModule.default.disabled]: disabled
|
|
108
|
+
})
|
|
109
|
+
})))), showRange && /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
110
|
+
className: _RangeSliderModule.default.rangeText,
|
|
111
|
+
color: disabled ? 'disabled' : 'primary'
|
|
112
|
+
}, max), !hideRightBtn && !showRange && /*#__PURE__*/React.createElement(_Button.Button, {
|
|
85
113
|
type: "ghost",
|
|
86
114
|
iconRightName: iconRightName,
|
|
87
115
|
size: btnRightSize,
|
|
88
116
|
ariaLabel: "Increase Value",
|
|
89
117
|
disabled: btnRightDisabled,
|
|
90
118
|
onClick: () => emitRoundedValue(value + step)
|
|
119
|
+
}), !hideValueInput && /*#__PURE__*/React.createElement(_Input.Input, {
|
|
120
|
+
size: "small",
|
|
121
|
+
type: "number",
|
|
122
|
+
value: String(value),
|
|
123
|
+
classNames: {
|
|
124
|
+
wrapper: _RangeSliderModule.default.valueInputWrapper
|
|
125
|
+
},
|
|
126
|
+
disabled: disabled,
|
|
127
|
+
onChange: handleInputChange,
|
|
128
|
+
disallowExponents: true,
|
|
129
|
+
hideNumberSpinner: true
|
|
91
130
|
}));
|
|
92
131
|
});
|
|
93
132
|
exports.RangeSlider = RangeSlider;
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
import classify from '../../utils/classify';
|
|
11
11
|
import type {ButtonSize} from '../Button';
|
|
12
12
|
import {Button, BUTTON_SIZE} from '../Button';
|
|
13
|
+
import {Input} from '../Input';
|
|
14
|
+
import {BodySmall} from '../Text';
|
|
13
15
|
|
|
14
16
|
import css from './RangeSlider.module.css';
|
|
15
17
|
|
|
@@ -32,6 +34,8 @@ export type RangeSliderProps = {
|
|
|
32
34
|
hideRightBtn?: boolean,
|
|
33
35
|
classNames?: ClassNames,
|
|
34
36
|
ariaLabel?: string,
|
|
37
|
+
showRange?: boolean,
|
|
38
|
+
hideValueInput?: boolean,
|
|
35
39
|
...
|
|
36
40
|
};
|
|
37
41
|
|
|
@@ -56,6 +60,8 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
56
60
|
hideLeftBtn,
|
|
57
61
|
hideRightBtn,
|
|
58
62
|
ariaLabel = 'Slider',
|
|
63
|
+
showRange,
|
|
64
|
+
hideValueInput,
|
|
59
65
|
...restInputProps
|
|
60
66
|
}: RangeSliderProps,
|
|
61
67
|
ref,
|
|
@@ -67,6 +73,22 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
67
73
|
|
|
68
74
|
const progressColor = disabled ? colorTextDisabled : colorFillPrimary;
|
|
69
75
|
|
|
76
|
+
const handleInputChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
77
|
+
let inputValue = parseFloat(e.currentTarget.value);
|
|
78
|
+
|
|
79
|
+
// Validate and adjust the value
|
|
80
|
+
if (isNaN(inputValue) || inputValue < min) {
|
|
81
|
+
inputValue = min;
|
|
82
|
+
} else if (inputValue > max) {
|
|
83
|
+
inputValue = max;
|
|
84
|
+
} else if (step > 0) {
|
|
85
|
+
const nearestStep = Math.round(inputValue / step) * step;
|
|
86
|
+
inputValue = Math.round(nearestStep * 100) / 100; // Adjust to nearest valid step
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
onChange?.(inputValue);
|
|
90
|
+
};
|
|
91
|
+
|
|
70
92
|
const handleChange = (e: SyntheticEvent<HTMLInputElement>) => {
|
|
71
93
|
emitRoundedValue(e.currentTarget.value);
|
|
72
94
|
};
|
|
@@ -87,7 +109,7 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
87
109
|
classNames?.wrapper,
|
|
88
110
|
)}
|
|
89
111
|
>
|
|
90
|
-
{!hideLeftBtn && (
|
|
112
|
+
{!hideLeftBtn && !showRange && (
|
|
91
113
|
<Button
|
|
92
114
|
type="ghost"
|
|
93
115
|
iconLeftName={iconLeftName}
|
|
@@ -98,6 +120,15 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
98
120
|
/>
|
|
99
121
|
)}
|
|
100
122
|
|
|
123
|
+
{showRange && (
|
|
124
|
+
<BodySmall
|
|
125
|
+
className={css.rangeText}
|
|
126
|
+
color={disabled ? 'disabled' : 'primary'}
|
|
127
|
+
>
|
|
128
|
+
{min}
|
|
129
|
+
</BodySmall>
|
|
130
|
+
)}
|
|
131
|
+
|
|
101
132
|
<div className={css.sliderContainer}>
|
|
102
133
|
<input
|
|
103
134
|
{...restInputProps}
|
|
@@ -123,12 +154,26 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
123
154
|
by allowing user-defined brackets or ranges for tick marks.
|
|
124
155
|
*/}
|
|
125
156
|
{Array.from({length: (max - min) / step + 1}, (_, index) => (
|
|
126
|
-
<option
|
|
157
|
+
<option
|
|
158
|
+
key={index}
|
|
159
|
+
value={min + index * step}
|
|
160
|
+
className={classify({[css.disabled]: disabled})}
|
|
161
|
+
/>
|
|
127
162
|
))}
|
|
128
163
|
</datalist>
|
|
129
164
|
)}
|
|
130
165
|
</div>
|
|
131
|
-
|
|
166
|
+
|
|
167
|
+
{showRange && (
|
|
168
|
+
<BodySmall
|
|
169
|
+
className={css.rangeText}
|
|
170
|
+
color={disabled ? 'disabled' : 'primary'}
|
|
171
|
+
>
|
|
172
|
+
{max}
|
|
173
|
+
</BodySmall>
|
|
174
|
+
)}
|
|
175
|
+
|
|
176
|
+
{!hideRightBtn && !showRange && (
|
|
132
177
|
<Button
|
|
133
178
|
type="ghost"
|
|
134
179
|
iconRightName={iconRightName}
|
|
@@ -138,6 +183,19 @@ export const RangeSlider: React$AbstractComponent<
|
|
|
138
183
|
onClick={() => emitRoundedValue(value + step)}
|
|
139
184
|
/>
|
|
140
185
|
)}
|
|
186
|
+
|
|
187
|
+
{!hideValueInput && (
|
|
188
|
+
<Input
|
|
189
|
+
size="small"
|
|
190
|
+
type="number"
|
|
191
|
+
value={String(value)}
|
|
192
|
+
classNames={{wrapper: css.valueInputWrapper}}
|
|
193
|
+
disabled={disabled}
|
|
194
|
+
onChange={handleInputChange}
|
|
195
|
+
disallowExponents
|
|
196
|
+
hideNumberSpinner
|
|
197
|
+
/>
|
|
198
|
+
)}
|
|
141
199
|
</div>
|
|
142
200
|
);
|
|
143
201
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
@value (colorFillPrimary, colorGrayLightest, colorBackgroundTertiary, colorFocusPrimary, colorTextDisabled) from '../../styles/variables/_color.css';
|
|
2
|
-
@value (sizeFluid, size4, size20, size2) from '../../styles/variables/_size.css';
|
|
3
|
-
@value (
|
|
2
|
+
@value (sizeFluid, size4, size20, size2, size34) from '../../styles/variables/_size.css';
|
|
3
|
+
@value (spaceXXSmall, spaceNone) from '../../styles/variables/_space.css';
|
|
4
4
|
@value (borderRadiusLarge, borderRadiusCircle, borderWidthTertiary, borderWidthNone) from '../../styles/variables/_border.css';
|
|
5
5
|
|
|
6
6
|
@value thumbSize: size20;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
display: flex;
|
|
11
11
|
align-items: center;
|
|
12
12
|
width: sizeFluid;
|
|
13
|
-
gap:
|
|
13
|
+
gap: spaceXXSmall;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.sliderContainer {
|
|
@@ -119,3 +119,19 @@ input[type='range']:focus::-moz-range-thumb {
|
|
|
119
119
|
padding-inline: spaceNone;
|
|
120
120
|
white-space: nowrap;
|
|
121
121
|
}
|
|
122
|
+
|
|
123
|
+
.sliderTicks option.disabled {
|
|
124
|
+
background-color: colorTextDisabled;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.rangeText {
|
|
128
|
+
display: flex;
|
|
129
|
+
min-width: size34;
|
|
130
|
+
min-height: size34;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
align-items: center;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.valueInputWrapper {
|
|
136
|
+
max-width: 58px;
|
|
137
|
+
}
|