mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-08 10:29:37 +00:00
169 lines
4.4 KiB
TypeScript
169 lines
4.4 KiB
TypeScript
import { mdiClose, mdiMenuDown } from "@mdi/js";
|
|
import {
|
|
css,
|
|
html,
|
|
LitElement,
|
|
nothing,
|
|
type CSSResultGroup,
|
|
type TemplateResult,
|
|
} from "lit";
|
|
import { customElement, property, query } from "lit/decorators";
|
|
import { fireEvent } from "../common/dom/fire_event";
|
|
import "./ha-combo-box-item";
|
|
import type { HaComboBoxItem } from "./ha-combo-box-item";
|
|
import "./ha-icon-button";
|
|
|
|
declare global {
|
|
interface HASSDomEvents {
|
|
clear: undefined;
|
|
}
|
|
}
|
|
|
|
export type PickerValueRenderer = (value: string) => TemplateResult<1>;
|
|
|
|
@customElement("ha-picker-field")
|
|
export class HaPickerField extends LitElement {
|
|
@property({ type: Boolean }) public disabled = false;
|
|
|
|
@property({ type: Boolean }) public required = false;
|
|
|
|
@property() public value?: string;
|
|
|
|
@property() public helper?: string;
|
|
|
|
@property() public placeholder?: string;
|
|
|
|
@property({ attribute: "hide-clear-icon", type: Boolean })
|
|
public hideClearIcon = false;
|
|
|
|
@property({ attribute: false })
|
|
public valueRenderer?: PickerValueRenderer;
|
|
|
|
@query("ha-combo-box-item", true) public item!: HaComboBoxItem;
|
|
|
|
public async focus() {
|
|
await this.updateComplete;
|
|
await this.item?.focus();
|
|
}
|
|
|
|
protected render() {
|
|
const showClearIcon =
|
|
!!this.value && !this.required && !this.disabled && !this.hideClearIcon;
|
|
|
|
return html`
|
|
<ha-combo-box-item .disabled=${this.disabled} type="button" compact>
|
|
${this.value
|
|
? this.valueRenderer
|
|
? this.valueRenderer(this.value)
|
|
: html`<slot name="headline">${this.value}</slot>`
|
|
: html`
|
|
<span slot="headline" class="placeholder">
|
|
${this.placeholder}
|
|
</span>
|
|
`}
|
|
${showClearIcon
|
|
? html`
|
|
<ha-icon-button
|
|
class="clear"
|
|
slot="end"
|
|
@click=${this._clear}
|
|
.path=${mdiClose}
|
|
></ha-icon-button>
|
|
`
|
|
: nothing}
|
|
<ha-svg-icon
|
|
class="arrow"
|
|
slot="end"
|
|
.path=${mdiMenuDown}
|
|
></ha-svg-icon>
|
|
</ha-combo-box-item>
|
|
`;
|
|
}
|
|
|
|
private _clear(e) {
|
|
e.stopPropagation();
|
|
fireEvent(this, "clear");
|
|
}
|
|
|
|
static get styles(): CSSResultGroup {
|
|
return [
|
|
css`
|
|
ha-combo-box-item[disabled] {
|
|
background-color: var(
|
|
--mdc-text-field-disabled-fill-color,
|
|
whitesmoke
|
|
);
|
|
}
|
|
ha-combo-box-item {
|
|
background-color: var(--mdc-text-field-fill-color, whitesmoke);
|
|
border-radius: var(--ha-border-radius-sm);
|
|
border-end-end-radius: 0;
|
|
border-end-start-radius: 0;
|
|
--md-list-item-one-line-container-height: 56px;
|
|
--md-list-item-two-line-container-height: 56px;
|
|
--md-list-item-top-space: 0px;
|
|
--md-list-item-bottom-space: 0px;
|
|
--md-list-item-leading-space: 8px;
|
|
--md-list-item-trailing-space: 8px;
|
|
--ha-md-list-item-gap: var(--ha-space-2);
|
|
/* Remove the default focus ring */
|
|
--md-focus-ring-width: 0px;
|
|
--md-focus-ring-duration: 0s;
|
|
}
|
|
|
|
/* Add Similar focus style as the text field */
|
|
ha-combo-box-item[disabled]:after {
|
|
background-color: var(
|
|
--mdc-text-field-disabled-line-color,
|
|
rgba(0, 0, 0, 0.42)
|
|
);
|
|
}
|
|
ha-combo-box-item:after {
|
|
display: block;
|
|
content: "";
|
|
position: absolute;
|
|
pointer-events: none;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
width: 100%;
|
|
background-color: var(
|
|
--mdc-text-field-idle-line-color,
|
|
rgba(0, 0, 0, 0.42)
|
|
);
|
|
transform:
|
|
height 180ms ease-in-out,
|
|
background-color 180ms ease-in-out;
|
|
}
|
|
|
|
ha-combo-box-item:focus:after {
|
|
height: 2px;
|
|
background-color: var(--mdc-theme-primary);
|
|
}
|
|
|
|
.clear {
|
|
margin: 0 -8px;
|
|
--mdc-icon-button-size: 32px;
|
|
--mdc-icon-size: 20px;
|
|
}
|
|
.arrow {
|
|
--mdc-icon-size: 20px;
|
|
width: 32px;
|
|
}
|
|
|
|
.placeholder {
|
|
color: var(--secondary-text-color);
|
|
padding: 0 8px;
|
|
}
|
|
`,
|
|
];
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"ha-picker-field": HaPickerField;
|
|
}
|
|
}
|