From 68e94d7222a1c385f42400d28f6882cc1560123b Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 28 Oct 2022 17:49:59 +0200 Subject: [PATCH] Add type expandable for ha-form (#14197) * Add type group for ha-form * rename to expandable * Add aria level * apply suggestions --- src/components/ha-form/ha-form-expandable.ts | 87 ++++++++ src/components/ha-form/ha-form.ts | 1 + src/components/ha-form/types.ts | 18 +- .../config-elements/hui-tile-card-editor.ts | 194 +++++++----------- 4 files changed, 173 insertions(+), 127 deletions(-) create mode 100644 src/components/ha-form/ha-form-expandable.ts diff --git a/src/components/ha-form/ha-form-expandable.ts b/src/components/ha-form/ha-form-expandable.ts new file mode 100644 index 0000000000..0c0c7bad64 --- /dev/null +++ b/src/components/ha-form/ha-form-expandable.ts @@ -0,0 +1,87 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators"; +import type { HomeAssistant } from "../../types"; +import "./ha-form"; +import type { + HaFormDataContainer, + HaFormElement, + HaFormExpandableSchema, + HaFormSchema, +} from "./types"; + +@customElement("ha-form-expandable") +export class HaFormExpendable extends LitElement implements HaFormElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public data!: HaFormDataContainer; + + @property({ attribute: false }) public schema!: HaFormExpandableSchema; + + @property({ type: Boolean }) public disabled = false; + + @property() public computeLabel?: ( + schema: HaFormSchema, + data?: HaFormDataContainer + ) => string; + + @property() public computeHelper?: (schema: HaFormSchema) => string; + + protected render(): TemplateResult { + return html` + +
+ ${this.schema.icon + ? html` ` + : this.schema.iconPath + ? html` ` + : null} + ${this.schema.title} +
+
+ +
+
+ `; + } + + static get styles(): CSSResultGroup { + return css` + :host { + display: flex !important; + flex-direction: column; + } + :host ha-form { + display: block; + } + .content { + padding: 12px; + } + ha-expansion-panel { + display: block; + --expansion-panel-content-padding: 0; + border-radius: 6px; + } + ha-svg-icon, + ha-icon { + color: var(--secondary-text-color); + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-form-expandable": HaFormExpendable; + } +} diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index c90c4d0c12..8148b30d26 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -9,6 +9,7 @@ import "./ha-form-boolean"; import "./ha-form-constant"; import "./ha-form-float"; import "./ha-form-grid"; +import "./ha-form-expandable"; import "./ha-form-integer"; import "./ha-form-multi_select"; import "./ha-form-positive_time_period_dict"; diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts index 3e3c649670..bce171a562 100644 --- a/src/components/ha-form/types.ts +++ b/src/components/ha-form/types.ts @@ -12,7 +12,8 @@ export type HaFormSchema = | HaFormMultiSelectSchema | HaFormTimeSchema | HaFormSelector - | HaFormGridSchema; + | HaFormGridSchema + | HaFormExpandableSchema; export interface HaFormBaseSchema { name: string; @@ -34,6 +35,17 @@ export interface HaFormGridSchema extends HaFormBaseSchema { schema: readonly HaFormSchema[]; } +export interface HaFormExpandableSchema extends HaFormBaseSchema { + type: "expandable"; + name: ""; + title: string; + icon?: string; + iconPath?: string; + expanded?: boolean; + headingLevel?: 1 | 2 | 3 | 4 | 5 | 6; + schema: readonly HaFormSchema[]; +} + export interface HaFormSelector extends HaFormBaseSchema { type?: never; selector: Selector; @@ -86,7 +98,9 @@ export interface HaFormTimeSchema extends HaFormBaseSchema { export type SchemaUnion< SchemaArray extends readonly HaFormSchema[], Schema = SchemaArray[number] -> = Schema extends HaFormGridSchema ? SchemaUnion : Schema; +> = Schema extends HaFormGridSchema | HaFormExpandableSchema + ? SchemaUnion + : Schema; export interface HaFormDataContainer { [key: string]: HaFormData; diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts index c495d0f1b0..e79ff9c27a 100644 --- a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts @@ -9,7 +9,6 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { computeDomain } from "../../../../common/entity/compute_domain"; import { domainIcon } from "../../../../common/entity/domain_icon"; import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter"; -import { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../types"; @@ -45,50 +44,76 @@ export class HuiTileCardEditor this._config = config; } - private _mainSchema = [{ name: "entity", selector: { entity: {} } }] as const; - - private _appearanceSchema = memoizeOne( - ( - localize: LocalizeFunc, - entity: string, - icon?: string, - entityState?: HassEntity - ) => + private _schema = memoizeOne( + (entity: string, icon?: string, entityState?: HassEntity) => [ + { name: "entity", selector: { entity: {} } }, { name: "", - type: "grid", + type: "expandable", + iconPath: mdiPalette, + title: this.hass!.localize( + `ui.panel.lovelace.editor.card.tile.appearance` + ), schema: [ - { name: "name", selector: { text: {} } }, { - name: "icon", - selector: { - icon: { - placeholder: icon || entityState?.attributes.icon, - fallbackPath: - !icon && !entityState?.attributes.icon && entityState - ? domainIcon(computeDomain(entity), entityState) - : undefined, + name: "", + type: "grid", + schema: [ + { name: "name", selector: { text: {} } }, + { + name: "icon", + selector: { + icon: { + placeholder: icon || entityState?.attributes.icon, + fallbackPath: + !icon && !entityState?.attributes.icon && entityState + ? domainIcon(computeDomain(entity), entityState) + : undefined, + }, + }, }, + { + name: "color", + selector: { + select: { + options: [ + { + label: this.hass!.localize( + `ui.panel.lovelace.editor.card.tile.default_color` + ), + value: "default", + }, + ...Array.from(THEME_COLORS).map((color) => ({ + label: capitalizeFirstLetter(color), + value: color, + })), + ], + }, + }, + }, + ] as const, + }, + ] as const, + }, + { + name: "", + type: "expandable", + title: this.hass!.localize( + `ui.panel.lovelace.editor.card.tile.actions` + ), + iconPath: mdiGestureTap, + schema: [ + { + name: "tap_action", + selector: { + "ui-action": {}, }, }, { - name: "color", + name: "icon_tap_action", selector: { - select: { - options: [ - { - label: localize( - `ui.panel.lovelace.editor.card.tile.default_color` - ), - value: "default", - }, - ...Array.from(THEME_COLORS).map((color) => ({ - label: capitalizeFirstLetter(color), - value: color, - })), - ], - }, + "ui-action": {}, }, }, { @@ -102,21 +127,6 @@ export class HuiTileCardEditor ] as const ); - private _actionsSchema = [ - { - name: "tap_action", - selector: { - "ui-action": {}, - }, - }, - { - name: "icon_tap_action", - selector: { - "ui-action": {}, - }, - }, - ] as const; - protected render(): TemplateResult { if (!this.hass || !this._config) { return html``; @@ -126,14 +136,7 @@ export class HuiTileCardEditor | HassEntity | undefined; - const mainSchema = this._mainSchema; - const appareanceSchema = this._appearanceSchema( - this.hass.localize, - this._config.entity, - this._config.icon, - entity - ); - const actionsSchema = this._actionsSchema; + const schema = this._schema(this._config.entity, this._config.icon, entity); const data = { color: "default", @@ -141,55 +144,13 @@ export class HuiTileCardEditor }; return html` -
-
- -
-
- -
- - ${this.hass!.localize( - `ui.panel.lovelace.editor.card.tile.appearance` - )} -
-
- -
-
-
-
- -
- - ${this.hass!.localize( - `ui.panel.lovelace.editor.card.tile.actions` - )} -
-
- -
-
-
-
+ `; } @@ -204,10 +165,7 @@ export class HuiTileCardEditor } private _computeLabelCallback = ( - schema: - | SchemaUnion - | SchemaUnion> - | SchemaUnion + schema: SchemaUnion> ) => { switch (schema.name) { case "color": @@ -230,20 +188,6 @@ export class HuiTileCardEditor display: flex; flex-direction: column; } - .group:not(:last-child) { - margin-bottom: 12px; - } - .content { - padding: 12px; - } - ha-expansion-panel { - --expansion-panel-content-padding: 0; - border: 1px solid var(--divider-color); - border-radius: 6px; - } - ha-svg-icon { - color: var(--secondary-text-color); - } `; } }