@instructure/ui-buttons 10.15.1 → 10.15.2-snapshot-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/es/BaseButton/__new-tests__/BaseButton.test.js +21 -1
- package/es/BaseButton/index.js +19 -3
- package/lib/BaseButton/__new-tests__/BaseButton.test.js +21 -1
- package/lib/BaseButton/index.js +19 -3
- package/package.json +20 -20
- package/src/BaseButton/__new-tests__/BaseButton.test.tsx +22 -1
- package/src/BaseButton/index.tsx +29 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/BaseButton/index.d.ts.map +1 -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
|
+
## [10.15.2-snapshot-0](https://github.com/instructure/instructure-ui/compare/v10.15.1...v10.15.2-snapshot-0) (2025-04-04)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **ui-buttons:** fix tabindex=0 added unnecessarly to Buttons ([a9a68a4](https://github.com/instructure/instructure-ui/commit/a9a68a447d04e6c5509e0ce785745cdcaea73c54))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [10.15.1](https://github.com/instructure/instructure-ui/compare/v10.15.0...v10.15.1) (2025-04-03)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @instructure/ui-buttons
|
|
@@ -105,6 +105,26 @@ describe('<BaseButton/>', () => {
|
|
|
105
105
|
expect(button).toBeInTheDocument();
|
|
106
106
|
expect(button).toHaveAttribute('tabIndex', '0');
|
|
107
107
|
});
|
|
108
|
+
it('should not set tabIndex="0" when the element has it by default', () => {
|
|
109
|
+
const onClick = vi.fn();
|
|
110
|
+
render(/*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(BaseButton, {
|
|
111
|
+
as: "button",
|
|
112
|
+
onClick: onClick
|
|
113
|
+
}, "Hello Button"), /*#__PURE__*/React.createElement(BaseButton, {
|
|
114
|
+
onClick: onClick,
|
|
115
|
+
href: "example.html"
|
|
116
|
+
}, "Hello link")));
|
|
117
|
+
const button = screen.getByRole('button', {
|
|
118
|
+
name: 'Hello Button'
|
|
119
|
+
});
|
|
120
|
+
expect(button).toBeInTheDocument();
|
|
121
|
+
expect(button).not.toHaveAttribute('tabIndex');
|
|
122
|
+
const link = screen.getByRole('link', {
|
|
123
|
+
name: 'Hello link'
|
|
124
|
+
});
|
|
125
|
+
expect(link).toBeInTheDocument();
|
|
126
|
+
expect(link).not.toHaveAttribute('tabIndex');
|
|
127
|
+
});
|
|
108
128
|
it('should pass down the type prop to the button element', async () => {
|
|
109
129
|
const onClick = vi.fn();
|
|
110
130
|
render(/*#__PURE__*/React.createElement(BaseButton, {
|
|
@@ -137,7 +157,7 @@ describe('<BaseButton/>', () => {
|
|
|
137
157
|
button.focus();
|
|
138
158
|
expect(document.activeElement).toBe(button);
|
|
139
159
|
});
|
|
140
|
-
it('should provide an
|
|
160
|
+
it('should provide an elementRef prop', async () => {
|
|
141
161
|
const elementRef = vi.fn();
|
|
142
162
|
render(/*#__PURE__*/React.createElement(BaseButton, {
|
|
143
163
|
elementRef: elementRef
|
package/es/BaseButton/index.js
CHANGED
|
@@ -208,9 +208,25 @@ let BaseButton = (_dec = withStyle(generateStyles, generateComponentTheme), _dec
|
|
|
208
208
|
props = _objectWithoutProperties(_this$props7, _excluded);
|
|
209
209
|
const isDisabled = this.isDisabled,
|
|
210
210
|
isEnabled = this.isEnabled,
|
|
211
|
-
isReadOnly = this.isReadOnly
|
|
211
|
+
isReadOnly = this.isReadOnly,
|
|
212
|
+
elementType = this.elementType;
|
|
213
|
+
// only add 0 tabIndex value if it doesn't have it by default, see
|
|
214
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
|
215
|
+
let needsZeroTabIndex = true;
|
|
216
|
+
if (typeof elementType == 'string') {
|
|
217
|
+
if (['button', 'frame', 'iframe', 'input', 'object', 'select', 'textarea', 'summary'].includes(elementType)) {
|
|
218
|
+
needsZeroTabIndex = false;
|
|
219
|
+
}
|
|
220
|
+
if (href && (elementType === 'a' || elementType === 'area')) {
|
|
221
|
+
needsZeroTabIndex = false;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
let tabIndexValue = tabIndex;
|
|
225
|
+
if (onClick && as && needsZeroTabIndex) {
|
|
226
|
+
tabIndexValue = tabIndex || 0;
|
|
227
|
+
}
|
|
212
228
|
return jsx(View, Object.assign({}, passthroughProps(props), {
|
|
213
|
-
as:
|
|
229
|
+
as: elementType,
|
|
214
230
|
focusColor: this.focusColor,
|
|
215
231
|
position: "relative",
|
|
216
232
|
display: display,
|
|
@@ -227,7 +243,7 @@ let BaseButton = (_dec = withStyle(generateStyles, generateComponentTheme), _dec
|
|
|
227
243
|
onClick: this.handleClick,
|
|
228
244
|
onKeyDown: this.handleKeyDown,
|
|
229
245
|
role: onClick && as !== 'button' ? 'button' : void 0,
|
|
230
|
-
tabIndex:
|
|
246
|
+
tabIndex: tabIndexValue,
|
|
231
247
|
disabled: isDisabled || isReadOnly,
|
|
232
248
|
css: isEnabled ? styles === null || styles === void 0 ? void 0 : styles.baseButton : null,
|
|
233
249
|
focusRingBorderRadius: String(styles === null || styles === void 0 ? void 0 : (_styles$content = styles.content) === null || _styles$content === void 0 ? void 0 : _styles$content.borderRadius)
|
|
@@ -107,6 +107,26 @@ describe('<BaseButton/>', () => {
|
|
|
107
107
|
expect(button).toBeInTheDocument();
|
|
108
108
|
expect(button).toHaveAttribute('tabIndex', '0');
|
|
109
109
|
});
|
|
110
|
+
it('should not set tabIndex="0" when the element has it by default', () => {
|
|
111
|
+
const onClick = _vitest.vi.fn();
|
|
112
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_index.BaseButton, {
|
|
113
|
+
as: "button",
|
|
114
|
+
onClick: onClick
|
|
115
|
+
}, "Hello Button"), /*#__PURE__*/_react.default.createElement(_index.BaseButton, {
|
|
116
|
+
onClick: onClick,
|
|
117
|
+
href: "example.html"
|
|
118
|
+
}, "Hello link")));
|
|
119
|
+
const button = _react2.screen.getByRole('button', {
|
|
120
|
+
name: 'Hello Button'
|
|
121
|
+
});
|
|
122
|
+
expect(button).toBeInTheDocument();
|
|
123
|
+
expect(button).not.toHaveAttribute('tabIndex');
|
|
124
|
+
const link = _react2.screen.getByRole('link', {
|
|
125
|
+
name: 'Hello link'
|
|
126
|
+
});
|
|
127
|
+
expect(link).toBeInTheDocument();
|
|
128
|
+
expect(link).not.toHaveAttribute('tabIndex');
|
|
129
|
+
});
|
|
110
130
|
it('should pass down the type prop to the button element', async () => {
|
|
111
131
|
const onClick = _vitest.vi.fn();
|
|
112
132
|
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.BaseButton, {
|
|
@@ -139,7 +159,7 @@ describe('<BaseButton/>', () => {
|
|
|
139
159
|
button.focus();
|
|
140
160
|
expect(document.activeElement).toBe(button);
|
|
141
161
|
});
|
|
142
|
-
it('should provide an
|
|
162
|
+
it('should provide an elementRef prop', async () => {
|
|
143
163
|
const elementRef = _vitest.vi.fn();
|
|
144
164
|
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.BaseButton, {
|
|
145
165
|
elementRef: elementRef
|
package/lib/BaseButton/index.js
CHANGED
|
@@ -218,9 +218,25 @@ let BaseButton = exports.BaseButton = (_dec = (0, _emotion.withStyle)(_styles.de
|
|
|
218
218
|
props = (0, _objectWithoutProperties2.default)(_this$props7, _excluded);
|
|
219
219
|
const isDisabled = this.isDisabled,
|
|
220
220
|
isEnabled = this.isEnabled,
|
|
221
|
-
isReadOnly = this.isReadOnly
|
|
221
|
+
isReadOnly = this.isReadOnly,
|
|
222
|
+
elementType = this.elementType;
|
|
223
|
+
// only add 0 tabIndex value if it doesn't have it by default, see
|
|
224
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
|
225
|
+
let needsZeroTabIndex = true;
|
|
226
|
+
if (typeof elementType == 'string') {
|
|
227
|
+
if (['button', 'frame', 'iframe', 'input', 'object', 'select', 'textarea', 'summary'].includes(elementType)) {
|
|
228
|
+
needsZeroTabIndex = false;
|
|
229
|
+
}
|
|
230
|
+
if (href && (elementType === 'a' || elementType === 'area')) {
|
|
231
|
+
needsZeroTabIndex = false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let tabIndexValue = tabIndex;
|
|
235
|
+
if (onClick && as && needsZeroTabIndex) {
|
|
236
|
+
tabIndexValue = tabIndex || 0;
|
|
237
|
+
}
|
|
222
238
|
return (0, _emotion.jsx)(_View.View, Object.assign({}, (0, _passthroughProps.passthroughProps)(props), {
|
|
223
|
-
as:
|
|
239
|
+
as: elementType,
|
|
224
240
|
focusColor: this.focusColor,
|
|
225
241
|
position: "relative",
|
|
226
242
|
display: display,
|
|
@@ -237,7 +253,7 @@ let BaseButton = exports.BaseButton = (_dec = (0, _emotion.withStyle)(_styles.de
|
|
|
237
253
|
onClick: this.handleClick,
|
|
238
254
|
onKeyDown: this.handleKeyDown,
|
|
239
255
|
role: onClick && as !== 'button' ? 'button' : void 0,
|
|
240
|
-
tabIndex:
|
|
256
|
+
tabIndex: tabIndexValue,
|
|
241
257
|
disabled: isDisabled || isReadOnly,
|
|
242
258
|
css: isEnabled ? styles === null || styles === void 0 ? void 0 : styles.baseButton : null,
|
|
243
259
|
focusRingBorderRadius: String(styles === null || styles === void 0 ? void 0 : (_styles$content = styles.content) === null || _styles$content === void 0 ? void 0 : _styles$content.borderRadius)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-buttons",
|
|
3
|
-
"version": "10.15.
|
|
3
|
+
"version": "10.15.2-snapshot-0",
|
|
4
4
|
"description": "Accessible button components",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-axe-check": "10.15.
|
|
27
|
-
"@instructure/ui-babel-preset": "10.15.
|
|
28
|
-
"@instructure/ui-test-utils": "10.15.
|
|
29
|
-
"@instructure/ui-themes": "10.15.
|
|
26
|
+
"@instructure/ui-axe-check": "10.15.2-snapshot-0",
|
|
27
|
+
"@instructure/ui-babel-preset": "10.15.2-snapshot-0",
|
|
28
|
+
"@instructure/ui-test-utils": "10.15.2-snapshot-0",
|
|
29
|
+
"@instructure/ui-themes": "10.15.2-snapshot-0",
|
|
30
30
|
"@testing-library/jest-dom": "^6.6.3",
|
|
31
31
|
"@testing-library/react": "^16.0.1",
|
|
32
32
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -34,21 +34,21 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@babel/runtime": "^7.26.0",
|
|
37
|
-
"@instructure/console": "10.15.
|
|
38
|
-
"@instructure/emotion": "10.15.
|
|
39
|
-
"@instructure/shared-types": "10.15.
|
|
40
|
-
"@instructure/ui-a11y-content": "10.15.
|
|
41
|
-
"@instructure/ui-a11y-utils": "10.15.
|
|
42
|
-
"@instructure/ui-color-utils": "10.15.
|
|
43
|
-
"@instructure/ui-dom-utils": "10.15.
|
|
44
|
-
"@instructure/ui-icons": "10.15.
|
|
45
|
-
"@instructure/ui-position": "10.15.
|
|
46
|
-
"@instructure/ui-prop-types": "10.15.
|
|
47
|
-
"@instructure/ui-react-utils": "10.15.
|
|
48
|
-
"@instructure/ui-testable": "10.15.
|
|
49
|
-
"@instructure/ui-tooltip": "10.15.
|
|
50
|
-
"@instructure/ui-utils": "10.15.
|
|
51
|
-
"@instructure/ui-view": "10.15.
|
|
37
|
+
"@instructure/console": "10.15.2-snapshot-0",
|
|
38
|
+
"@instructure/emotion": "10.15.2-snapshot-0",
|
|
39
|
+
"@instructure/shared-types": "10.15.2-snapshot-0",
|
|
40
|
+
"@instructure/ui-a11y-content": "10.15.2-snapshot-0",
|
|
41
|
+
"@instructure/ui-a11y-utils": "10.15.2-snapshot-0",
|
|
42
|
+
"@instructure/ui-color-utils": "10.15.2-snapshot-0",
|
|
43
|
+
"@instructure/ui-dom-utils": "10.15.2-snapshot-0",
|
|
44
|
+
"@instructure/ui-icons": "10.15.2-snapshot-0",
|
|
45
|
+
"@instructure/ui-position": "10.15.2-snapshot-0",
|
|
46
|
+
"@instructure/ui-prop-types": "10.15.2-snapshot-0",
|
|
47
|
+
"@instructure/ui-react-utils": "10.15.2-snapshot-0",
|
|
48
|
+
"@instructure/ui-testable": "10.15.2-snapshot-0",
|
|
49
|
+
"@instructure/ui-tooltip": "10.15.2-snapshot-0",
|
|
50
|
+
"@instructure/ui-utils": "10.15.2-snapshot-0",
|
|
51
|
+
"@instructure/ui-view": "10.15.2-snapshot-0",
|
|
52
52
|
"keycode": "^2",
|
|
53
53
|
"prop-types": "^15.8.1"
|
|
54
54
|
},
|
|
@@ -126,6 +126,27 @@ describe('<BaseButton/>', () => {
|
|
|
126
126
|
expect(button).toHaveAttribute('tabIndex', '0')
|
|
127
127
|
})
|
|
128
128
|
|
|
129
|
+
it('should not set tabIndex="0" when the element has it by default', () => {
|
|
130
|
+
const onClick = vi.fn()
|
|
131
|
+
|
|
132
|
+
render(
|
|
133
|
+
<>
|
|
134
|
+
<BaseButton as="button" onClick={onClick}>
|
|
135
|
+
Hello Button
|
|
136
|
+
</BaseButton>
|
|
137
|
+
<BaseButton onClick={onClick} href="example.html">
|
|
138
|
+
Hello link
|
|
139
|
+
</BaseButton>
|
|
140
|
+
</>
|
|
141
|
+
)
|
|
142
|
+
const button = screen.getByRole('button', { name: 'Hello Button' })
|
|
143
|
+
expect(button).toBeInTheDocument()
|
|
144
|
+
expect(button).not.toHaveAttribute('tabIndex')
|
|
145
|
+
const link = screen.getByRole('link', { name: 'Hello link' })
|
|
146
|
+
expect(link).toBeInTheDocument()
|
|
147
|
+
expect(link).not.toHaveAttribute('tabIndex')
|
|
148
|
+
})
|
|
149
|
+
|
|
129
150
|
it('should pass down the type prop to the button element', async () => {
|
|
130
151
|
const onClick = vi.fn()
|
|
131
152
|
render(
|
|
@@ -163,7 +184,7 @@ describe('<BaseButton/>', () => {
|
|
|
163
184
|
expect(document.activeElement).toBe(button)
|
|
164
185
|
})
|
|
165
186
|
|
|
166
|
-
it('should provide an
|
|
187
|
+
it('should provide an elementRef prop', async () => {
|
|
167
188
|
const elementRef = vi.fn()
|
|
168
189
|
render(<BaseButton elementRef={elementRef}>Hello World</BaseButton>)
|
|
169
190
|
|
package/src/BaseButton/index.tsx
CHANGED
|
@@ -255,12 +255,37 @@ class BaseButton extends Component<BaseButtonProps> {
|
|
|
255
255
|
...props
|
|
256
256
|
} = this.props
|
|
257
257
|
|
|
258
|
-
const { isDisabled, isEnabled, isReadOnly } = this
|
|
259
|
-
|
|
258
|
+
const { isDisabled, isEnabled, isReadOnly, elementType } = this
|
|
259
|
+
// only add 0 tabIndex value if it doesn't have it by default, see
|
|
260
|
+
// https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
|
|
261
|
+
let needsZeroTabIndex = true
|
|
262
|
+
if (typeof elementType == 'string') {
|
|
263
|
+
if (
|
|
264
|
+
[
|
|
265
|
+
'button',
|
|
266
|
+
'frame',
|
|
267
|
+
'iframe',
|
|
268
|
+
'input',
|
|
269
|
+
'object',
|
|
270
|
+
'select',
|
|
271
|
+
'textarea',
|
|
272
|
+
'summary'
|
|
273
|
+
].includes(elementType)
|
|
274
|
+
) {
|
|
275
|
+
needsZeroTabIndex = false
|
|
276
|
+
}
|
|
277
|
+
if (href && (elementType === 'a' || elementType === 'area')) {
|
|
278
|
+
needsZeroTabIndex = false
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
let tabIndexValue = tabIndex
|
|
282
|
+
if (onClick && as && needsZeroTabIndex) {
|
|
283
|
+
tabIndexValue = tabIndex || 0
|
|
284
|
+
}
|
|
260
285
|
return (
|
|
261
286
|
<View
|
|
262
287
|
{...passthroughProps(props)}
|
|
263
|
-
as={
|
|
288
|
+
as={elementType}
|
|
264
289
|
focusColor={this.focusColor}
|
|
265
290
|
position="relative"
|
|
266
291
|
display={display}
|
|
@@ -277,7 +302,7 @@ class BaseButton extends Component<BaseButtonProps> {
|
|
|
277
302
|
onClick={this.handleClick}
|
|
278
303
|
onKeyDown={this.handleKeyDown}
|
|
279
304
|
role={onClick && as !== 'button' ? 'button' : undefined}
|
|
280
|
-
tabIndex={
|
|
305
|
+
tabIndex={tabIndexValue}
|
|
281
306
|
disabled={isDisabled || isReadOnly}
|
|
282
307
|
css={isEnabled ? styles?.baseButton : null}
|
|
283
308
|
focusRingBorderRadius={String(
|