mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Migrate ha-multi-textfield, ha-selector-text to ha-input and update to use new input components (#30280)
* Migrate ha-multi-textfield to ha-input-multi and update ha-selector-text to use new input components * Review * Update src/components/input/ha-input-multi.ts --------- Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,7 @@ import { LitElement, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-multi-textfield";
|
||||
import "./input/ha-input-multi";
|
||||
|
||||
@customElement("ha-aliases-editor")
|
||||
class AliasesEditor extends LitElement {
|
||||
@@ -20,7 +20,7 @@ class AliasesEditor extends LitElement {
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-multi-textfield
|
||||
<ha-input-multi
|
||||
.hass=${this.hass}
|
||||
.value=${this.aliases}
|
||||
.disabled=${this.disabled}
|
||||
@@ -32,7 +32,7 @@ class AliasesEditor extends LitElement {
|
||||
item-index
|
||||
@value-changed=${this._aliasesChanged}
|
||||
>
|
||||
</ha-multi-textfield>
|
||||
</ha-input-multi>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { mdiEye, mdiEyeOff } from "@mdi/js";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import { ensureArray } from "../../common/array/ensure-array";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type { StringSelector } from "../../data/selector";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../ha-icon-button";
|
||||
import "../ha-multi-textfield";
|
||||
import type { HomeAssistant, ValueChangedEvent } from "../../types";
|
||||
import "../ha-textarea";
|
||||
import "../ha-textfield";
|
||||
import "../input/ha-input";
|
||||
import "../input/ha-input-multi";
|
||||
|
||||
@customElement("ha-selector-text")
|
||||
export class HaTextSelector extends LitElement {
|
||||
@@ -30,9 +28,7 @@ export class HaTextSelector extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public required = true;
|
||||
|
||||
@state() private _unmaskedPassword = false;
|
||||
|
||||
@query("ha-textfield, ha-textarea") private _input?: HTMLInputElement;
|
||||
@query("ha-input, ha-textarea") private _input?: HTMLInputElement;
|
||||
|
||||
public async focus() {
|
||||
await this.updateComplete;
|
||||
@@ -49,8 +45,7 @@ export class HaTextSelector extends LitElement {
|
||||
protected render() {
|
||||
if (this.selector.text?.multiple) {
|
||||
return html`
|
||||
<ha-multi-textfield
|
||||
.hass=${this.hass}
|
||||
<ha-input-multi
|
||||
.value=${ensureArray(this.value ?? [])}
|
||||
.disabled=${this.disabled}
|
||||
.label=${this.label}
|
||||
@@ -61,7 +56,7 @@ export class HaTextSelector extends LitElement {
|
||||
.autocomplete=${this.selector.text?.autocomplete}
|
||||
@value-changed=${this._handleChange}
|
||||
>
|
||||
</ha-multi-textfield>
|
||||
</ha-input-multi>
|
||||
`;
|
||||
}
|
||||
if (this.selector.text?.multiline) {
|
||||
@@ -81,45 +76,34 @@ export class HaTextSelector extends LitElement {
|
||||
autogrow
|
||||
></ha-textarea>`;
|
||||
}
|
||||
return html`<ha-textfield
|
||||
.name=${this.name}
|
||||
.value=${this.value || ""}
|
||||
.placeholder=${this.placeholder || ""}
|
||||
.helper=${this.helper}
|
||||
helperPersistent
|
||||
.disabled=${this.disabled}
|
||||
.type=${this._unmaskedPassword ? "text" : this.selector.text?.type}
|
||||
@input=${this._handleChange}
|
||||
@change=${this._handleChange}
|
||||
.label=${this.label || ""}
|
||||
.prefix=${this.selector.text?.prefix}
|
||||
.suffix=${this.selector.text?.type === "password"
|
||||
? // reserve some space for the icon.
|
||||
html`<div style="width: 24px"></div>`
|
||||
: this.selector.text?.suffix}
|
||||
.required=${this.required}
|
||||
.autocomplete=${this.selector.text?.autocomplete}
|
||||
></ha-textfield>
|
||||
${this.selector.text?.type === "password"
|
||||
? html`<ha-icon-button
|
||||
.label=${this.hass?.localize(
|
||||
this._unmaskedPassword
|
||||
? "ui.components.selectors.text.hide_password"
|
||||
: "ui.components.selectors.text.show_password"
|
||||
) || (this._unmaskedPassword ? "Hide password" : "Show password")}
|
||||
@click=${this._toggleUnmaskedPassword}
|
||||
.path=${this._unmaskedPassword ? mdiEyeOff : mdiEye}
|
||||
></ha-icon-button>`
|
||||
: ""}`;
|
||||
return html`<ha-input
|
||||
.name=${this.name}
|
||||
.value=${this.value || ""}
|
||||
.placeholder=${this.placeholder || ""}
|
||||
.hint=${this.helper}
|
||||
.disabled=${this.disabled}
|
||||
.type=${this.selector.text?.type}
|
||||
@input=${this._handleChange}
|
||||
@change=${this._handleChange}
|
||||
.label=${this.label || ""}
|
||||
.required=${this.required}
|
||||
.autocomplete=${this.selector.text?.autocomplete}
|
||||
.passwordToggle=${this.selector.text?.type === "password"}
|
||||
>
|
||||
${this.selector.text?.prefix
|
||||
? html`<span slot="start">${this.selector.text.prefix}</span>`
|
||||
: nothing}
|
||||
${this.selector.text?.suffix
|
||||
? html`<span slot="end">${this.selector.text.suffix}</span>`
|
||||
: nothing}
|
||||
</ha-input>`;
|
||||
}
|
||||
|
||||
private _toggleUnmaskedPassword(): void {
|
||||
this._unmaskedPassword = !this._unmaskedPassword;
|
||||
}
|
||||
|
||||
private _handleChange(ev) {
|
||||
private _handleChange(ev: ValueChangedEvent<string> | InputEvent) {
|
||||
ev.stopPropagation();
|
||||
let value = ev.detail?.value ?? ev.target.value;
|
||||
let value: string | undefined =
|
||||
(ev as ValueChangedEvent<string>).detail?.value ??
|
||||
(ev.target as HTMLInputElement).value;
|
||||
if (this.value === value) {
|
||||
return;
|
||||
}
|
||||
@@ -139,20 +123,9 @@ export class HaTextSelector extends LitElement {
|
||||
position: relative;
|
||||
}
|
||||
ha-textarea,
|
||||
ha-textfield {
|
||||
ha-input {
|
||||
width: 100%;
|
||||
}
|
||||
ha-icon-button {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
inset-inline-start: initial;
|
||||
inset-inline-end: 8px;
|
||||
--ha-icon-button-size: 40px;
|
||||
--mdc-icon-size: 20px;
|
||||
color: var(--secondary-text-color);
|
||||
direction: var(--direction);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiContentCopy, mdiEye, mdiEyeOff } from "@mdi/js";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { copyToClipboard } from "../../common/util/copy-clipboard";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { showToast } from "../../util/toast";
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import { consume, type ContextType } from "@lit/context";
|
||||
import { mdiDeleteOutline, mdiDragHorizontalVariant, mdiPlus } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { repeat } from "lit/directives/repeat";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { haStyle } from "../resources/styles";
|
||||
import type { HomeAssistant } from "../types";
|
||||
import "./ha-button";
|
||||
import "./ha-icon-button";
|
||||
import "./ha-input-helper-text";
|
||||
import "./ha-sortable";
|
||||
import "./ha-textfield";
|
||||
import type { HaTextField } from "./ha-textfield";
|
||||
|
||||
@customElement("ha-multi-textfield")
|
||||
class HaMultiTextField extends LitElement {
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { localizeContext } from "../../data/context";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import "../ha-button";
|
||||
import "../ha-icon-button";
|
||||
import "../ha-input-helper-text";
|
||||
import "../ha-sortable";
|
||||
import "./ha-input";
|
||||
import type { HaInput, InputType } from "./ha-input";
|
||||
|
||||
@customElement("ha-input-multi")
|
||||
class HaInputMulti extends LitElement {
|
||||
@property({ attribute: false }) public value?: string[];
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
@@ -25,7 +24,7 @@ class HaMultiTextField extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public helper?: string;
|
||||
|
||||
@property({ attribute: false }) public inputType?: string;
|
||||
@property({ attribute: false }) public inputType?: InputType;
|
||||
|
||||
@property({ attribute: false }) public inputSuffix?: string;
|
||||
|
||||
@@ -47,6 +46,10 @@ class HaMultiTextField extends LitElement {
|
||||
@property({ type: Boolean, attribute: "update-on-blur" })
|
||||
public updateOnBlur = false;
|
||||
|
||||
@state()
|
||||
@consume({ context: localizeContext, subscribe: true })
|
||||
private localize?: ContextType<typeof localizeContext>;
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<ha-sortable
|
||||
@@ -63,9 +66,7 @@ class HaMultiTextField extends LitElement {
|
||||
const indexSuffix = `${this.itemIndex ? ` ${index + 1}` : ""}`;
|
||||
return html`
|
||||
<div class="layout horizontal center-center row">
|
||||
<ha-textfield
|
||||
.suffix=${this.inputSuffix}
|
||||
.prefix=${this.inputPrefix}
|
||||
<ha-input
|
||||
.type=${this.inputType}
|
||||
.autocomplete=${this.autocomplete}
|
||||
.disabled=${this.disabled}
|
||||
@@ -78,13 +79,20 @@ class HaMultiTextField extends LitElement {
|
||||
@input=${this._editItem}
|
||||
@change=${this._editItem}
|
||||
@keydown=${this._keyDown}
|
||||
></ha-textfield>
|
||||
>
|
||||
${this.inputPrefix
|
||||
? html`<span slot="start">${this.inputPrefix}</span>`
|
||||
: nothing}
|
||||
${this.inputSuffix
|
||||
? html`<span slot="end">${this.inputSuffix}</span>`
|
||||
: nothing}
|
||||
</ha-input>
|
||||
<ha-icon-button
|
||||
.disabled=${this.disabled}
|
||||
.index=${index}
|
||||
slot="navigationIcon"
|
||||
.label=${this.removeLabel ??
|
||||
this.hass?.localize("ui.common.remove") ??
|
||||
this.localize?.("ui.common.remove") ??
|
||||
"Remove"}
|
||||
@click=${this._removeItem}
|
||||
.path=${mdiDeleteOutline}
|
||||
@@ -112,10 +120,10 @@ class HaMultiTextField extends LitElement {
|
||||
<ha-svg-icon slot="start" .path=${mdiPlus}></ha-svg-icon>
|
||||
${this.addLabel ??
|
||||
(this.label
|
||||
? this.hass?.localize("ui.components.multi-textfield.add_item", {
|
||||
? this.localize?.("ui.components.multi-textfield.add_item", {
|
||||
item: this.label,
|
||||
})
|
||||
: this.hass?.localize("ui.common.add")) ??
|
||||
: this.localize?.("ui.common.add")) ??
|
||||
"Add"}
|
||||
</ha-button>
|
||||
</div>
|
||||
@@ -138,8 +146,8 @@ class HaMultiTextField extends LitElement {
|
||||
const items = [...this._items, ""];
|
||||
this._fireChanged(items);
|
||||
await this.updateComplete;
|
||||
const field = this.shadowRoot?.querySelector(`ha-textfield[data-last]`) as
|
||||
| HaTextField
|
||||
const field = this.shadowRoot?.querySelector(`ha-input[data-last]`) as
|
||||
| HaInput
|
||||
| undefined;
|
||||
field?.focus();
|
||||
}
|
||||
@@ -191,9 +199,7 @@ class HaMultiTextField extends LitElement {
|
||||
css`
|
||||
.row {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
ha-textfield {
|
||||
display: block;
|
||||
--ha-input-padding-bottom: 0;
|
||||
}
|
||||
ha-icon-button {
|
||||
display: block;
|
||||
@@ -210,6 +216,6 @@ class HaMultiTextField extends LitElement {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-multi-textfield": HaMultiTextField;
|
||||
"ha-input-multi": HaInputMulti;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user