@instructure/ui-number-input 8.13.1-snapshot.48 → 8.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-number-input",
3
- "version": "8.13.1-snapshot.48+4961e7204",
3
+ "version": "8.14.0",
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/",
@@ -24,21 +24,21 @@
24
24
  "ts:check": "tsc -p tsconfig.build.json --noEmit --emitDeclarationOnly false"
25
25
  },
26
26
  "devDependencies": {
27
- "@instructure/ui-babel-preset": "8.13.1-snapshot.48+4961e7204",
28
- "@instructure/ui-test-locator": "8.13.1-snapshot.48+4961e7204",
29
- "@instructure/ui-test-utils": "8.13.1-snapshot.48+4961e7204",
30
- "@instructure/ui-themes": "8.13.1-snapshot.48+4961e7204"
27
+ "@instructure/ui-babel-preset": "8.14.0",
28
+ "@instructure/ui-test-locator": "8.14.0",
29
+ "@instructure/ui-test-utils": "8.14.0",
30
+ "@instructure/ui-themes": "8.14.0"
31
31
  },
32
32
  "dependencies": {
33
33
  "@babel/runtime": "^7.13.10",
34
- "@instructure/emotion": "8.13.1-snapshot.48+4961e7204",
35
- "@instructure/shared-types": "8.13.1-snapshot.48+4961e7204",
36
- "@instructure/ui-form-field": "8.13.1-snapshot.48+4961e7204",
37
- "@instructure/ui-icons": "8.13.1-snapshot.48+4961e7204",
38
- "@instructure/ui-react-utils": "8.13.1-snapshot.48+4961e7204",
39
- "@instructure/ui-testable": "8.13.1-snapshot.48+4961e7204",
40
- "@instructure/ui-utils": "8.13.1-snapshot.48+4961e7204",
41
- "@instructure/uid": "8.13.1-snapshot.48+4961e7204",
34
+ "@instructure/emotion": "8.14.0",
35
+ "@instructure/shared-types": "8.14.0",
36
+ "@instructure/ui-form-field": "8.14.0",
37
+ "@instructure/ui-icons": "8.14.0",
38
+ "@instructure/ui-react-utils": "8.14.0",
39
+ "@instructure/ui-testable": "8.14.0",
40
+ "@instructure/ui-utils": "8.14.0",
41
+ "@instructure/uid": "8.14.0",
42
42
  "keycode": "^2",
43
43
  "prop-types": "^15"
44
44
  },
@@ -48,6 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "sideEffects": false,
52
- "gitHead": "4961e72046cb5d951afcc2d90f416e34539cbde2"
51
+ "sideEffects": false
53
52
  }
@@ -21,8 +21,9 @@
21
21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  * SOFTWARE.
23
23
  */
24
+
24
25
  /** @jsx jsx */
25
- import { Component } from 'react'
26
+ import React, { Component } from 'react'
26
27
  import keycode from 'keycode'
27
28
 
28
29
  import { FormField } from '@instructure/ui-form-field'
@@ -43,18 +44,20 @@ import { withStyle, jsx } from '@instructure/emotion'
43
44
 
44
45
  import generateStyle from './styles'
45
46
  import generateComponentTheme from './theme'
47
+
48
+ import { allowedProps, propTypes } from './props'
46
49
  import type {
47
50
  NumberInputProps,
48
51
  NumberInputState,
49
52
  NumberInputStyleProps
50
53
  } from './props'
51
- import { allowedProps, propTypes } from './props'
52
54
 
53
55
  /**
54
56
  ---
55
57
  category: components
56
58
  id: NumberInput
57
59
  ---
60
+ @tsProps
58
61
  **/
59
62
  @withStyle(generateStyle, generateComponentTheme)
60
63
  @testable()
@@ -63,37 +66,24 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
63
66
  static allowedProps = allowedProps
64
67
  static propTypes = propTypes
65
68
  static defaultProps = {
66
- id: null,
67
69
  // Leave interaction default undefined so that `disabled` and `readOnly` can also be supplied
68
70
  interaction: undefined,
69
71
  messages: [],
70
- placeholder: null,
71
72
  isRequired: false,
72
73
  showArrows: true,
73
74
  size: 'medium',
74
75
  display: 'block',
75
76
  textAlign: 'start',
76
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
77
- inputRef: (event) => {},
78
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
79
- onFocus: (event) => {},
80
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
81
- onBlur: (event) => {},
82
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
83
- onChange: (event, value) => {},
84
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
85
- onDecrement: (event) => {},
86
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
87
- onIncrement: (event) => {},
88
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
89
- onKeyDown: (event) => {},
90
77
  inputMode: 'numeric'
91
78
  }
92
79
 
93
80
  state: NumberInputState = { hasFocus: false }
94
- _input = null
81
+
95
82
  ref: Element | null = null
96
83
 
84
+ private _input: HTMLInputElement | null = null
85
+ private _id?: string
86
+
97
87
  handleRef = (el: Element | null) => {
98
88
  this.ref = el
99
89
  }
@@ -102,12 +92,9 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
102
92
  if (this.props.id) {
103
93
  return this.props.id
104
94
  }
105
- // @ts-expect-error ts-migrate(2339) FIXME: Property '_id' does not exist on type 'NumberInput... Remove this comment to see the full error message
106
95
  if (!this._id) {
107
- // @ts-expect-error ts-migrate(2339) FIXME: Property '_id' does not exist on type 'NumberInput... Remove this comment to see the full error message
108
96
  this._id = uid('NumberInput')
109
97
  }
110
- // @ts-expect-error ts-migrate(2339) FIXME: Property '_id' does not exist on type 'NumberInput... Remove this comment to see the full error message
111
98
  return this._id
112
99
  }
113
100
 
@@ -138,68 +125,77 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
138
125
  }
139
126
  }
140
127
 
141
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'element' implicitly has an 'any' type.
142
- handleInputRef = (element) => {
128
+ handleInputRef = (element: HTMLInputElement | null) => {
143
129
  this._input = element
144
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
145
- this.props.inputRef(element)
130
+
131
+ if (typeof this.props.inputRef === 'function') {
132
+ this.props.inputRef(element)
133
+ }
146
134
  }
147
135
 
148
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
149
- handleFocus = (event) => {
136
+ handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
150
137
  this.setState({ hasFocus: true })
151
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
152
- this.props.onFocus(event)
138
+
139
+ if (typeof this.props.onFocus === 'function') {
140
+ this.props.onFocus(event)
141
+ }
153
142
  }
154
143
 
155
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
156
- handleBlur = (event) => {
144
+ handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
157
145
  this.setState({ hasFocus: false })
158
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
159
- this.props.onBlur(event)
146
+
147
+ if (typeof this.props.onBlur === 'function') {
148
+ this.props.onBlur(event)
149
+ }
160
150
  }
161
151
 
162
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
163
- handleChange = (event) => {
164
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
165
- this.props.onChange(event, event.target.value)
152
+ handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
153
+ if (typeof this.props.onChange === 'function') {
154
+ this.props.onChange(event, event.target.value)
155
+ }
166
156
  }
167
157
 
168
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
169
- handleKeyDown = (event) => {
170
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
171
- this.props.onKeyDown(event)
158
+ handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
159
+ const { onKeyDown, onDecrement, onIncrement } = this.props
160
+
161
+ if (typeof onKeyDown === 'function') {
162
+ onKeyDown(event)
163
+ }
172
164
 
173
165
  if (event.keyCode === keycode.codes.down) {
174
166
  event.preventDefault()
175
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
176
- this.props.onDecrement(event)
167
+ if (typeof onDecrement === 'function') {
168
+ onDecrement(event)
169
+ }
177
170
  } else if (event.keyCode === keycode.codes.up) {
178
171
  event.preventDefault()
179
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
180
- this.props.onIncrement(event)
172
+ if (typeof onIncrement === 'function') {
173
+ onIncrement(event)
174
+ }
181
175
  }
182
176
  }
183
177
 
184
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
185
- handleClickUpArrow = (event) => {
178
+ handleClickUpArrow = (event: React.MouseEvent<HTMLButtonElement>) => {
186
179
  this.arrowClicked(event, this.props.onIncrement)
187
180
  }
188
181
 
189
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
190
- handleClickDownArrow = (event) => {
182
+ handleClickDownArrow = (event: React.MouseEvent<HTMLButtonElement>) => {
191
183
  this.arrowClicked(event, this.props.onDecrement)
192
184
  }
193
185
 
194
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
195
- arrowClicked(event, callback) {
186
+ arrowClicked(
187
+ event: React.MouseEvent<HTMLButtonElement>,
188
+ callback: NumberInputProps['onIncrement'] | NumberInputProps['onDecrement']
189
+ ) {
196
190
  const { interaction } = this
197
191
 
198
192
  event.preventDefault()
199
193
  if (interaction === 'enabled') {
200
- // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
201
- this._input.focus()
202
- callback(event)
194
+ this._input?.focus()
195
+
196
+ if (typeof callback === 'function') {
197
+ callback(event)
198
+ }
203
199
  }
204
200
  }
205
201
 
@@ -210,8 +206,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
210
206
  aria-hidden
211
207
  css={this.props.styles?.arrow}
212
208
  onMouseDown={this.handleClickUpArrow}
213
- // @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
214
- tabIndex="-1"
209
+ tabIndex={-1}
215
210
  type="button"
216
211
  >
217
212
  <IconArrowOpenUpLine />
@@ -220,8 +215,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
220
215
  aria-hidden
221
216
  css={this.props.styles?.arrow}
222
217
  onMouseDown={this.handleClickDownArrow}
223
- // @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'number | ... Remove this comment to see the full error message
224
- tabIndex="-1"
218
+ tabIndex={-1}
225
219
  type="button"
226
220
  >
227
221
  <IconArrowOpenDownLine />
@@ -21,6 +21,9 @@
21
21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
  * SOFTWARE.
23
23
  */
24
+
25
+ import React from 'react'
26
+ import type { InputHTMLAttributes } from 'react'
24
27
  import PropTypes from 'prop-types'
25
28
 
26
29
  import { FormPropTypes } from '@instructure/ui-form-field'
@@ -30,154 +33,183 @@ import type {
30
33
  NumberInputTheme,
31
34
  OtherHTMLAttributes
32
35
  } from '@instructure/shared-types'
33
- import type { FormMessage } from '@instructure/ui-form-field'
36
+ import type { FormFieldOwnProps, FormMessage } from '@instructure/ui-form-field'
34
37
  import type { InteractionType } from '@instructure/ui-react-utils'
35
38
  import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
36
- import { InputHTMLAttributes } from 'react'
37
39
 
38
40
  type NumberInputOwnProps = {
39
- renderLabel: React.ReactNode | ((...args: any[]) => any)
40
- id?: string
41
- interaction?: InteractionType
42
- messages?: FormMessage[]
43
- placeholder?: string
44
- isRequired?: boolean
45
- showArrows?: boolean
46
- size?: 'medium' | 'large'
47
- value?: string | number
48
- width?: string
49
- display?: 'inline-block' | 'block'
50
- inputRef?: (...args: any[]) => any
51
- onFocus?: (...args: any[]) => any
52
- onBlur?: (...args: any[]) => any
53
- onChange?: (...args: any[]) => any
54
- onDecrement?: (...args: any[]) => any
55
- onIncrement?: (...args: any[]) => any
56
- onKeyDown?: (...args: any[]) => any
57
- inputMode?: 'numeric' | 'decimal' | 'tel'
58
- textAlign?: 'start' | 'center'
59
- }
60
-
61
- type NumberInputState = {
62
- hasFocus: boolean
63
- }
64
-
65
- type NumberInputStyleProps = NumberInputState & {
66
- interaction: InteractionType
67
- invalid: boolean
68
- }
69
-
70
- type PropKeys = keyof NumberInputOwnProps
71
-
72
- type AllowedPropKeys = Readonly<Array<PropKeys>>
73
-
74
- type NumberInputProps = NumberInputOwnProps &
75
- WithStyleProps<NumberInputTheme, NumberInputStyle> &
76
- OtherHTMLAttributes<
77
- NumberInputOwnProps,
78
- InputHTMLAttributes<NumberInputOwnProps>
79
- >
80
-
81
- type NumberInputStyle = ComponentStyle<
82
- | 'numberInput'
83
- | 'arrowContainer'
84
- | 'arrow'
85
- | 'inputWidth'
86
- | 'inputContainer'
87
- | 'input'
88
- >
89
-
90
- const propTypes: PropValidators<PropKeys> = {
91
41
  /**
92
42
  * The form field label.
93
43
  */
94
- renderLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
44
+ renderLabel: React.ReactNode | (() => React.ReactNode)
45
+
95
46
  /**
96
47
  * The id of the input. One is generated if not supplied.
97
48
  */
98
- id: PropTypes.string,
49
+ id?: string
50
+
99
51
  /**
100
52
  * Specifies if interaction with the input is enabled, disabled, or readonly.
101
53
  * When "disabled", the input changes visibly to indicate that it cannot
102
54
  * receive user interactions. When "readonly" the input still cannot receive
103
55
  * user interactions but it keeps the same styles as if it were enabled.
104
56
  */
105
- interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
57
+ interaction?: InteractionType
58
+
106
59
  /**
107
- * Object with shape: `{
108
- * text: PropTypes.node,
109
- * type: PropTypes.oneOf(['error', 'hint', 'success', 'screenreader-only'])
60
+ * Array of objects with shape: `{
61
+ * text: ReactNode,
62
+ * type: One of: ['error', 'hint', 'success', 'screenreader-only']
110
63
  * }`
111
64
  */
112
- messages: PropTypes.arrayOf(FormPropTypes.message),
65
+ messages?: FormMessage[]
66
+
113
67
  /**
114
68
  * Html placeholder text to display when the input has no value. This
115
69
  * should be hint text, not a label replacement.
116
70
  */
117
- placeholder: PropTypes.string,
71
+ placeholder?: string
72
+
118
73
  /**
119
74
  * Whether or not the text input is required.
120
75
  */
121
- isRequired: PropTypes.bool,
76
+ isRequired?: boolean
77
+
122
78
  /**
123
79
  * Whether or not to display the up/down arrow buttons.
124
80
  */
125
- showArrows: PropTypes.bool,
81
+ showArrows?: boolean
82
+
126
83
  /**
127
84
  * The size of the input.
128
85
  */
129
- size: PropTypes.oneOf(['medium', 'large']),
86
+ size?: 'medium' | 'large'
87
+
130
88
  /**
131
89
  * The value of the input (should be accompanied by an `onChange` prop).
132
90
  */
133
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
91
+ value?: string | number
92
+
134
93
  /**
135
94
  * The width of the input.
136
95
  */
137
- width: PropTypes.string,
96
+ width?: string
97
+
138
98
  /**
139
99
  * The display of the root element.
140
100
  */
141
- display: PropTypes.oneOf(['inline-block', 'block']),
101
+ display?: 'inline-block' | 'block'
102
+
142
103
  /**
143
104
  * A function that provides a reference to the actual input element.
144
105
  */
145
- inputRef: PropTypes.func,
106
+ inputRef?: (element: HTMLInputElement | null) => void
107
+
146
108
  /**
147
109
  * Callback fired when input receives focus.
148
110
  */
149
- onFocus: PropTypes.func,
111
+ onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void
112
+
150
113
  /**
151
114
  * Callback fired when the input loses focus.
152
115
  */
153
- onBlur: PropTypes.func,
116
+ onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void
117
+
154
118
  /**
155
119
  * Callback executed when the input fires a change event.
156
120
  * @param {Object} event - the event object
157
- * @param {Object} value - the string value of the input
121
+ * @param {string} value - the string value of the input
158
122
  */
159
- onChange: PropTypes.func,
123
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>, value: string) => void
124
+
160
125
  /**
161
126
  * Called when the down arrow button is clicked, or the down arrow key is
162
127
  * pressed.
163
128
  */
164
- onDecrement: PropTypes.func,
129
+ onDecrement?: (
130
+ event:
131
+ | React.KeyboardEvent<HTMLInputElement>
132
+ | React.MouseEvent<HTMLButtonElement>
133
+ ) => void
134
+
165
135
  /**
166
136
  * Called when the up arrow button is clicked, or the up arrow key is
167
137
  * pressed.
168
138
  */
169
- onIncrement: PropTypes.func,
139
+ onIncrement?: (
140
+ event:
141
+ | React.KeyboardEvent<HTMLInputElement>
142
+ | React.MouseEvent<HTMLButtonElement>
143
+ ) => void
144
+
170
145
  /**
171
146
  * Callback fired when a key is pressed.
172
147
  */
173
- onKeyDown: PropTypes.func,
148
+ onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void
149
+
174
150
  /**
175
151
  * The inputMode attribute of the underlying `input` element can be one of ['numeric', 'decimal', 'tel']
176
152
  */
177
- inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
153
+ inputMode?: 'numeric' | 'decimal' | 'tel'
154
+
178
155
  /**
179
156
  * The text alignment of the input.
180
157
  */
158
+ textAlign?: 'start' | 'center'
159
+ }
160
+
161
+ type NumberInputState = {
162
+ hasFocus: boolean
163
+ }
164
+
165
+ type NumberInputStyleProps = NumberInputState & {
166
+ interaction: InteractionType
167
+ invalid: boolean
168
+ }
169
+
170
+ type PropKeys = keyof NumberInputOwnProps
171
+
172
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
173
+
174
+ type NumberInputProps =
175
+ // pickProps passes through FormField.allowedProps, except the ones set manually
176
+ Omit<FormFieldOwnProps, 'label' | 'inline' | 'id' | 'elementRef'> &
177
+ NumberInputOwnProps &
178
+ WithStyleProps<NumberInputTheme, NumberInputStyle> &
179
+ OtherHTMLAttributes<
180
+ NumberInputOwnProps,
181
+ InputHTMLAttributes<NumberInputOwnProps>
182
+ >
183
+
184
+ type NumberInputStyle = ComponentStyle<
185
+ | 'numberInput'
186
+ | 'arrowContainer'
187
+ | 'arrow'
188
+ | 'inputWidth'
189
+ | 'inputContainer'
190
+ | 'input'
191
+ >
192
+
193
+ const propTypes: PropValidators<PropKeys> = {
194
+ renderLabel: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
195
+ id: PropTypes.string,
196
+ interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
197
+ messages: PropTypes.arrayOf(FormPropTypes.message),
198
+ placeholder: PropTypes.string,
199
+ isRequired: PropTypes.bool,
200
+ showArrows: PropTypes.bool,
201
+ size: PropTypes.oneOf(['medium', 'large']),
202
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
203
+ width: PropTypes.string,
204
+ display: PropTypes.oneOf(['inline-block', 'block']),
205
+ inputRef: PropTypes.func,
206
+ onFocus: PropTypes.func,
207
+ onBlur: PropTypes.func,
208
+ onChange: PropTypes.func,
209
+ onDecrement: PropTypes.func,
210
+ onIncrement: PropTypes.func,
211
+ onKeyDown: PropTypes.func,
212
+ inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
181
213
  textAlign: PropTypes.oneOf(['start', 'center'])
182
214
  }
183
215