@instructure/ui-buttons 8.13.1-snapshot.9 → 8.14.1-snapshot.15

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/es/BaseButton/index.js +64 -43
  3. package/es/BaseButton/props.js +2 -88
  4. package/es/BaseButton/theme.js +1 -1
  5. package/es/Button/index.js +2 -2
  6. package/es/Button/props.js +3 -65
  7. package/es/CloseButton/index.js +23 -18
  8. package/es/CloseButton/props.js +2 -60
  9. package/es/CondensedButton/index.js +2 -2
  10. package/es/CondensedButton/props.js +3 -48
  11. package/es/IconButton/index.js +2 -2
  12. package/es/IconButton/props.js +3 -68
  13. package/es/ToggleButton/index.js +4 -5
  14. package/es/ToggleButton/props.js +1 -58
  15. package/lib/BaseButton/index.js +67 -43
  16. package/lib/BaseButton/props.js +2 -88
  17. package/lib/BaseButton/theme.js +1 -1
  18. package/lib/Button/index.js +2 -2
  19. package/lib/Button/props.js +3 -65
  20. package/lib/CloseButton/index.js +23 -18
  21. package/lib/CloseButton/props.js +2 -60
  22. package/lib/CondensedButton/index.js +2 -2
  23. package/lib/CondensedButton/props.js +3 -48
  24. package/lib/IconButton/index.js +2 -2
  25. package/lib/IconButton/props.js +3 -68
  26. package/lib/ToggleButton/index.js +4 -5
  27. package/lib/ToggleButton/props.js +1 -58
  28. package/package.json +21 -21
  29. package/src/BaseButton/index.tsx +35 -27
  30. package/src/BaseButton/props.ts +103 -73
  31. package/src/BaseButton/theme.ts +1 -6
  32. package/src/Button/index.tsx +4 -8
  33. package/src/Button/props.ts +74 -48
  34. package/src/CloseButton/index.tsx +4 -6
  35. package/src/CloseButton/props.ts +66 -41
  36. package/src/CondensedButton/index.tsx +3 -7
  37. package/src/CondensedButton/props.ts +56 -34
  38. package/src/IconButton/index.tsx +3 -7
  39. package/src/IconButton/props.ts +77 -50
  40. package/src/ToggleButton/index.tsx +8 -15
  41. package/src/ToggleButton/props.ts +65 -39
  42. package/tsconfig.build.json +25 -2
  43. package/tsconfig.build.tsbuildinfo +1 -0
  44. package/types/BaseButton/BaseButtonLocator.d.ts +57 -56
  45. package/types/BaseButton/BaseButtonLocator.d.ts.map +1 -1
  46. package/types/BaseButton/index.d.ts +16 -15
  47. package/types/BaseButton/index.d.ts.map +1 -1
  48. package/types/BaseButton/props.d.ts +76 -5
  49. package/types/BaseButton/props.d.ts.map +1 -1
  50. package/types/BaseButton/theme.d.ts.map +1 -1
  51. package/types/Button/ButtonLocator.d.ts +57 -56
  52. package/types/Button/ButtonLocator.d.ts.map +1 -1
  53. package/types/Button/index.d.ts +10 -7
  54. package/types/Button/index.d.ts.map +1 -1
  55. package/types/Button/locator.d.ts +52 -52
  56. package/types/Button/props.d.ts +57 -3
  57. package/types/Button/props.d.ts.map +1 -1
  58. package/types/CloseButton/CloseButtonLocator.d.ts +52 -52
  59. package/types/CloseButton/index.d.ts +4 -3
  60. package/types/CloseButton/index.d.ts.map +1 -1
  61. package/types/CloseButton/props.d.ts +55 -5
  62. package/types/CloseButton/props.d.ts.map +1 -1
  63. package/types/CondensedButton/CondensedButtonLocator.d.ts +57 -56
  64. package/types/CondensedButton/CondensedButtonLocator.d.ts.map +1 -1
  65. package/types/CondensedButton/index.d.ts +9 -6
  66. package/types/CondensedButton/index.d.ts.map +1 -1
  67. package/types/CondensedButton/props.d.ts +44 -3
  68. package/types/CondensedButton/props.d.ts.map +1 -1
  69. package/types/IconButton/IconButtonLocator.d.ts +57 -56
  70. package/types/IconButton/IconButtonLocator.d.ts.map +1 -1
  71. package/types/IconButton/index.d.ts +11 -8
  72. package/types/IconButton/index.d.ts.map +1 -1
  73. package/types/IconButton/props.d.ts +60 -4
  74. package/types/IconButton/props.d.ts.map +1 -1
  75. package/types/ToggleButton/ToggleButtonLocator.d.ts +57 -56
  76. package/types/ToggleButton/ToggleButtonLocator.d.ts.map +1 -1
  77. package/types/ToggleButton/index.d.ts +12 -13
  78. package/types/ToggleButton/index.d.ts.map +1 -1
  79. package/types/ToggleButton/props.d.ts +52 -4
  80. package/types/ToggleButton/props.d.ts.map +1 -1
@@ -23,9 +23,10 @@
23
23
  */
24
24
 
25
25
  /** @jsx jsx */
26
- import { Component } from 'react'
26
+ import React, { Component } from 'react'
27
27
  import keycode from 'keycode'
28
28
 
29
+ import { warn } from '@instructure/console'
29
30
  import { testable } from '@instructure/ui-testable'
30
31
  import {
31
32
  getElementType,
@@ -36,6 +37,7 @@ import {
36
37
  import { isActiveElement } from '@instructure/ui-dom-utils'
37
38
  import { hasVisibleChildren } from '@instructure/ui-a11y-utils'
38
39
  import { View } from '@instructure/ui-view'
40
+ import type { ViewProps } from '@instructure/ui-view'
39
41
 
40
42
  import { withStyle, jsx } from '@instructure/emotion'
41
43
 
@@ -49,6 +51,7 @@ import type { BaseButtonProps, BaseButtonStyleProps } from './props'
49
51
  ---
50
52
  category: components/utilities
51
53
  ---
54
+ @tsProps
52
55
  **/
53
56
 
54
57
  @withStyle(generateStyles, generateComponentTheme)
@@ -59,13 +62,11 @@ class BaseButton extends Component<BaseButtonProps> {
59
62
  static propTypes = propTypes
60
63
  static allowedProps = allowedProps
61
64
  static defaultProps = {
62
- children: null,
63
65
  type: 'button',
64
66
  size: 'medium',
65
- // @ts-expect-error ts-migrate(6133) FIXME: 'el' is declared but its value is never read.
66
- elementRef: (el) => {},
67
67
  as: 'button',
68
68
  // Leave interaction default undefined so that `disabled` and `readOnly` can also be supplied
69
+ interaction: undefined,
69
70
  color: 'secondary',
70
71
  shape: 'rectangle',
71
72
  display: 'inline-block',
@@ -74,23 +75,19 @@ class BaseButton extends Component<BaseButtonProps> {
74
75
  withBorder: true,
75
76
  isCondensed: false,
76
77
  margin: '0',
77
- cursor: 'pointer',
78
- // @ts-expect-error ts-migrate(6133) FIXME: 'event' is declared but its value is never read.
79
- onKeyDown: (event) => {}
78
+ cursor: 'pointer'
80
79
  } as const
81
80
 
82
81
  ref: Element | null = null
83
82
 
84
83
  componentDidMount() {
85
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
86
- this.props.makeStyles(this.makeStylesVariables)
84
+ this.props.makeStyles?.(this.makeStylesVariables)
87
85
  }
88
86
 
89
- // @ts-expect-error ts-migrate(6133) FIXME: 'prevProps' is declared but its value is never rea... Remove this comment to see the full error message
90
- componentDidUpdate(prevProps, prevState, snapshot) {
91
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
92
- this.props.makeStyles(this.makeStylesVariables)
87
+ componentDidUpdate() {
88
+ this.props.makeStyles?.(this.makeStylesVariables)
93
89
  }
90
+
94
91
  get _rootElement() {
95
92
  console.warn(
96
93
  '_rootElement property is deprecated and will be removed in v9, please use ref instead'
@@ -131,6 +128,20 @@ class BaseButton extends Component<BaseButtonProps> {
131
128
  return this.interaction === 'enabled'
132
129
  }
133
130
 
131
+ // TODO: delete once the type of tabIndex is changed to number only
132
+ get tabIndex() {
133
+ const { tabIndex } = this.props
134
+
135
+ if (typeof tabIndex === 'string') {
136
+ warn(
137
+ false,
138
+ 'The `string` value for `tabIndex` is deprecated. Only `number` type will be accepted from V9.0.0.'
139
+ )
140
+ return parseInt(tabIndex)
141
+ }
142
+ return tabIndex
143
+ }
144
+
134
145
  get focusColor() {
135
146
  const { color, focusColor, withBackground } = this.props
136
147
 
@@ -147,8 +158,7 @@ class BaseButton extends Component<BaseButtonProps> {
147
158
  return 'info'
148
159
  }
149
160
 
150
- // @ts-expect-error ts-migrate(2532) FIXME: Object is possibly 'undefined'.
151
- return color.includes('inverse') ? 'inverse' : 'info'
161
+ return color!.includes('inverse') ? 'inverse' : 'info'
152
162
  }
153
163
 
154
164
  get focused() {
@@ -156,8 +166,7 @@ class BaseButton extends Component<BaseButtonProps> {
156
166
  }
157
167
 
158
168
  focus() {
159
- // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
160
- this.ref && this.ref.focus()
169
+ this.ref && (this.ref as HTMLElement).focus()
161
170
  }
162
171
 
163
172
  handleElementRef = (el: Element | null) => {
@@ -170,8 +179,7 @@ class BaseButton extends Component<BaseButtonProps> {
170
179
  }
171
180
  }
172
181
 
173
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
174
- handleClick = (event) => {
182
+ handleClick = (event: React.MouseEvent<ViewProps>) => {
175
183
  const { onClick } = this.props
176
184
  const { interaction } = this
177
185
 
@@ -186,13 +194,13 @@ class BaseButton extends Component<BaseButtonProps> {
186
194
  }
187
195
  }
188
196
 
189
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'event' implicitly has an 'any' type.
190
- handleKeyDown = (event) => {
197
+ handleKeyDown = (event: React.KeyboardEvent<ViewProps>) => {
191
198
  const { onClick, onKeyDown, href } = this.props
192
199
  const { interaction } = this
193
200
 
194
- // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message
195
- onKeyDown(event)
201
+ if (typeof onKeyDown === 'function') {
202
+ onKeyDown(event)
203
+ }
196
204
 
197
205
  // behave like a button when space key is pressed
198
206
  const { space, enter } = keycode.codes
@@ -209,8 +217,7 @@ class BaseButton extends Component<BaseButtonProps> {
209
217
  }
210
218
 
211
219
  if (href) {
212
- // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
213
- this.ref && this.ref.click()
220
+ this.ref && (this.ref as HTMLElement).click()
214
221
  }
215
222
  }
216
223
  }
@@ -274,6 +281,8 @@ class BaseButton extends Component<BaseButtonProps> {
274
281
 
275
282
  const { isDisabled, isEnabled, isReadOnly } = this
276
283
 
284
+ const tabIndexNumber = this.tabIndex
285
+
277
286
  return (
278
287
  <View
279
288
  {...passthroughProps(props)}
@@ -294,8 +303,7 @@ class BaseButton extends Component<BaseButtonProps> {
294
303
  onClick={this.handleClick}
295
304
  onKeyDown={this.handleKeyDown}
296
305
  role={onClick && as !== 'button' ? 'button' : undefined}
297
- //@ts-expect-error fix this later to be number
298
- tabIndex={onClick && as ? tabIndex || '0' : tabIndex}
306
+ tabIndex={onClick && as ? tabIndexNumber || 0 : tabIndexNumber}
299
307
  disabled={isDisabled || isReadOnly}
300
308
  css={isEnabled ? styles?.baseButton : null}
301
309
  >
@@ -34,35 +34,130 @@ import type {
34
34
  ComponentStyle
35
35
  } from '@instructure/emotion'
36
36
  import type {
37
+ ToProp,
37
38
  AsElementType,
38
39
  BaseButtonTheme,
39
40
  OtherHTMLAttributes,
40
41
  PropValidators
41
42
  } from '@instructure/shared-types'
42
43
  import type { Cursor } from '@instructure/ui-prop-types'
44
+ import type { ViewProps } from '@instructure/ui-view'
43
45
 
44
46
  type BaseButtonOwnProps = {
47
+ /**
48
+ * Specifies the `Button` children.
49
+ */
45
50
  children?: React.ReactNode
51
+
52
+ /**
53
+ * Specifies the type of the `Button`'s underlying html element.
54
+ */
46
55
  type?: 'button' | 'submit' | 'reset'
56
+
57
+ /**
58
+ * The size of the `Button`
59
+ */
47
60
  size?: 'small' | 'medium' | 'large'
61
+
62
+ /**
63
+ * Provides a reference to the `Button`'s underlying html element.
64
+ */
48
65
  elementRef?: (element: Element | null) => void
66
+
67
+ /**
68
+ * The element to render as the component root, `Button` by default.
69
+ */
49
70
  as?: AsElementType
71
+
72
+ /**
73
+ * Specifies if interaction with the `Button` is enabled, disabled, or readonly.
74
+ */
50
75
  interaction?: InteractionType
76
+
77
+ /**
78
+ * Specifies the color for the `Button`.
79
+ */
51
80
  color?: 'primary' | 'primary-inverse' | 'secondary' | 'success' | 'danger'
81
+
82
+ /**
83
+ * Override the `Button`'s default focus outline color.
84
+ */
52
85
  focusColor?: 'info' | 'inverse'
86
+
87
+ /**
88
+ * The `Button` display property. When set to `inline-block`, the `Button` displays inline with other elements.
89
+ * When set to block, the `Button` expands to fill the width of the container.
90
+ */
53
91
  display?: 'inline-block' | 'block'
92
+
93
+ /**
94
+ * Sets the alignment of the `Button` children and/or icon.
95
+ */
54
96
  textAlign?: 'start' | 'center'
97
+
98
+ /**
99
+ * Specifies if the `Button` shape should be a circle or rectangle.
100
+ */
55
101
  shape?: 'rectangle' | 'circle'
102
+
103
+ /**
104
+ * Specifies if the `Button` should render with a solid background. When false, the background is transparent.
105
+ */
56
106
  withBackground?: boolean
107
+
108
+ /**
109
+ * Specifies if the `Button` should render with a border.
110
+ */
57
111
  withBorder?: boolean
112
+
113
+ /**
114
+ * Designates if the `Button` should render without padding. This option should only be set when `withBorder` and
115
+ * `withBackground` are also set to false.
116
+ */
58
117
  isCondensed?: boolean
118
+
119
+ /**
120
+ * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`,
121
+ * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via
122
+ * familiar CSS-like shorthand. For example: `margin="small auto large"`.
123
+ */
59
124
  margin?: Spacing
125
+
126
+ /**
127
+ * Specify a mouse cursor to use when hovering over the button.
128
+ * The `pointer` cursor is used by default.
129
+ */
60
130
  cursor?: Cursor
131
+
132
+ /**
133
+ * Specifies an href attribute for the `Button`'s underlying html element.
134
+ */
61
135
  href?: string
62
- onClick?: (...args: any[]) => any
63
- onKeyDown?: (...args: any[]) => any
64
- renderIcon?: React.ReactNode | ((...args: any[]) => any)
65
- tabIndex?: number | string
136
+
137
+ /**
138
+ * Callback fired when the `Button` is clicked.
139
+ */
140
+ onClick?: (
141
+ event: React.KeyboardEvent<ViewProps> | React.MouseEvent<ViewProps>
142
+ ) => void
143
+
144
+ /**
145
+ * Callback fired when the `Button` receives a keydown event.
146
+ */
147
+ onKeyDown?: (event: React.KeyboardEvent<ViewProps>) => void
148
+
149
+ /**
150
+ * An icon, or function that returns an icon.
151
+ */
152
+ renderIcon?: React.ReactNode | (() => React.ReactNode)
153
+
154
+ // Deprecated `string` tabIndex type
155
+ /**
156
+ * Specifies the tabindex of the `Button`.
157
+ *
158
+ * (`string` type is __deprecated__, use `number`)
159
+ */
160
+ tabIndex?: number | string // TODO: remove string type in v9
66
161
  }
67
162
 
68
163
  type BaseButtonStyleProps = {
@@ -76,7 +171,8 @@ type AllowedPropKeys = Readonly<Array<PropKeys>>
76
171
 
77
172
  type BaseButtonProps = BaseButtonOwnProps &
78
173
  WithStyleProps<BaseButtonTheme, BaseButtonStyle> &
79
- OtherHTMLAttributes<BaseButtonOwnProps>
174
+ OtherHTMLAttributes<BaseButtonOwnProps> &
175
+ ToProp
80
176
 
81
177
  type BaseButtonStyle = ComponentStyle<
82
178
  | 'baseButton'
@@ -90,33 +186,12 @@ type BaseButtonStyle = ComponentStyle<
90
186
  >
91
187
 
92
188
  const propTypes: PropValidators<PropKeys> = {
93
- /**
94
- * Specifies the `Button` children.
95
- */
96
189
  children: PropTypes.node,
97
- /**
98
- * Specifies the type of the `Button`'s underlying html element.
99
- */
100
190
  type: PropTypes.oneOf(['button', 'submit', 'reset']),
101
- /**
102
- * The size of the `Button`
103
- */
104
191
  size: PropTypes.oneOf(['small', 'medium', 'large']),
105
- /**
106
- * Provides a reference to the `Button`'s underlying html element.
107
- */
108
192
  elementRef: PropTypes.func,
109
- /**
110
- * The element to render as the component root, `Button` by default.
111
- */
112
193
  as: PropTypes.elementType,
113
- /**
114
- * Specifies if interaction with the `Button` is enabled, disabled, or readonly.
115
- */
116
194
  interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
117
- /**
118
- * Specifies the color for the `Button`.
119
- */
120
195
  color: PropTypes.oneOf([
121
196
  'primary',
122
197
  'primary-inverse',
@@ -124,66 +199,21 @@ const propTypes: PropValidators<PropKeys> = {
124
199
  'success',
125
200
  'danger'
126
201
  ]),
127
- /**
128
- * Override the `Button`'s default focus outline color.
129
- */
130
202
  focusColor: PropTypes.oneOf(['info', 'inverse']),
131
- /**
132
- * The `Button` display property. When set to `inline-block`, the `Button` displays inline with other elements.
133
- * When set to block, the `Button` expands to fill the width of the container.
134
- */
135
203
  display: PropTypes.oneOf(['inline-block', 'block']),
136
- /**
137
- * Sets the alignment of the `Button` children and/or icon.
138
- */
139
204
  textAlign: PropTypes.oneOf(['start', 'center']),
140
- /**
141
- * Specifies if the `Button` shape should be a circle or rectangle.
142
- */
143
205
  shape: PropTypes.oneOf(['rectangle', 'circle']),
144
- /**
145
- * Specifies if the `Button` should render with a solid background. When false, the background is transparent.
146
- */
147
206
  withBackground: PropTypes.bool,
148
- /**
149
- * Specifies if the `Button` should render with a border.
150
- */
151
207
  withBorder: PropTypes.bool,
152
- /**
153
- * Designates if the `Button` should render without padding. This option should only be set when `withBorder` and
154
- * `withBackground` are also set to false.
155
- */
156
208
  isCondensed: PropTypes.bool,
157
- /**
158
- * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`,
159
- * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via
160
- * familiar CSS-like shorthand. For example: `margin="small auto large"`.
161
- */
162
209
  margin: ThemeablePropTypes.spacing,
163
- /**
164
- * Specify a mouse cursor to use when hovering over the button.
165
- * The `pointer` cursor is used by default.
166
- */
167
210
  cursor: PropTypes.string,
168
- /**
169
- * Specifies an href attribute for the `Button`'s underlying html element.
170
- */
171
211
  href: PropTypes.string,
172
- /**
173
- * Callback fired when the `Button` is clicked.
174
- */
175
212
  onClick: PropTypes.func,
176
- /**
177
- * Callback fired when the `Button` receives a keydown event.
178
- */
179
213
  onKeyDown: PropTypes.func,
180
- /**
181
- * An icon, or function that returns an icon.
182
- */
183
214
  renderIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
184
- /**
185
- * Specifies the tabindex of the `Button`.
186
- */
215
+ // Deprecated `string` tabIndex type
216
+ // TODO: remove string type in v9
187
217
  tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
188
218
  }
189
219
 
@@ -75,12 +75,7 @@ const generateButtonThemeVars = <Variant extends Variants>({
75
75
  [`${style}Background`]: backgroundColor,
76
76
  [`${style}HoverBackground`]: darken(backgroundColor, 10),
77
77
  [`${style}ActiveBackground`]: darken(backgroundColor, 10),
78
- [`${style}ActiveBoxShadow`]: `${activeShadow} ${darken(
79
- borderColor,
80
- 20,
81
- // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 3.
82
- 0.45
83
- )}`,
78
+ [`${style}ActiveBoxShadow`]: `${activeShadow} ${darken(borderColor, 20)}`,
84
79
 
85
80
  [`${style}GhostColor`]: ghostTextColor,
86
81
  [`${style}GhostBorderColor`]: ghostBorderColor,
@@ -39,6 +39,7 @@ import type { ButtonProps } from './props'
39
39
  ---
40
40
  category: components
41
41
  ---
42
+ @tsProps
42
43
  **/
43
44
  // needed for listing the available theme variables on docs page
44
45
  @withStyle(null, generateComponentTheme)
@@ -49,13 +50,11 @@ class Button extends Component<ButtonProps> {
49
50
  static propTypes = propTypes
50
51
  static allowedProps = allowedProps
51
52
  static defaultProps = {
52
- children: null,
53
53
  type: 'button',
54
54
  size: 'medium',
55
- // @ts-expect-error ts-migrate(6133) FIXME: 'el' is declared but its value is never read.
56
- elementRef: (el) => {},
57
55
  as: 'button',
58
56
  // Leave interaction default undefined so that `disabled` and `readOnly` can also be supplied
57
+ interaction: undefined,
59
58
  color: 'secondary',
60
59
  display: 'inline-block',
61
60
  textAlign: 'center',
@@ -64,17 +63,15 @@ class Button extends Component<ButtonProps> {
64
63
  cursor: 'pointer'
65
64
  }
66
65
 
67
- _buttonComponent = null
66
+ _buttonComponent: BaseButton | null = null
68
67
 
69
68
  ref: Element | null = null
70
69
 
71
70
  get focused() {
72
- // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
73
71
  return this._buttonComponent && this._buttonComponent.focused
74
72
  }
75
73
 
76
74
  focus() {
77
- // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'.
78
75
  this._buttonComponent && this._buttonComponent.focus()
79
76
  }
80
77
 
@@ -88,8 +85,7 @@ class Button extends Component<ButtonProps> {
88
85
  }
89
86
  }
90
87
 
91
- // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'component' implicitly has an 'any' type... Remove this comment to see the full error message
92
- handleButtonRef = (component) => {
88
+ handleButtonRef = (component: BaseButton | null) => {
93
89
  this._buttonComponent = component
94
90
  }
95
91
 
@@ -29,110 +29,135 @@ import { ThemeablePropTypes } from '@instructure/emotion'
29
29
 
30
30
  import type { Spacing, WithStyleProps } from '@instructure/emotion'
31
31
  import type {
32
+ ToProp,
32
33
  AsElementType,
33
34
  PropValidators,
34
35
  BaseButtonTheme,
35
36
  OtherHTMLAttributes
36
37
  } from '@instructure/shared-types'
37
38
  import type { Cursor } from '@instructure/ui-prop-types'
39
+ import type { ViewProps } from '@instructure/ui-view'
38
40
 
39
41
  type ButtonOwnProps = {
40
- children?: React.ReactNode
41
- type?: 'button' | 'submit' | 'reset'
42
- size?: 'small' | 'medium' | 'large'
43
- elementRef?: (element: Element | null) => void
44
- as?: AsElementType
45
- interaction?: 'enabled' | 'disabled' | 'readonly'
46
- color?: 'primary' | 'primary-inverse' | 'secondary' | 'success' | 'danger'
47
- focusColor?: 'info' | 'inverse'
48
- display?: 'inline-block' | 'block'
49
- textAlign?: 'start' | 'center'
50
- withBackground?: boolean
51
- margin?: Spacing
52
- cursor?: Cursor
53
- href?: string
54
- renderIcon?: React.ReactNode | ((...args: any[]) => any)
55
- }
56
-
57
- type PropKeys = keyof ButtonOwnProps
58
-
59
- type AllowedPropKeys = Readonly<Array<PropKeys>>
60
-
61
- type ButtonProps = ButtonOwnProps &
62
- WithStyleProps<BaseButtonTheme, null> &
63
- OtherHTMLAttributes<ButtonOwnProps>
64
-
65
- const propTypes: PropValidators<PropKeys> = {
66
42
  /**
67
43
  * Specifies the `Button` children.
68
44
  */
69
- children: PropTypes.node,
45
+ children?: React.ReactNode
46
+
70
47
  /**
71
48
  * Specifies the type of the `Button`'s underlying html element.
72
49
  */
73
- type: PropTypes.oneOf(['button', 'submit', 'reset']),
50
+ type?: 'button' | 'submit' | 'reset'
51
+
74
52
  /**
75
53
  * The size of the `Button`
76
54
  */
77
- size: PropTypes.oneOf(['small', 'medium', 'large']),
55
+ size?: 'small' | 'medium' | 'large'
56
+
78
57
  /**
79
58
  * Provides a reference to the `Button`'s underlying html element.
80
59
  */
81
- elementRef: PropTypes.func,
60
+ elementRef?: (element: Element | null) => void
61
+
82
62
  /**
83
63
  * The element to render as the component root, `Button` by default.
84
64
  */
85
- as: PropTypes.elementType,
65
+ as?: AsElementType
66
+
86
67
  /**
87
68
  * Specifies if interaction with the `Button` is enabled, disabled, or readonly.
88
69
  */
89
- interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
70
+ interaction?: 'enabled' | 'disabled' | 'readonly'
71
+
90
72
  /**
91
73
  * Specifies the color for the `Button`.
92
74
  */
93
- color: PropTypes.oneOf([
94
- 'primary',
95
- 'primary-inverse',
96
- 'secondary',
97
- 'success',
98
- 'danger'
99
- ]),
75
+ color?: 'primary' | 'primary-inverse' | 'secondary' | 'success' | 'danger'
76
+
100
77
  /**
101
78
  * Override the `Button`'s default focus outline color.
102
79
  */
103
- focusColor: PropTypes.oneOf(['info', 'inverse']),
80
+ focusColor?: 'info' | 'inverse'
81
+
104
82
  /**
105
83
  * The `Button` display property. When set to `inline-block`, the `Button` displays inline with other elements.
106
84
  * When set to block, the `Button` expands to fill the width of the container.
107
85
  */
108
- display: PropTypes.oneOf(['inline-block', 'block']),
86
+ display?: 'inline-block' | 'block'
87
+
109
88
  /**
110
89
  * Sets the alignment of the `Button` children and/or icon.
111
90
  */
112
- textAlign: PropTypes.oneOf(['start', 'center']),
91
+ textAlign?: 'start' | 'center'
92
+
113
93
  /**
114
94
  * Specifies if the `Button` should render with a solid background. When false, the background is transparent.
115
95
  */
116
- withBackground: PropTypes.bool,
96
+ withBackground?: boolean
97
+
117
98
  /**
118
99
  * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`,
119
100
  * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via
120
101
  * familiar CSS-like shorthand. For example: `margin="small auto large"`.
121
102
  */
122
- margin: ThemeablePropTypes.spacing,
103
+ margin?: Spacing
104
+
123
105
  /**
124
106
  * Specify a mouse cursor to use when hovering over the button.
125
107
  * The `pointer` cursor is used by default.
126
108
  */
127
- cursor: PropTypes.string,
109
+ cursor?: Cursor
110
+
128
111
  /**
129
112
  * Specifies an href attribute for the `Button`'s underlying html element.
130
113
  */
131
- href: PropTypes.string,
114
+ href?: string
115
+
132
116
  /**
133
117
  * An icon, or function that returns an icon.
134
118
  */
135
- renderIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func])
119
+ renderIcon?: React.ReactNode | (() => React.ReactNode)
120
+
121
+ /**
122
+ * Callback fired when the `Button` is clicked.
123
+ */
124
+ onClick?: (
125
+ event: React.KeyboardEvent<ViewProps> | React.MouseEvent<ViewProps>
126
+ ) => void
127
+ }
128
+
129
+ type PropKeys = keyof ButtonOwnProps
130
+
131
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
132
+
133
+ type ButtonProps = ButtonOwnProps &
134
+ WithStyleProps<BaseButtonTheme, null> &
135
+ OtherHTMLAttributes<ButtonOwnProps> &
136
+ ToProp
137
+
138
+ const propTypes: PropValidators<PropKeys> = {
139
+ children: PropTypes.node,
140
+ type: PropTypes.oneOf(['button', 'submit', 'reset']),
141
+ size: PropTypes.oneOf(['small', 'medium', 'large']),
142
+ elementRef: PropTypes.func,
143
+ as: PropTypes.elementType,
144
+ interaction: PropTypes.oneOf(['enabled', 'disabled', 'readonly']),
145
+ color: PropTypes.oneOf([
146
+ 'primary',
147
+ 'primary-inverse',
148
+ 'secondary',
149
+ 'success',
150
+ 'danger'
151
+ ]),
152
+ focusColor: PropTypes.oneOf(['info', 'inverse']),
153
+ display: PropTypes.oneOf(['inline-block', 'block']),
154
+ textAlign: PropTypes.oneOf(['start', 'center']),
155
+ withBackground: PropTypes.bool,
156
+ margin: ThemeablePropTypes.spacing,
157
+ cursor: PropTypes.string,
158
+ href: PropTypes.string,
159
+ renderIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
160
+ onClick: PropTypes.func
136
161
  }
137
162
 
138
163
  const allowedProps: AllowedPropKeys = [
@@ -150,7 +175,8 @@ const allowedProps: AllowedPropKeys = [
150
175
  'size',
151
176
  'textAlign',
152
177
  'type',
153
- 'withBackground'
178
+ 'withBackground',
179
+ 'onClick'
154
180
  ]
155
181
 
156
182
  export type { ButtonProps }