diff --git a/gallery/src/pages/components/ha-input.markdown b/gallery/src/pages/components/ha-input.markdown new file mode 100644 index 0000000000..5acbc595d8 --- /dev/null +++ b/gallery/src/pages/components/ha-input.markdown @@ -0,0 +1,82 @@ +--- +title: Input +--- + +# Input `` + +A text input component supporting Home Assistant theming and validation, based on webawesome input. +Supports multiple input types including text, number, password, email, search, and more. + +## Implementation + +### Example usage + +```html + + + + + + + + + +``` + +### API + +This component is based on the webawesome input component. + +**Slots** + +- `start`: Content placed before the input (usually for icons or prefixes). +- `end`: Content placed after the input (usually for icons or suffixes). +- `label`: Custom label content. Overrides the `label` property. +- `hint`: Custom hint content. Overrides the `hint` property. +- `clear-icon`: Custom clear icon. +- `show-password-icon`: Custom show password icon. +- `hide-password-icon`: Custom hide password icon. + +**Properties/Attributes** + +| Name | Type | Default | Description | +| -------------------- | ---------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- | +| appearance | "material"/"outlined" | "material" | Sets the input appearance style. "material" is the default filled style, "outlined" uses a bordered style. | +| type | "text"/"number"/"password"/"email"/"search"/"tel"/"url"/"date"/"datetime-local"/"time"/"color" | "text" | Sets the input type. | +| value | String | - | The current value of the input. | +| label | String | "" | The input's label text. | +| hint | String | "" | The input's hint/helper text. | +| placeholder | String | "" | Placeholder text shown when the input is empty. | +| with-clear | Boolean | false | Adds a clear button when the input is not empty. | +| readonly | Boolean | false | Makes the input readonly. | +| disabled | Boolean | false | Disables the input and prevents user interaction. | +| required | Boolean | false | Makes the input a required field. | +| password-toggle | Boolean | false | Adds a button to toggle the password visibility. | +| without-spin-buttons | Boolean | false | Hides the browser's built-in spin buttons for number inputs. | +| auto-validate | Boolean | false | Validates the input on blur instead of on form submit. | +| invalid | Boolean | false | Marks the input as invalid. | +| inset-label | Boolean | false | Uses an inset label style where the label stays inside the input. | +| validation-message | String | "" | Custom validation message shown when the input is invalid. | +| pattern | String | - | A regular expression pattern to validate input against. | +| minlength | Number | - | The minimum length of input that will be considered valid. | +| maxlength | Number | - | The maximum length of input that will be considered valid. | +| min | Number/String | - | The input's minimum value. Only applies to date and number input types. | +| max | Number/String | - | The input's maximum value. Only applies to date and number input types. | +| step | Number/"any" | - | Specifies the granularity that the value must adhere to. | + +**CSS Custom Properties** + +- `--ha-input-padding-top` - Padding above the input. +- `--ha-input-padding-bottom` - Padding below the input. Defaults to `var(--ha-space-2)`. +- `--ha-input-text-align` - Text alignment of the input. Defaults to `start`. +- `--ha-input-required-marker` - The marker shown after the label for required fields. Defaults to `"*"`. + +--- + +## Derivatives + +The following components extend or wrap `ha-input` for specific use cases: + +- **``** — A pre-configured search input with a magnify icon, clear button, and localized "Search" placeholder. Extends `ha-input`. +- **``** — A read-only input with a copy-to-clipboard button. Supports optional value masking with a reveal toggle. +- **``** — A dynamic list of text inputs for managing arrays of strings. Supports adding, removing, and drag-and-drop reordering. diff --git a/gallery/src/pages/components/ha-input.ts b/gallery/src/pages/components/ha-input.ts new file mode 100644 index 0000000000..c0e95dbd0d --- /dev/null +++ b/gallery/src/pages/components/ha-input.ts @@ -0,0 +1,232 @@ +import { ContextProvider } from "@lit/context"; +import { mdiMagnify } from "@mdi/js"; +import type { TemplateResult } from "lit"; +import { css, html, LitElement } from "lit"; +import { customElement } from "lit/decorators"; +import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-svg-icon"; +import "../../../../src/components/input/ha-input"; +import "../../../../src/components/input/ha-input-copy"; +import "../../../../src/components/input/ha-input-multi"; +import "../../../../src/components/input/ha-input-search"; +import { localizeContext } from "../../../../src/data/context"; + +const LOCALIZE_KEYS: Record = { + "ui.common.copy": "Copy", + "ui.common.show": "Show", + "ui.common.hide": "Hide", + "ui.common.add": "Add", + "ui.common.remove": "Remove", + "ui.common.search": "Search", + "ui.common.copied_clipboard": "Copied to clipboard", +}; + +@customElement("demo-components-ha-input") +export class DemoHaInput extends LitElement { + constructor() { + super(); + // Provides localizeContext for ha-input-copy, ha-input-multi and ha-input-search + // eslint-disable-next-line no-new + new ContextProvider(this, { + context: localizeContext, + initialValue: ((key: string) => LOCALIZE_KEYS[key] ?? key) as any, + }); + } + + protected render(): TemplateResult { + return html` + ${["light", "dark"].map( + (mode) => html` +
+ +
+

Basic

+
+ + + +
+ +

Input types

+
+ + + +
+
+ + + + +
+ +

States

+
+ + + +
+
+ + + +
+ +

With slots

+
+ + $ + + + kg + + + + +
+ +

Appearance: outlined

+
+ + + +
+
+ +
+
+
+ + +
+

ha-input-search

+ + + +

ha-input-copy

+ + +

ha-input-multi

+ +
+
+
+ ` + )} + `; + } + + firstUpdated(changedProps) { + super.firstUpdated(changedProps); + applyThemesOnElement( + this.shadowRoot!.querySelector(".dark"), + { + default_theme: "default", + default_dark_theme: "default", + themes: {}, + darkMode: true, + theme: "default", + }, + undefined, + undefined, + true + ); + } + + static styles = css` + :host { + display: flex; + justify-content: center; + } + .dark, + .light { + display: block; + background-color: var(--primary-background-color); + padding: 0 50px; + } + ha-card { + margin: 24px auto; + } + .card-content { + display: flex; + flex-direction: column; + gap: var(--ha-space-2); + } + h3 { + margin: var(--ha-space-4) 0 var(--ha-space-1) 0; + font-size: var(--ha-font-size-l); + font-weight: var(--ha-font-weight-medium); + } + h3:first-child { + margin-top: 0; + } + .row { + display: flex; + gap: var(--ha-space-4); + } + .row > * { + flex: 1; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "demo-components-ha-input": DemoHaInput; + } +} diff --git a/src/components/ha-aliases-editor.ts b/src/components/ha-aliases-editor.ts index 6109a3358b..e031a78a79 100644 --- a/src/components/ha-aliases-editor.ts +++ b/src/components/ha-aliases-editor.ts @@ -21,7 +21,6 @@ class AliasesEditor extends LitElement { return html`