mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-17 15:45:43 +01:00
114 lines
3.1 KiB
TypeScript
114 lines
3.1 KiB
TypeScript
import type { CSSResultGroup, TemplateResult } from "lit";
|
|
import { css, html, LitElement } from "lit";
|
|
import { customElement, property } from "lit/decorators";
|
|
import { ifDefined } from "lit/directives/if-defined";
|
|
import "./ha-button";
|
|
import "./ha-svg-icon";
|
|
|
|
@customElement("ha-icon-button")
|
|
export class HaIconButton extends LitElement {
|
|
@property({ type: Boolean, reflect: true }) disabled = false;
|
|
|
|
// SVG icon path (if you need a non SVG icon instead, use the provided slot to pass an <ha-icon> in)
|
|
@property({ type: String }) path?: string;
|
|
|
|
// Label that is used for ARIA support and as tooltip
|
|
@property({ type: String }) label?: string;
|
|
|
|
// These should always be set as properties, not attributes,
|
|
// so that only the <button> element gets the attribute
|
|
@property({ type: String, attribute: "aria-haspopup" })
|
|
ariaHasPopup!: "false" | "true" | "menu" | "listbox" | "tree" | "grid";
|
|
|
|
@property({ attribute: "hide-title", type: Boolean }) hideTitle = false;
|
|
|
|
@property({ type: Boolean, reflect: true }) selected = false;
|
|
|
|
@property() href?: string;
|
|
|
|
@property() target?: "_blank" | "_parent" | "_self" | "_top";
|
|
|
|
@property() rel?: string;
|
|
|
|
@property() download?: string;
|
|
|
|
static shadowRootOptions: ShadowRootInit = {
|
|
mode: "open",
|
|
delegatesFocus: true,
|
|
};
|
|
|
|
protected render(): TemplateResult {
|
|
return html`
|
|
<ha-button
|
|
appearance="plain"
|
|
variant="neutral"
|
|
aria-label=${ifDefined(this.label)}
|
|
title=${ifDefined(this.hideTitle ? undefined : this.label)}
|
|
aria-haspopup=${ifDefined(this.ariaHasPopup)}
|
|
.disabled=${this.disabled}
|
|
.iconTag=${this.path ? "ha-svg-icon" : "span"}
|
|
.href=${this.href}
|
|
.target=${this.target}
|
|
.rel=${this.rel}
|
|
.download=${this.download}
|
|
>
|
|
${this.path
|
|
? html`<ha-svg-icon .path=${this.path}></ha-svg-icon>`
|
|
: html`<span><slot></slot></span>`}
|
|
</ha-button>
|
|
`;
|
|
}
|
|
|
|
static styles: CSSResultGroup = css`
|
|
:host {
|
|
display: inline-block;
|
|
outline: none;
|
|
--ha-button-height: var(--ha-icon-button-size, 48px);
|
|
}
|
|
ha-button {
|
|
position: relative;
|
|
isolation: isolate;
|
|
--wa-form-control-padding-inline: var(
|
|
--ha-icon-button-padding-inline,
|
|
--ha-space-2
|
|
);
|
|
--wa-color-on-normal: currentColor;
|
|
--wa-color-fill-quiet: transparent;
|
|
--ha-button-label-overflow: visible;
|
|
}
|
|
ha-button::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: -1;
|
|
border-radius: 50%;
|
|
background-color: currentColor;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
ha-button::part(base) {
|
|
width: var(--wa-form-control-height);
|
|
aspect-ratio: 1;
|
|
outline-offset: -4px;
|
|
}
|
|
ha-button::part(label) {
|
|
display: flex;
|
|
}
|
|
:host([selected]) ha-button::after {
|
|
opacity: 0.1;
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
:host(:hover:not([disabled])) ha-button::after {
|
|
opacity: 0.1;
|
|
}
|
|
}
|
|
`;
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"ha-icon-button": HaIconButton;
|
|
}
|
|
}
|