From 2fa9ab44c2f1fe6738ad53daa759be2af36401c3 Mon Sep 17 00:00:00 2001 From: oki07 Date: Sat, 23 Nov 2024 13:40:17 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B7=E3=83=93?= =?UTF-8?q?=E3=83=AA=E3=83=86=E3=82=A3=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sp-dropdown-action-button.ts | 12 ++++++++++ .../dropdownAction/sp-dropdown-action.ts | 24 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/components/dropdownAction/sp-dropdown-action-button.ts b/src/components/dropdownAction/sp-dropdown-action-button.ts index 1a37125..2216fca 100644 --- a/src/components/dropdownAction/sp-dropdown-action-button.ts +++ b/src/components/dropdownAction/sp-dropdown-action-button.ts @@ -30,6 +30,18 @@ export class SpDropdownActionButton extends UbButton { iconElement.size = "small"; this.buttonElement.insertBefore(iconElement, this.textElement.nextSibling); } + + setAriaHasPopup(value: string) { + this.buttonElement.setAttribute("aria-haspopup", value); + } + + setAriaExpanded(value: string) { + this.buttonElement.setAttribute("aria-expanded", value); + } + + setAriaControls(value: string) { + this.buttonElement.setAttribute("aria-controls", value); + } } declare global { diff --git a/src/components/dropdownAction/sp-dropdown-action.ts b/src/components/dropdownAction/sp-dropdown-action.ts index 3836488..2f6e689 100644 --- a/src/components/dropdownAction/sp-dropdown-action.ts +++ b/src/components/dropdownAction/sp-dropdown-action.ts @@ -13,6 +13,10 @@ function isValidPosition(value: string): value is Position { return positions.some((position) => position === value); } +function createMenuId() { + return `sp-dropdown-action-menu-${Math.random().toString(32).substring(2)}`; +} + const styles = new CSSStyleSheet(); styles.replaceSync(`${foundationStyle} ${dropdownActionStyle}`); @@ -21,6 +25,8 @@ export class SpDropdownAction extends HTMLElement { #buttonElement = document.createElement("sp-dropdown-action-button"); #menuElement = document.createElement("div"); #menuSlotElement = document.createElement("slot"); + + #menuId = createMenuId(); #open: boolean = false; #disabled: boolean = false; @@ -87,7 +93,7 @@ export class SpDropdownAction extends HTMLElement { connectedCallback() { this.#buttonElement.addEventListener( "click", - this.#toggle.bind(this), + this.#toggleMenuVisibility.bind(this), ); this.#baseElement.appendChild(this.#buttonElement); @@ -103,6 +109,7 @@ export class SpDropdownAction extends HTMLElement { this.shadowRoot?.appendChild(this.#baseElement); + this.#setupAccessibilityAttributes(); this.#syncMenuMinWidthWithButtonWidth(); } @@ -132,12 +139,25 @@ export class SpDropdownAction extends HTMLElement { } } - #toggle() { + #toggleMenuVisibility() { this.open = !this.open; + this.#updateAriaExpandedAttribute(); } #hideMenu() { this.open = false; + this.#updateAriaExpandedAttribute(); + } + + #setupAccessibilityAttributes() { + this.#buttonElement.setAriaHasPopup("true"); + this.#buttonElement.setAriaControls(this.#menuId); + this.#menuElement.setAttribute("id", this.#menuId); + this.#updateAriaExpandedAttribute(); + } + + #updateAriaExpandedAttribute() { + this.#buttonElement.setAriaExpanded(this.open ? "true" : "false"); } #syncMenuMinWidthWithButtonWidth() {