kopia lustrzana https://github.com/shoelace-style/shoelace
improve tab accessibility
rodzic
673dc29dfe
commit
864d567572
|
@ -14,6 +14,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
- Fixed a bug in `<sl-tab-group>` where the divider was on the wrong side when using `placement="end"`
|
||||
- Fixed a bug in `<sl-tab-group>` that caused nested tab groups to scroll when using `placement="start|end"` [#815](https://github.com/shoelace-style/shoelace/issues/815)
|
||||
- Fixed a bug in `<sl-tooltip>` that caused the target to be lost after a slot change [#831](https://github.com/shoelace-style/shoelace/pull/831)
|
||||
- Improved accessibility of `<sl-tab-group>`, `<sl-tab>`, and `<sl-tab-panel>` to work better with screen readers
|
||||
- Updated Bootstrap Icons to 1.9.1
|
||||
- Updated Floating UI to 1.0.0
|
||||
|
||||
|
|
|
@ -122,14 +122,9 @@ export default class SlTabGroup extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
getAllTabs(includeDisabled = false) {
|
||||
getAllTabs() {
|
||||
const slot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot[name="nav"]')!;
|
||||
|
||||
return [...(slot.assignedElements() as SlTab[])].filter(el => {
|
||||
return includeDisabled
|
||||
? el.tagName.toLowerCase() === 'sl-tab'
|
||||
: el.tagName.toLowerCase() === 'sl-tab' && !el.disabled;
|
||||
});
|
||||
return [...(slot.assignedElements() as SlTab[])].filter(el => el.tagName.toLowerCase() === 'sl-tab');
|
||||
}
|
||||
|
||||
getAllPanels() {
|
||||
|
@ -318,7 +313,7 @@ export default class SlTabGroup extends LitElement {
|
|||
|
||||
// We can't used offsetLeft/offsetTop here due to a shadow parent issue where neither can getBoundingClientRect
|
||||
// because it provides invalid values for animating elements: https://bugs.chromium.org/p/chromium/issues/detail?id=920069
|
||||
const allTabs = this.getAllTabs(true);
|
||||
const allTabs = this.getAllTabs();
|
||||
const precedingTabs = allTabs.slice(0, allTabs.indexOf(currentTab));
|
||||
const offset = precedingTabs.reduce(
|
||||
(previous, current) => ({
|
||||
|
|
|
@ -2,6 +2,7 @@ import { html, LitElement } from 'lit';
|
|||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { autoIncrement } from '../../internal/auto-increment';
|
||||
import { watch } from '../../internal/watch';
|
||||
import styles from './tab-panel.styles';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
|
||||
|
@ -31,6 +32,12 @@ export default class SlTabPanel extends LitElement {
|
|||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.id = this.id.length > 0 ? this.id : this.componentId;
|
||||
this.setAttribute('role', 'tabpanel');
|
||||
}
|
||||
|
||||
@watch('active')
|
||||
handleActiveChange() {
|
||||
this.setAttribute('aria-hidden', this.active ? 'false' : 'true');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -41,8 +48,6 @@ export default class SlTabPanel extends LitElement {
|
|||
'tab-panel': true,
|
||||
'tab-panel--active': this.active
|
||||
})}
|
||||
role="tabpanel"
|
||||
aria-hidden=${this.active ? 'false' : 'true'}
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { classMap } from 'lit/directives/class-map.js';
|
|||
import '../../components/icon-button/icon-button';
|
||||
import { autoIncrement } from '../../internal/auto-increment';
|
||||
import { emit } from '../../internal/event';
|
||||
import { watch } from '../../internal/watch';
|
||||
import { LocalizeController } from '../../utilities/localize';
|
||||
import styles from './tab.styles';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
|
@ -47,6 +48,11 @@ export default class SlTab extends LitElement {
|
|||
/** The locale to render the component in. */
|
||||
@property() lang: string;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.setAttribute('role', 'tab');
|
||||
}
|
||||
|
||||
/** Sets focus to the tab. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.tab.focus(options);
|
||||
|
@ -61,6 +67,16 @@ export default class SlTab extends LitElement {
|
|||
emit(this, 'sl-close');
|
||||
}
|
||||
|
||||
@watch('active')
|
||||
handleActiveChange() {
|
||||
this.setAttribute('aria-selected', this.active ? 'true' : 'false');
|
||||
}
|
||||
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
render() {
|
||||
// If the user didn't provide an ID, we'll set one so we can link tabs and tab panels with aria labels
|
||||
this.id = this.id.length > 0 ? this.id : this.componentId;
|
||||
|
@ -74,10 +90,7 @@ export default class SlTab extends LitElement {
|
|||
'tab--closable': this.closable,
|
||||
'tab--disabled': this.disabled
|
||||
})}
|
||||
role="tab"
|
||||
aria-disabled=${this.disabled ? 'true' : 'false'}
|
||||
aria-selected=${this.active ? 'true' : 'false'}
|
||||
tabindex=${this.disabled || !this.active ? '-1' : '0'}
|
||||
tabindex="0"
|
||||
>
|
||||
<slot></slot>
|
||||
${this.closable
|
||||
|
|
Ładowanie…
Reference in New Issue