@instructure/ui-tabs 11.7.10 → 11.7.11-snapshot-4
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 +7 -0
- package/es/Tabs/v2/Tab/index.js +21 -2
- package/es/Tabs/v2/Tab/props.js +1 -1
- package/es/Tabs/v2/index.js +195 -85
- package/es/Tabs/v2/props.js +1 -1
- package/lib/Tabs/v2/Tab/index.js +21 -2
- package/lib/Tabs/v2/Tab/props.js +1 -1
- package/lib/Tabs/v2/index.js +194 -84
- package/lib/Tabs/v2/props.js +1 -1
- package/package.json +16 -16
- package/src/Tabs/v2/README.md +57 -1
- package/src/Tabs/v2/Tab/index.tsx +16 -2
- package/src/Tabs/v2/Tab/props.ts +7 -0
- package/src/Tabs/v2/index.tsx +227 -124
- package/src/Tabs/v2/props.ts +10 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Tabs/v2/Tab/index.d.ts +6 -0
- package/types/Tabs/v2/Tab/index.d.ts.map +1 -1
- package/types/Tabs/v2/Tab/props.d.ts +5 -0
- package/types/Tabs/v2/Tab/props.d.ts.map +1 -1
- package/types/Tabs/v2/index.d.ts +25 -13
- package/types/Tabs/v2/index.d.ts.map +1 -1
- package/types/Tabs/v2/props.d.ts +8 -0
- package/types/Tabs/v2/props.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
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
|
+
## [11.7.11-snapshot-4](https://github.com/instructure/instructure-ui/compare/v11.7.10...v11.7.11-snapshot-4) (2026-10-22)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **ui-tabs:** add roving tabindex and manual activation mode ([#2723](https://github.com/instructure/instructure-ui/issues/2723)) ([bc4bbdc](https://github.com/instructure/instructure-ui/commit/bc4bbdc3def4f353f8dc7b5e6ef672625e9efb1b))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
## [11.7.10](https://github.com/instructure/instructure-ui/compare/v11.7.8...v11.7.10) (2026-10-14)
|
|
7
14
|
|
|
8
15
|
**Note:** Version bump only for package @instructure/ui-tabs
|
package/es/Tabs/v2/Tab/index.js
CHANGED
|
@@ -86,12 +86,30 @@ let Tab = (_dec = withStyleNew(generateStyle), _dec(_class = class Tab extends C
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
|
+
handleFocus = event => {
|
|
90
|
+
const {
|
|
91
|
+
onFocus,
|
|
92
|
+
index,
|
|
93
|
+
id,
|
|
94
|
+
isDisabled
|
|
95
|
+
} = this.props;
|
|
96
|
+
if (isDisabled) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (typeof onFocus === 'function') {
|
|
100
|
+
onFocus(event, {
|
|
101
|
+
index,
|
|
102
|
+
id
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
};
|
|
89
106
|
render() {
|
|
90
107
|
const {
|
|
91
108
|
id,
|
|
92
109
|
variant,
|
|
93
110
|
isSelected,
|
|
94
111
|
isDisabled,
|
|
112
|
+
isTabbable = isSelected,
|
|
95
113
|
controls,
|
|
96
114
|
children,
|
|
97
115
|
styles,
|
|
@@ -104,11 +122,12 @@ let Tab = (_dec = withStyleNew(generateStyle), _dec(_class = class Tab extends C
|
|
|
104
122
|
id: id,
|
|
105
123
|
onClick: this.handleClick,
|
|
106
124
|
onKeyDown: this.handleKeyDown,
|
|
125
|
+
onFocus: this.handleFocus,
|
|
107
126
|
css: styles?.tab,
|
|
108
|
-
"aria-selected": isSelected ? 'true' :
|
|
127
|
+
"aria-selected": isSelected ? 'true' : 'false',
|
|
109
128
|
"aria-disabled": isDisabled ? 'true' : undefined,
|
|
110
129
|
"aria-controls": controls,
|
|
111
|
-
tabIndex:
|
|
130
|
+
tabIndex: isDisabled ? undefined : isTabbable ? 0 : -1,
|
|
112
131
|
position: "relative",
|
|
113
132
|
focusPosition: "offset",
|
|
114
133
|
children: callRenderProp(children)
|
package/es/Tabs/v2/Tab/props.js
CHANGED
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
const allowedProps = ['variant', 'id', 'index', 'controls', 'isDisabled', 'isSelected', 'onClick', 'onKeyDown', 'children', 'isOverflowScroll'];
|
|
25
|
+
const allowedProps = ['variant', 'id', 'index', 'controls', 'isDisabled', 'isSelected', 'isTabbable', 'onClick', 'onKeyDown', 'onFocus', 'children', 'isOverflowScroll'];
|
|
26
26
|
export { allowedProps };
|
package/es/Tabs/v2/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _dec, _dec2, _class;
|
|
1
|
+
var _dec, _dec2, _dec3, _class;
|
|
2
2
|
/*
|
|
3
3
|
* The MIT License (MIT)
|
|
4
4
|
*
|
|
@@ -28,8 +28,8 @@ import keycode from 'keycode';
|
|
|
28
28
|
import { View } from '@instructure/ui-view/latest';
|
|
29
29
|
import { matchComponentTypes, safeCloneElement, passthroughProps, withDeterministicId } from '@instructure/ui-react-utils';
|
|
30
30
|
import { logError as error } from '@instructure/console';
|
|
31
|
-
import {
|
|
32
|
-
import { getBoundingClientRect } from '@instructure/ui-dom-utils';
|
|
31
|
+
import { textDirectionContextConsumer } from '@instructure/ui-i18n';
|
|
32
|
+
import { contains, getBoundingClientRect } from '@instructure/ui-dom-utils';
|
|
33
33
|
import { debounce } from '@instructure/debounce';
|
|
34
34
|
import { px } from '@instructure/ui-utils';
|
|
35
35
|
import { withStyleNew } from '@instructure/emotion';
|
|
@@ -43,19 +43,19 @@ import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
|
43
43
|
category: components
|
|
44
44
|
---
|
|
45
45
|
**/
|
|
46
|
-
let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _dec(_class = _dec2(_class = class Tabs extends Component {
|
|
46
|
+
let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _dec3 = textDirectionContextConsumer(), _dec(_class = _dec2(_class = _dec3(_class = class Tabs extends Component {
|
|
47
47
|
static displayName = 'Tabs';
|
|
48
48
|
static componentId = 'Tabs';
|
|
49
49
|
static allowedProps = allowedProps;
|
|
50
50
|
static defaultProps = {
|
|
51
51
|
variant: 'default',
|
|
52
52
|
shouldFocusOnRender: false,
|
|
53
|
-
tabOverflow: 'stack'
|
|
53
|
+
tabOverflow: 'stack',
|
|
54
|
+
activationMode: 'auto'
|
|
54
55
|
};
|
|
55
56
|
static Panel = Panel;
|
|
56
57
|
static Tab = Tab;
|
|
57
58
|
_tabList = null;
|
|
58
|
-
_focusable = null;
|
|
59
59
|
_tabListPosition;
|
|
60
60
|
_debounced;
|
|
61
61
|
_resizeListener;
|
|
@@ -185,26 +185,74 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
+
get isRtl() {
|
|
189
|
+
return this.props.dir === textDirectionContextConsumer.DIRECTION.rtl;
|
|
190
|
+
}
|
|
188
191
|
handleTabClick = (event, {
|
|
189
192
|
index
|
|
190
193
|
}) => {
|
|
191
|
-
const
|
|
192
|
-
|
|
194
|
+
const target = this.getNextTab(this.getTabs(), index, 0);
|
|
195
|
+
if (target) {
|
|
196
|
+
this.fireOnChange(event, target);
|
|
197
|
+
}
|
|
193
198
|
};
|
|
194
199
|
handleTabKeyDown = (event, {
|
|
195
200
|
index
|
|
196
201
|
}) => {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
const tabs = this.getTabs();
|
|
203
|
+
let target;
|
|
204
|
+
let isActivation = false;
|
|
205
|
+
switch (event.keyCode) {
|
|
206
|
+
case keycode.codes.left:
|
|
207
|
+
target = this.getNextTab(tabs, index, this.isRtl ? 1 : -1);
|
|
208
|
+
break;
|
|
209
|
+
case keycode.codes.right:
|
|
210
|
+
target = this.getNextTab(tabs, index, this.isRtl ? -1 : 1);
|
|
211
|
+
break;
|
|
212
|
+
case keycode.codes.up:
|
|
213
|
+
target = this.getNextTab(tabs, index, -1);
|
|
214
|
+
break;
|
|
215
|
+
case keycode.codes.down:
|
|
216
|
+
target = this.getNextTab(tabs, index, 1);
|
|
217
|
+
break;
|
|
218
|
+
case keycode.codes.home:
|
|
219
|
+
target = this.getEdgeTab(tabs, 'first');
|
|
220
|
+
break;
|
|
221
|
+
case keycode.codes.end:
|
|
222
|
+
target = this.getEdgeTab(tabs, 'last');
|
|
223
|
+
break;
|
|
224
|
+
case keycode.codes.enter:
|
|
225
|
+
case keycode.codes.space:
|
|
226
|
+
target = this.getNextTab(tabs, index, 0);
|
|
227
|
+
isActivation = true;
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
return;
|
|
204
231
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
232
|
+
event.stopPropagation();
|
|
233
|
+
event.preventDefault();
|
|
234
|
+
if (!target) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (isActivation || this.props.activationMode !== 'manual') {
|
|
238
|
+
this.fireOnChange(event, target);
|
|
239
|
+
}
|
|
240
|
+
this.focusTab(target.tabDomId);
|
|
241
|
+
};
|
|
242
|
+
handleTabFocus = (_event, {
|
|
243
|
+
id
|
|
244
|
+
}) => {
|
|
245
|
+
if (this.state.focusedTabId !== id) {
|
|
246
|
+
this.setState({
|
|
247
|
+
focusedTabId: id
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
handleTabListBlur = event => {
|
|
252
|
+
if (!contains(event.currentTarget, event.relatedTarget)) {
|
|
253
|
+
this.setState({
|
|
254
|
+
focusedTabId: undefined
|
|
255
|
+
});
|
|
208
256
|
}
|
|
209
257
|
};
|
|
210
258
|
handleResize = () => {
|
|
@@ -213,67 +261,129 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
213
261
|
});
|
|
214
262
|
this._tabListPosition = getBoundingClientRect(this._tabList);
|
|
215
263
|
};
|
|
216
|
-
|
|
217
|
-
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The single source of truth for tab order, ids and state.
|
|
267
|
+
*/
|
|
268
|
+
getTabs() {
|
|
269
|
+
const panels = [];
|
|
270
|
+
Children.toArray(this.props.children).forEach((child, index) => {
|
|
271
|
+
if (matchComponentTypes(child, [Panel])) {
|
|
272
|
+
panels.push({
|
|
273
|
+
index,
|
|
274
|
+
panel: child
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
const explicitlySelected = panels.find(({
|
|
279
|
+
panel
|
|
280
|
+
}) => panel.props.isSelected && !panel.props.isDisabled);
|
|
281
|
+
const fallbackIndex = explicitlySelected ? explicitlySelected.index : 0;
|
|
282
|
+
return panels.map(({
|
|
283
|
+
index,
|
|
284
|
+
panel
|
|
285
|
+
}) => {
|
|
286
|
+
const baseId = panel.props.id || this.props.deterministicId(`Tabs_${index}`);
|
|
287
|
+
const isDisabled = !!panel.props.isDisabled;
|
|
288
|
+
return {
|
|
289
|
+
index,
|
|
290
|
+
tabDomId: `tab-${baseId}`,
|
|
291
|
+
panelDomId: panel.props.id || `panel-${baseId}`,
|
|
292
|
+
isDisabled,
|
|
293
|
+
isSelected: !isDisabled && (!!panel.props.isSelected || index === fallbackIndex),
|
|
294
|
+
panel
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
getNextTab(tabs, startIndex, step) {
|
|
218
299
|
const count = tabs.length;
|
|
219
|
-
const
|
|
220
|
-
error(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
300
|
+
const from = tabs.findIndex(tab => tab.index === startIndex);
|
|
301
|
+
error(from >= 0, `[Tabs] Invalid tab index: '${startIndex}'.`);
|
|
302
|
+
if (from < 0) {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
if (step === 0) {
|
|
306
|
+
return tabs[from];
|
|
307
|
+
}
|
|
308
|
+
for (let offset = 1; offset <= count; offset++) {
|
|
309
|
+
const candidate = tabs[((from + step * offset) % count + count) % count];
|
|
310
|
+
if (!candidate.isDisabled) {
|
|
311
|
+
return candidate;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
getEdgeTab(tabs, edge) {
|
|
317
|
+
const enabled = tabs.filter(tab => !tab.isDisabled);
|
|
318
|
+
return edge === 'first' ? enabled[0] : enabled[enabled.length - 1];
|
|
319
|
+
}
|
|
320
|
+
getRovingTabId(tabs) {
|
|
321
|
+
const {
|
|
322
|
+
focusedTabId
|
|
323
|
+
} = this.state;
|
|
324
|
+
const focused = tabs.find(tab => tab.tabDomId === focusedTabId && !tab.isDisabled);
|
|
325
|
+
return focused?.tabDomId ?? tabs.find(tab => tab.isSelected)?.tabDomId ?? tabs.find(tab => !tab.isDisabled)?.tabDomId;
|
|
232
326
|
}
|
|
233
327
|
fireOnChange(event, {
|
|
234
328
|
index,
|
|
235
|
-
|
|
329
|
+
panel,
|
|
330
|
+
tabDomId
|
|
236
331
|
}) {
|
|
237
332
|
if (typeof this.props.onRequestTabChange === 'function') {
|
|
238
333
|
this.props.onRequestTabChange(event, {
|
|
239
334
|
index,
|
|
240
|
-
id
|
|
335
|
+
id: panel.props.id
|
|
241
336
|
});
|
|
242
337
|
}
|
|
243
|
-
|
|
244
|
-
|
|
338
|
+
this.scrollTabIntoView(tabDomId);
|
|
339
|
+
}
|
|
340
|
+
scrollTabIntoView(tabDomId) {
|
|
245
341
|
// one "tick" later than the keypress
|
|
246
342
|
setTimeout(() => {
|
|
247
343
|
if (this.state.withTabListOverflow) {
|
|
248
|
-
|
|
249
|
-
this.showActiveTabIfOverlayed(tab);
|
|
344
|
+
this.showActiveTabIfOverlayed(this._tabList.querySelector(`#${CSS.escape(tabDomId)}`));
|
|
250
345
|
}
|
|
251
346
|
}, 0);
|
|
252
347
|
}
|
|
253
|
-
createTab(
|
|
254
|
-
const
|
|
348
|
+
createTab(tab, isTabbable) {
|
|
349
|
+
const {
|
|
350
|
+
index,
|
|
351
|
+
tabDomId,
|
|
352
|
+
panelDomId,
|
|
353
|
+
isSelected,
|
|
354
|
+
isDisabled,
|
|
355
|
+
panel
|
|
356
|
+
} = tab;
|
|
255
357
|
return _jsx(Tab, {
|
|
256
358
|
variant: this.props.variant,
|
|
257
|
-
id:
|
|
258
|
-
controls:
|
|
359
|
+
id: tabDomId,
|
|
360
|
+
controls: panelDomId,
|
|
259
361
|
index: index,
|
|
260
|
-
isSelected:
|
|
261
|
-
isDisabled:
|
|
362
|
+
isSelected: isSelected,
|
|
363
|
+
isDisabled: isDisabled,
|
|
364
|
+
isTabbable: isTabbable,
|
|
262
365
|
onClick: this.handleTabClick,
|
|
263
366
|
onKeyDown: this.handleTabKeyDown,
|
|
367
|
+
onFocus: this.handleTabFocus,
|
|
264
368
|
isOverflowScroll: this.props.tabOverflow === 'scroll',
|
|
265
369
|
children: panel.props.renderTitle
|
|
266
370
|
}, `tab-${index}`);
|
|
267
371
|
}
|
|
268
|
-
clonePanel(
|
|
269
|
-
const
|
|
372
|
+
clonePanel(tab, activePanel) {
|
|
373
|
+
const {
|
|
374
|
+
index,
|
|
375
|
+
tabDomId,
|
|
376
|
+
panelDomId,
|
|
377
|
+
isSelected,
|
|
378
|
+
panel
|
|
379
|
+
} = tab;
|
|
270
380
|
|
|
271
381
|
// fixHeight can be 0, so simply `fixheight` could return falsy value
|
|
272
382
|
const hasFixedHeight = typeof this.props.fixHeight !== 'undefined';
|
|
273
383
|
const commonProps = {
|
|
274
|
-
id:
|
|
275
|
-
labelledBy:
|
|
276
|
-
isSelected
|
|
384
|
+
id: panelDomId,
|
|
385
|
+
labelledBy: tabDomId,
|
|
386
|
+
isSelected,
|
|
277
387
|
variant: this.props.variant,
|
|
278
388
|
maxHeight: !hasFixedHeight ? this.props.maxHeight : undefined,
|
|
279
389
|
minHeight: !hasFixedHeight ? this.props.minHeight : '100%'
|
|
@@ -299,14 +409,19 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
299
409
|
});
|
|
300
410
|
}
|
|
301
411
|
}
|
|
302
|
-
handleFocusableRef = el => {
|
|
303
|
-
this._focusable = el;
|
|
304
|
-
};
|
|
305
412
|
handleTabListRef = el => {
|
|
306
413
|
this._tabList = el;
|
|
307
414
|
};
|
|
308
415
|
focus() {
|
|
309
|
-
this.
|
|
416
|
+
this.focusTab(this.getRovingTabId(this.getTabs()));
|
|
417
|
+
}
|
|
418
|
+
focusTab(tabDomId) {
|
|
419
|
+
if (!tabDomId) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
const tab = this._tabList?.querySelector(`#${CSS.escape(tabDomId)}`);
|
|
423
|
+
tab?.focus();
|
|
424
|
+
this.scrollTabIntoView(tabDomId);
|
|
310
425
|
}
|
|
311
426
|
handleScroll = event => {
|
|
312
427
|
if (this.props.tabOverflow !== 'scroll' || !this.state.withTabListOverflow) {
|
|
@@ -334,27 +449,24 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
334
449
|
onRequestTabChange,
|
|
335
450
|
tabOverflow,
|
|
336
451
|
styles,
|
|
452
|
+
dir,
|
|
337
453
|
...props
|
|
338
454
|
} = this.props;
|
|
339
|
-
const
|
|
455
|
+
const tabDescriptors = this.getTabs();
|
|
456
|
+
const rovingTabId = this.getRovingTabId(tabDescriptors);
|
|
457
|
+
const tabsByIndex = new Map(tabDescriptors.map(tab => [tab.index, tab]));
|
|
458
|
+
const activePanels = tabDescriptors.map(tab => tab.panel).filter(panel => panel.props.active);
|
|
340
459
|
if (activePanels.length > 1) {
|
|
341
460
|
error(false, `[Tabs] Only one Panel can be marked as active.`);
|
|
342
461
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
if (matchComponentTypes(child, [Panel])) {
|
|
347
|
-
const selected = !child.props.isDisabled && (child.props.isSelected || selectedIndex === index);
|
|
348
|
-
const id = this.props.deterministicId(`Tabs_${index}`);
|
|
349
|
-
tabs.push(this.createTab(index, id, selected, child));
|
|
350
|
-
if (activePanels.length === 1) {
|
|
351
|
-
panels.push(this.clonePanel(index, id, selected, child, activePanels[0]));
|
|
352
|
-
} else {
|
|
353
|
-
panels.push(this.clonePanel(index, id, selected, child));
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
462
|
+
Children.toArray(children).forEach((child, index) => {
|
|
463
|
+
const tab = tabsByIndex.get(index);
|
|
464
|
+
if (!tab) {
|
|
356
465
|
panels.push(child);
|
|
466
|
+
return;
|
|
357
467
|
}
|
|
468
|
+
tabs.push(this.createTab(tab, tab.tabDomId === rovingTabId));
|
|
469
|
+
panels.push(this.clonePanel(tab, activePanels.length === 1 ? activePanels[0] : undefined));
|
|
358
470
|
});
|
|
359
471
|
const withScrollFade = tabOverflow === 'scroll' && this.state.withTabListOverflow;
|
|
360
472
|
|
|
@@ -373,23 +485,21 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
373
485
|
as: "div",
|
|
374
486
|
css: styles?.container,
|
|
375
487
|
"data-cid": "Tabs",
|
|
376
|
-
children: [_jsx(
|
|
377
|
-
|
|
378
|
-
|
|
488
|
+
children: [_jsx(View, {
|
|
489
|
+
as: "div",
|
|
490
|
+
position: "relative",
|
|
491
|
+
borderRadius: "medium",
|
|
492
|
+
shouldAnimateFocus: false,
|
|
493
|
+
css: styles?.tabs,
|
|
494
|
+
children: _jsxs(View, {
|
|
379
495
|
as: "div",
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
css: styles?.tabList,
|
|
388
|
-
"aria-label": screenReaderLabel,
|
|
389
|
-
elementRef: this.handleTabListRef,
|
|
390
|
-
onScroll: this.handleScroll,
|
|
391
|
-
children: [tabs, withScrollFade && startScrollOverlay, withScrollFade && endScrollOverlay]
|
|
392
|
-
})
|
|
496
|
+
role: "tablist",
|
|
497
|
+
css: styles?.tabList,
|
|
498
|
+
"aria-label": screenReaderLabel,
|
|
499
|
+
elementRef: this.handleTabListRef,
|
|
500
|
+
onScroll: this.handleScroll,
|
|
501
|
+
onBlur: this.handleTabListBlur,
|
|
502
|
+
children: [tabs, withScrollFade && startScrollOverlay, withScrollFade && endScrollOverlay]
|
|
393
503
|
})
|
|
394
504
|
}), _jsx("div", {
|
|
395
505
|
css: styles?.panelsContainer,
|
|
@@ -397,6 +507,6 @@ let Tabs = (_dec = withDeterministicId(), _dec2 = withStyleNew(generateStyle), _
|
|
|
397
507
|
})]
|
|
398
508
|
});
|
|
399
509
|
}
|
|
400
|
-
}) || _class) || _class);
|
|
510
|
+
}) || _class) || _class) || _class);
|
|
401
511
|
export default Tabs;
|
|
402
512
|
export { Tabs, Panel };
|
package/es/Tabs/v2/props.js
CHANGED
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
const allowedProps = ['children', 'variant', 'screenReaderLabel', 'onRequestTabChange', 'maxWidth', 'maxHeight', 'minHeight', 'fixHeight', 'margin', 'padding', 'textAlign', 'elementRef', 'tabOverflow', 'shouldFocusOnRender'];
|
|
25
|
+
const allowedProps = ['children', 'variant', 'screenReaderLabel', 'onRequestTabChange', 'maxWidth', 'maxHeight', 'minHeight', 'fixHeight', 'margin', 'padding', 'textAlign', 'elementRef', 'tabOverflow', 'shouldFocusOnRender', 'activationMode'];
|
|
26
26
|
export { allowedProps };
|
package/lib/Tabs/v2/Tab/index.js
CHANGED
|
@@ -91,12 +91,30 @@ let Tab = exports.Tab = (_dec = (0, _emotion.withStyleNew)(_styles.default), _de
|
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
|
+
handleFocus = event => {
|
|
95
|
+
const {
|
|
96
|
+
onFocus,
|
|
97
|
+
index,
|
|
98
|
+
id,
|
|
99
|
+
isDisabled
|
|
100
|
+
} = this.props;
|
|
101
|
+
if (isDisabled) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (typeof onFocus === 'function') {
|
|
105
|
+
onFocus(event, {
|
|
106
|
+
index,
|
|
107
|
+
id
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|
|
94
111
|
render() {
|
|
95
112
|
const {
|
|
96
113
|
id,
|
|
97
114
|
variant,
|
|
98
115
|
isSelected,
|
|
99
116
|
isDisabled,
|
|
117
|
+
isTabbable = isSelected,
|
|
100
118
|
controls,
|
|
101
119
|
children,
|
|
102
120
|
styles,
|
|
@@ -109,11 +127,12 @@ let Tab = exports.Tab = (_dec = (0, _emotion.withStyleNew)(_styles.default), _de
|
|
|
109
127
|
id: id,
|
|
110
128
|
onClick: this.handleClick,
|
|
111
129
|
onKeyDown: this.handleKeyDown,
|
|
130
|
+
onFocus: this.handleFocus,
|
|
112
131
|
css: styles?.tab,
|
|
113
|
-
"aria-selected": isSelected ? 'true' :
|
|
132
|
+
"aria-selected": isSelected ? 'true' : 'false',
|
|
114
133
|
"aria-disabled": isDisabled ? 'true' : undefined,
|
|
115
134
|
"aria-controls": controls,
|
|
116
|
-
tabIndex:
|
|
135
|
+
tabIndex: isDisabled ? undefined : isTabbable ? 0 : -1,
|
|
117
136
|
position: "relative",
|
|
118
137
|
focusPosition: "offset",
|
|
119
138
|
children: (0, _uiReactUtils.callRenderProp)(children)
|
package/lib/Tabs/v2/Tab/props.js
CHANGED
|
@@ -28,4 +28,4 @@ exports.allowedProps = void 0;
|
|
|
28
28
|
* SOFTWARE.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
const allowedProps = exports.allowedProps = ['variant', 'id', 'index', 'controls', 'isDisabled', 'isSelected', 'onClick', 'onKeyDown', 'children', 'isOverflowScroll'];
|
|
31
|
+
const allowedProps = exports.allowedProps = ['variant', 'id', 'index', 'controls', 'isDisabled', 'isSelected', 'isTabbable', 'onClick', 'onKeyDown', 'onFocus', 'children', 'isOverflowScroll'];
|