Fix dropdown bugs (#1293)

* fix dropdown auto-size; closes #1268

* fix slotted dropdown items; fixes #1271

* fix keyboard selection in dropdowns in shadow roots; fixes #1270
This commit is contained in:
Cory LaViska
2025-08-12 11:31:40 -04:00
committed by GitHub
parent da27a8dc74
commit f92ef1f74e
3 changed files with 29 additions and 9 deletions

View File

@@ -11,6 +11,9 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
## Next
- Fixed incorrectly named exported tooltip parts in `<wa-slider>` [pr:1277]
- Fixed a bug in `<wa-dropdown>` that caused menus to overflow the viewport instead of resizing [issue:1267]
- Fixed a bug in `<wa-dropdown>` that prevented keyboard selection of items when nested in shadow roots [issue:1270]
- Fixed a bug in `<wa-dropdown>` that prevented items passed in from slots from being detected [issue:1271]
## 3.0.0-beta.4

View File

@@ -17,6 +17,9 @@
color: var(--wa-color-text-normal);
text-align: start;
user-select: none;
overflow: auto;
max-width: var(--auto-size-available-width) !important;
max-height: var(--auto-size-available-height) !important;
&.show {
animation: show var(--show-duration) ease;

View File

@@ -8,6 +8,7 @@ import { WaAfterShowEvent } from '../../events/after-show.js';
import { WaHideEvent } from '../../events/hide.js';
import { WaSelectEvent } from '../../events/select.js';
import { WaShowEvent } from '../../events/show.js';
import { activeElements } from '../../internal/active-elements.js';
import { animateWithClass } from '../../internal/animate.js';
import { uniqueId } from '../../internal/math.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
@@ -123,19 +124,30 @@ export default class WaDropdown extends WebAwesomeElement {
}
}
/** Gets all <wa-dropdown-item> elements slotted in the menu that aren't disabled. */
/** Gets all dropdown items slotted in the menu. */
private getItems(includeDisabled = false): WaDropdownItem[] {
const items = [...this.children].filter(
el => el.localName === 'wa-dropdown-item' && !el.hasAttribute('slot'),
) as WaDropdownItem[];
const items = this.defaultSlot
.assignedElements({ flatten: true })
.filter(el => el.localName === 'wa-dropdown-item') as WaDropdownItem[];
return includeDisabled ? items : items.filter(item => !item.disabled);
}
/** Gets all dropdown items in a specific submenu. */
private getSubmenuItems(parentItem: WaDropdownItem, includeDisabled = false): WaDropdownItem[] {
const items = [...parentItem.children].filter(
el => el.localName === 'wa-dropdown-item' && el.getAttribute('slot') === 'submenu',
) as WaDropdownItem[];
// Find the submenu slot within the parent item
const submenuSlot =
parentItem.shadowRoot?.querySelector<HTMLSlotElement>('slot[name="submenu"]') ||
parentItem.querySelector<HTMLSlotElement>('slot[name="submenu"]');
if (!submenuSlot) {
return [];
}
// Get the items from the submenu slot
const items = submenuSlot
.assignedElements({ flatten: true })
.filter(el => el.localName === 'wa-dropdown-item') as WaDropdownItem[];
return includeDisabled ? items : items.filter(item => !item.disabled);
}
@@ -277,7 +289,7 @@ export default class WaDropdown extends WebAwesomeElement {
return;
}
const activeElement = document.activeElement as HTMLElement;
const activeElement = [...activeElements()].find(el => el.localName === 'wa-dropdown-item');
const isFocusedOnItem = activeElement?.localName === 'wa-dropdown-item';
const currentSubmenuItem = this.getCurrentSubmenuItem();
const isInSubmenu = !!currentSubmenuItem;
@@ -706,7 +718,9 @@ export default class WaDropdown extends WebAwesomeElement {
flip
flip-fallback-strategy="best-fit"
shift
shift-padding="8"
shift-padding="10"
auto-size="vertical"
auto-size-padding="10"
>
<slot
name="trigger"