mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
116 lines
3.5 KiB
TypeScript
116 lines
3.5 KiB
TypeScript
import Dropdown from "@home-assistant/webawesome/dist/components/dropdown/dropdown";
|
|
import { css, type CSSResultGroup } from "lit";
|
|
import { customElement, property } from "lit/decorators";
|
|
import type { HaDropdownItem } from "./ha-dropdown-item";
|
|
import type { HaIconButton } from "./ha-icon-button";
|
|
|
|
/**
|
|
* Event type for the ha-dropdown component when an item is selected.
|
|
* @param T - The type of the value of the selected item.
|
|
*/
|
|
export type HaDropdownSelectEvent<T = string> = CustomEvent<{
|
|
item: Omit<HaDropdownItem, "value"> & { value: T };
|
|
}>;
|
|
|
|
/**
|
|
* Home Assistant dropdown component
|
|
*
|
|
* @element ha-dropdown
|
|
* @extends {Dropdown}
|
|
*
|
|
* @summary
|
|
* A stylable dropdown component supporting Home Assistant theming, variants, and appearances based on webawesome dropdown.
|
|
*
|
|
*/
|
|
@customElement("ha-dropdown")
|
|
// @ts-ignore Allow to set an alternative anchor element
|
|
export class HaDropdown extends Dropdown {
|
|
@property({ attribute: false }) dropdownTag = "ha-dropdown";
|
|
|
|
@property({ attribute: false }) dropdownItemTag = "ha-dropdown-item";
|
|
|
|
public get anchorElement(): HTMLButtonElement | HaIconButton | undefined {
|
|
// @ts-ignore Allow to set an anchor element on popup
|
|
return this.popup?.anchor as HTMLButtonElement | HaIconButton | undefined;
|
|
}
|
|
|
|
public set anchorElement(
|
|
element: HTMLButtonElement | HaIconButton | undefined
|
|
) {
|
|
// @ts-ignore Allow to get the current anchor element from popup
|
|
if (!this.popup) {
|
|
return;
|
|
}
|
|
|
|
// @ts-ignore
|
|
if (this.popup.anchor && this.popup.anchor.localName === "ha-icon-button") {
|
|
// @ts-ignore
|
|
(this.popup.anchor as HaIconButton).selected = false;
|
|
}
|
|
|
|
// @ts-ignore Allow to get the current anchor element from popup
|
|
this.popup.anchor = element;
|
|
}
|
|
|
|
/** Get the slotted trigger button, a <wa-button> or <button> element */
|
|
// @ts-ignore Override parent method to be able to use alternative anchor
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
private override getTrigger(): HTMLButtonElement | HaIconButton | null {
|
|
if (this.anchorElement) {
|
|
return this.anchorElement;
|
|
}
|
|
// @ts-ignore fallback to default trigger slot if no anchorElement is set
|
|
return super.getTrigger();
|
|
}
|
|
|
|
// @ts-ignore
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
private override async showMenu() {
|
|
// @ts-ignore
|
|
await super.showMenu();
|
|
const triggerElement = this.getTrigger();
|
|
if (triggerElement && triggerElement.localName === "ha-icon-button") {
|
|
(triggerElement as HaIconButton).selected = true;
|
|
}
|
|
}
|
|
|
|
// @ts-ignore
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
private override async hideMenu() {
|
|
const triggerElement = this.getTrigger();
|
|
if (triggerElement && triggerElement.localName === "ha-icon-button") {
|
|
(triggerElement as HaIconButton).selected = false;
|
|
}
|
|
// @ts-ignore
|
|
await super.hideMenu();
|
|
}
|
|
|
|
static get styles(): CSSResultGroup {
|
|
return [
|
|
Dropdown.styles,
|
|
css`
|
|
:host {
|
|
font-size: var(--ha-dropdown-font-size, var(--ha-font-size-m));
|
|
--wa-color-surface-raised: var(
|
|
--card-background-color,
|
|
var(--ha-dialog-surface-background, var(--mdc-theme-surface, #fff)),
|
|
);
|
|
}
|
|
|
|
#menu {
|
|
padding: var(--ha-space-1);
|
|
}
|
|
wa-popup::part(popup) {
|
|
z-index: 200;
|
|
}
|
|
`,
|
|
];
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"ha-dropdown": HaDropdown;
|
|
}
|
|
}
|