diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index c18d4a6e0..87690312f 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -14,7 +14,8 @@ _During the beta period, these restrictions may be relaxed in the event of a mis - Fixed a bug in `` where the divider was on the wrong side when using `placement="end"` - Fixed a bug in `` 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 `` that caused the target to be lost after a slot change [#831](https://github.com/shoelace-style/shoelace/pull/831) -- Improved accessibility of ``, ``, and `` to work better with screen readers +- Improved accessibility of ``, ``, and `` to announce better in screen readers and by allowing focus on disabled items +- Improved accessibility of `` and `` by allowing focus on disabled items - Updated Bootstrap Icons to 1.9.1 - Updated Floating UI to 1.0.0 diff --git a/src/components/menu-item/menu-item.styles.ts b/src/components/menu-item/menu-item.styles.ts index 2cef791b1..70f7e283e 100644 --- a/src/components/menu-item/menu-item.styles.ts +++ b/src/components/menu-item/menu-item.styles.ts @@ -27,7 +27,7 @@ export default css` .menu-item.menu-item--disabled { outline: none; - color: var(--sl-color-neutral-400); + opacity: 0.5; cursor: not-allowed; } @@ -59,8 +59,8 @@ export default css` outline: none; } - :host(:hover:not([aria-disabled='true'])) .menu-item, - :host(:focus-visible:not(.sl-focus-invisible):not([aria-disabled='true'])) .menu-item { + :host(:hover) .menu-item, + :host(:focus-visible:not(.sl-focus-invisible)) .menu-item { outline: none; background-color: var(--sl-color-primary-600); color: var(--sl-color-neutral-0); diff --git a/src/components/menu/menu.ts b/src/components/menu/menu.ts index 4a26a9358..45f26dc27 100644 --- a/src/components/menu/menu.ts +++ b/src/components/menu/menu.ts @@ -29,21 +29,14 @@ export default class SlMenu extends LitElement { private typeToSelectString = ''; private typeToSelectTimeout: number; - firstUpdated() { + connectedCallback() { + super.connectedCallback(); this.setAttribute('role', 'menu'); } - getAllItems(options: { includeDisabled: boolean } = { includeDisabled: true }) { + getAllItems() { return [...this.defaultSlot.assignedElements({ flatten: true })].filter((el: HTMLElement) => { - if (el.getAttribute('role') !== 'menuitem') { - return false; - } - - if (!options.includeDisabled && (el as SlMenuItem).disabled) { - return false; - } - - return true; + return el.getAttribute('role') === 'menuitem'; }) as SlMenuItem[]; } @@ -52,7 +45,7 @@ export default class SlMenu extends LitElement { * The menu item may or may not have focus, but for keyboard interaction purposes it's considered the "active" item. */ getCurrentItem() { - return this.getAllItems({ includeDisabled: false }).find(i => i.getAttribute('tabindex') === '0'); + return this.getAllItems().find(i => i.getAttribute('tabindex') === '0'); } /** @@ -60,8 +53,8 @@ export default class SlMenu extends LitElement { * `tabindex="-1"` to all other items. This method must be called prior to setting focus on a menu item. */ setCurrentItem(item: SlMenuItem) { - const items = this.getAllItems({ includeDisabled: false }); - const activeItem = item.disabled ? items[0] : item; + const items = this.getAllItems(); + const activeItem = item ?? items[0]; // Update tab indexes items.forEach(i => { @@ -76,7 +69,7 @@ export default class SlMenu extends LitElement { * type-to-select behavior when the menu doesn't have focus. */ typeToSelect(event: KeyboardEvent) { - const items = this.getAllItems({ includeDisabled: false }); + const items = this.getAllItems(); clearTimeout(this.typeToSelectTimeout); this.typeToSelectTimeout = window.setTimeout(() => (this.typeToSelectString = ''), 1000); @@ -129,7 +122,7 @@ export default class SlMenu extends LitElement { // Move the selection when pressing down or up if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) { - const items = this.getAllItems({ includeDisabled: false }); + const items = this.getAllItems(); const activeItem = this.getCurrentItem(); let index = activeItem ? items.indexOf(activeItem) : 0; @@ -172,7 +165,7 @@ export default class SlMenu extends LitElement { } handleSlotChange() { - const items = this.getAllItems({ includeDisabled: false }); + const items = this.getAllItems(); // Reset the roving tab index when the slotted items change if (items.length > 0) {