@instructure/ui-number-input 10.2.2-snapshot-17 → 10.2.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 +1 -1
- package/package.json +14 -14
- package/src/NumberInput/README.md +230 -94
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
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
|
-
## [10.2.2
|
|
6
|
+
## [10.2.2](https://github.com/instructure/instructure-ui/compare/v10.2.1...v10.2.2) (2024-09-13)
|
|
7
7
|
|
|
8
8
|
**Note:** Version bump only for package @instructure/ui-number-input
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-number-input",
|
|
3
|
-
"version": "10.2.2
|
|
3
|
+
"version": "10.2.2",
|
|
4
4
|
"description": "A UI component library made by Instructure Inc.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"homepage": "https://instructure.github.io/instructure-ui/",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"ts:check": "tsc -p tsconfig.build.json --noEmit --emitDeclarationOnly false"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-axe-check": "10.2.2
|
|
27
|
-
"@instructure/ui-babel-preset": "10.2.2
|
|
28
|
-
"@instructure/ui-scripts": "10.2.2
|
|
29
|
-
"@instructure/ui-test-utils": "10.2.2
|
|
30
|
-
"@instructure/ui-themes": "10.2.2
|
|
26
|
+
"@instructure/ui-axe-check": "10.2.2",
|
|
27
|
+
"@instructure/ui-babel-preset": "10.2.2",
|
|
28
|
+
"@instructure/ui-scripts": "10.2.2",
|
|
29
|
+
"@instructure/ui-test-utils": "10.2.2",
|
|
30
|
+
"@instructure/ui-themes": "10.2.2",
|
|
31
31
|
"@testing-library/jest-dom": "^6.4.6",
|
|
32
32
|
"@testing-library/react": "^15.0.7",
|
|
33
33
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@babel/runtime": "^7.24.5",
|
|
38
|
-
"@instructure/emotion": "10.2.2
|
|
39
|
-
"@instructure/shared-types": "10.2.2
|
|
40
|
-
"@instructure/ui-form-field": "10.2.2
|
|
41
|
-
"@instructure/ui-icons": "10.2.2
|
|
42
|
-
"@instructure/ui-react-utils": "10.2.2
|
|
43
|
-
"@instructure/ui-testable": "10.2.2
|
|
44
|
-
"@instructure/ui-utils": "10.2.2
|
|
45
|
-
"@instructure/uid": "10.2.2
|
|
38
|
+
"@instructure/emotion": "10.2.2",
|
|
39
|
+
"@instructure/shared-types": "10.2.2",
|
|
40
|
+
"@instructure/ui-form-field": "10.2.2",
|
|
41
|
+
"@instructure/ui-icons": "10.2.2",
|
|
42
|
+
"@instructure/ui-react-utils": "10.2.2",
|
|
43
|
+
"@instructure/ui-testable": "10.2.2",
|
|
44
|
+
"@instructure/ui-utils": "10.2.2",
|
|
45
|
+
"@instructure/uid": "10.2.2",
|
|
46
46
|
"keycode": "^2",
|
|
47
47
|
"prop-types": "^15.8.1"
|
|
48
48
|
},
|
|
@@ -10,137 +10,273 @@ This example handles arrow buttons, up/down arrow keys, and typing into
|
|
|
10
10
|
the input. It also includes an `onBlur` handler that displays an error message
|
|
11
11
|
if the input is invalid or missing.
|
|
12
12
|
|
|
13
|
-
```js
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Example extends React.Component {
|
|
18
|
-
MIN = 0
|
|
19
|
-
MAX = 999
|
|
20
|
-
|
|
21
|
-
state = {
|
|
22
|
-
disabled: false,
|
|
23
|
-
inline: false,
|
|
24
|
-
messages: null,
|
|
25
|
-
number: null,
|
|
26
|
-
readOnly: false,
|
|
27
|
-
showArrows: true,
|
|
28
|
-
value: ''
|
|
29
|
-
}
|
|
13
|
+
- ```js
|
|
14
|
+
class Example extends React.Component {
|
|
15
|
+
MIN = 0
|
|
16
|
+
MAX = 999
|
|
30
17
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
value
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
handleDecrement = (event) => this.setState(({ number }) => {
|
|
38
|
-
if (isNaN(number)) return
|
|
39
|
-
if (number === null) return this.setNumber(this.MIN)
|
|
40
|
-
if (isInteger(number)) return this.setNumber(number - 1)
|
|
41
|
-
return this.setNumber(Math.floor(number))
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
handleIncrement = (event) => this.setState(({ number }) => {
|
|
45
|
-
if (isNaN(number)) return
|
|
46
|
-
if (number === null) return this.setNumber(this.MIN + 1)
|
|
47
|
-
if (isInteger(number)) return this.setNumber(number + 1)
|
|
48
|
-
return this.setNumber(Math.ceil(number))
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
handleBlur = (event) => this.setState(({ number, value }) => {
|
|
52
|
-
if (isNaN(number)) return this.invalidNumber(value)
|
|
53
|
-
if (number === null) return this.required()
|
|
54
|
-
return this.setNumber(Math.round(number))
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
setNumber (n) {
|
|
58
|
-
const number = this.bound(n)
|
|
59
|
-
return {
|
|
18
|
+
state = {
|
|
19
|
+
disabled: false,
|
|
20
|
+
inline: false,
|
|
60
21
|
messages: null,
|
|
61
|
-
number,
|
|
62
|
-
|
|
22
|
+
number: null,
|
|
23
|
+
readOnly: false,
|
|
24
|
+
showArrows: true,
|
|
25
|
+
value: ''
|
|
63
26
|
}
|
|
64
|
-
}
|
|
65
27
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
28
|
+
handleChange = (event, value) =>
|
|
29
|
+
this.setState({
|
|
30
|
+
messages: null,
|
|
31
|
+
number: value ? Number(value) : null,
|
|
32
|
+
value
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
handleDecrement = (event) =>
|
|
36
|
+
this.setState(({ number }) => {
|
|
37
|
+
if (isNaN(number)) return
|
|
38
|
+
if (number === null) return this.setNumber(this.MIN)
|
|
39
|
+
if (Number.isInteger(number)) return this.setNumber(number - 1)
|
|
40
|
+
return this.setNumber(Math.floor(number))
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
handleIncrement = (event) =>
|
|
44
|
+
this.setState(({ number }) => {
|
|
45
|
+
if (isNaN(number)) return
|
|
46
|
+
if (number === null) return this.setNumber(this.MIN + 1)
|
|
47
|
+
if (Number.isInteger(number)) return this.setNumber(number + 1)
|
|
48
|
+
return this.setNumber(Math.ceil(number))
|
|
49
|
+
})
|
|
71
50
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
51
|
+
handleBlur = (event) =>
|
|
52
|
+
this.setState(({ number, value }) => {
|
|
53
|
+
if (isNaN(number)) return this.invalidNumber(value)
|
|
54
|
+
if (number === null) return this.required()
|
|
55
|
+
return this.setNumber(Math.round(number))
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
setNumber(n) {
|
|
59
|
+
const number = this.bound(n)
|
|
60
|
+
return {
|
|
61
|
+
messages: null,
|
|
62
|
+
number,
|
|
63
|
+
value: number
|
|
64
|
+
}
|
|
75
65
|
}
|
|
76
|
-
}
|
|
77
66
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
67
|
+
bound(n) {
|
|
68
|
+
if (n < this.MIN) return this.MIN
|
|
69
|
+
if (n > this.MAX) return this.MAX
|
|
70
|
+
return n
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
invalidNumber(value) {
|
|
74
|
+
return {
|
|
75
|
+
messages: [{ text: `'${value}' is not a valid number.`, type: 'error' }]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
required() {
|
|
80
|
+
return {
|
|
81
|
+
messages: [{ text: 'This is required.', type: 'error' }]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
toggleDisabled = (event) =>
|
|
86
|
+
this.setState(({ disabled }) => ({ disabled: !disabled }))
|
|
87
|
+
|
|
88
|
+
toggleInline = (event) =>
|
|
89
|
+
this.setState(({ inline }) => ({ inline: !inline }))
|
|
90
|
+
|
|
91
|
+
toggleReadOnly = (event) =>
|
|
92
|
+
this.setState(({ readOnly }) => ({ readOnly: !readOnly }))
|
|
93
|
+
|
|
94
|
+
toggleShowArrows = (event) =>
|
|
95
|
+
this.setState(({ showArrows }) => ({ showArrows: !showArrows }))
|
|
96
|
+
|
|
97
|
+
render() {
|
|
98
|
+
return (
|
|
99
|
+
<FormFieldGroup description="Controlled NumberInput example">
|
|
100
|
+
<Checkbox
|
|
101
|
+
checked={this.state.showArrows}
|
|
102
|
+
label="Show arrows"
|
|
103
|
+
onChange={this.toggleShowArrows}
|
|
104
|
+
/>
|
|
105
|
+
<Checkbox
|
|
106
|
+
checked={this.state.disabled}
|
|
107
|
+
label="Disabled"
|
|
108
|
+
onChange={this.toggleDisabled}
|
|
109
|
+
/>
|
|
110
|
+
<Checkbox
|
|
111
|
+
checked={this.state.readOnly}
|
|
112
|
+
label="Read only"
|
|
113
|
+
onChange={this.toggleReadOnly}
|
|
114
|
+
/>
|
|
115
|
+
<Checkbox
|
|
116
|
+
checked={this.state.inline}
|
|
117
|
+
label="Inline display"
|
|
118
|
+
onChange={this.toggleInline}
|
|
119
|
+
/>
|
|
120
|
+
<NumberInput
|
|
121
|
+
renderLabel={`How old are you? (${this.MIN}-${this.MAX})`}
|
|
122
|
+
display={this.state.inline ? 'inline-block' : null}
|
|
123
|
+
messages={this.state.messages}
|
|
124
|
+
onBlur={this.handleBlur}
|
|
125
|
+
onChange={this.handleChange}
|
|
126
|
+
onDecrement={this.handleDecrement}
|
|
127
|
+
onIncrement={this.handleIncrement}
|
|
128
|
+
placeholder="Age (in years)"
|
|
129
|
+
interaction={
|
|
130
|
+
this.state.disabled
|
|
131
|
+
? 'disabled'
|
|
132
|
+
: this.state.readOnly
|
|
133
|
+
? 'readonly'
|
|
134
|
+
: 'enabled'
|
|
135
|
+
}
|
|
136
|
+
isRequired
|
|
137
|
+
showArrows={this.state.showArrows}
|
|
138
|
+
value={this.state.value}
|
|
139
|
+
/>
|
|
140
|
+
</FormFieldGroup>
|
|
141
|
+
)
|
|
81
142
|
}
|
|
82
143
|
}
|
|
83
144
|
|
|
84
|
-
|
|
145
|
+
render(<Example />)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
- ```js
|
|
149
|
+
const Example = () => {
|
|
150
|
+
const MIN = 0
|
|
151
|
+
const MAX = 999
|
|
152
|
+
|
|
153
|
+
const [disabled, setDisabled] = useState(false)
|
|
154
|
+
const [inline, setInline] = useState(false)
|
|
155
|
+
const [messages, setMessages] = useState(null)
|
|
156
|
+
const [number, setNumber] = useState(null)
|
|
157
|
+
const [readOnly, setReadOnly] = useState(false)
|
|
158
|
+
const [showArrows, setShowArrows] = useState(true)
|
|
159
|
+
const [value, setValue] = useState('')
|
|
85
160
|
|
|
86
|
-
|
|
161
|
+
const handleChange = (event, value) => {
|
|
162
|
+
setMessages(null)
|
|
163
|
+
setNumber(value ? Number(value) : null)
|
|
164
|
+
setValue(value)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const handleDecrement = (event) => {
|
|
168
|
+
if (!isNaN(number)) {
|
|
169
|
+
const newNumber =
|
|
170
|
+
number === null
|
|
171
|
+
? MIN
|
|
172
|
+
: Number.isInteger(number)
|
|
173
|
+
? number - 1
|
|
174
|
+
: Math.floor(number)
|
|
175
|
+
updateNumber(newNumber)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const handleIncrement = (event) => {
|
|
180
|
+
if (!isNaN(number)) {
|
|
181
|
+
const newNumber =
|
|
182
|
+
number === null
|
|
183
|
+
? MIN + 1
|
|
184
|
+
: Number.isInteger(number)
|
|
185
|
+
? number + 1
|
|
186
|
+
: Math.ceil(number)
|
|
187
|
+
updateNumber(newNumber)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const handleBlur = (event) => {
|
|
192
|
+
if (isNaN(number)) return invalidNumber(value)
|
|
193
|
+
if (number === null) return required()
|
|
194
|
+
return updateNumber(Math.round(number))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const updateNumber = (n) => {
|
|
198
|
+
const number = bound(n)
|
|
199
|
+
setMessages(null)
|
|
200
|
+
setNumber(number)
|
|
201
|
+
setValue(number)
|
|
202
|
+
}
|
|
87
203
|
|
|
88
|
-
|
|
204
|
+
const bound = (n) => {
|
|
205
|
+
if (n < MIN) return MIN
|
|
206
|
+
if (n > MAX) return MAX
|
|
207
|
+
return n
|
|
208
|
+
}
|
|
89
209
|
|
|
90
|
-
|
|
210
|
+
const invalidNumber = (value) => {
|
|
211
|
+
setMessages([
|
|
212
|
+
{ text: `'${value}' is not a valid number.`, type: 'error' }
|
|
213
|
+
])
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const required = () => {
|
|
217
|
+
setMessages([{ text: 'This is required.', type: 'error' }])
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const toggleDisabled = (event) => {
|
|
221
|
+
setDisabled((prevDisabled) => !prevDisabled)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const toggleInline = (event) => {
|
|
225
|
+
setInline((prevInline) => !prevInline)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const toggleReadOnly = (event) => {
|
|
229
|
+
setReadOnly((prevReadOnly) => !prevReadOnly)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const toggleShowArrows = (event) => {
|
|
233
|
+
setShowArrows((prevShowArrows) => !prevShowArrows)
|
|
234
|
+
}
|
|
91
235
|
|
|
92
|
-
render () {
|
|
93
236
|
return (
|
|
94
237
|
<FormFieldGroup description="Controlled NumberInput example">
|
|
95
238
|
<Checkbox
|
|
96
|
-
checked={
|
|
239
|
+
checked={showArrows}
|
|
97
240
|
label="Show arrows"
|
|
98
|
-
onChange={
|
|
241
|
+
onChange={toggleShowArrows}
|
|
99
242
|
/>
|
|
100
243
|
<Checkbox
|
|
101
|
-
checked={
|
|
244
|
+
checked={disabled}
|
|
102
245
|
label="Disabled"
|
|
103
|
-
onChange={
|
|
246
|
+
onChange={toggleDisabled}
|
|
104
247
|
/>
|
|
105
248
|
<Checkbox
|
|
106
|
-
checked={
|
|
249
|
+
checked={readOnly}
|
|
107
250
|
label="Read only"
|
|
108
|
-
onChange={
|
|
251
|
+
onChange={toggleReadOnly}
|
|
109
252
|
/>
|
|
110
253
|
<Checkbox
|
|
111
|
-
checked={
|
|
254
|
+
checked={inline}
|
|
112
255
|
label="Inline display"
|
|
113
|
-
onChange={
|
|
256
|
+
onChange={toggleInline}
|
|
114
257
|
/>
|
|
115
258
|
<NumberInput
|
|
116
|
-
renderLabel={`How old are you? (${
|
|
117
|
-
display={
|
|
118
|
-
messages={
|
|
119
|
-
onBlur={
|
|
120
|
-
onChange={
|
|
121
|
-
onDecrement={
|
|
122
|
-
onIncrement={
|
|
259
|
+
renderLabel={`How old are you? (${MIN}-${MAX})`}
|
|
260
|
+
display={inline ? 'inline-block' : null}
|
|
261
|
+
messages={messages}
|
|
262
|
+
onBlur={handleBlur}
|
|
263
|
+
onChange={handleChange}
|
|
264
|
+
onDecrement={handleDecrement}
|
|
265
|
+
onIncrement={handleIncrement}
|
|
123
266
|
placeholder="Age (in years)"
|
|
124
|
-
interaction={
|
|
125
|
-
? 'disabled'
|
|
126
|
-
: this.state.readOnly ? 'readonly' : 'enabled'
|
|
267
|
+
interaction={
|
|
268
|
+
disabled ? 'disabled' : readOnly ? 'readonly' : 'enabled'
|
|
127
269
|
}
|
|
128
270
|
isRequired
|
|
129
|
-
showArrows={
|
|
130
|
-
value={
|
|
271
|
+
showArrows={showArrows}
|
|
272
|
+
value={value}
|
|
131
273
|
/>
|
|
132
274
|
</FormFieldGroup>
|
|
133
275
|
)
|
|
134
276
|
}
|
|
135
|
-
}
|
|
136
277
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return Math.floor(number) === number
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
render(<Example />)
|
|
143
|
-
```
|
|
278
|
+
render(<Example />)
|
|
279
|
+
```
|
|
144
280
|
|
|
145
281
|
> Note: `NumberInput` accepts a string or number as its `value`. However, the value returned by the `onChange` callback is always a string and should be converted to a number before attempting to augment it.
|
|
146
282
|
|