mirror of
				https://github.com/home-assistant/frontend.git
				synced 2025-11-04 00:19:47 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			20240603.0
			...
			ha-form-co
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					261cc6598d | 
							
								
								
									
										74
									
								
								src/components/ha-form/ha-form-conditional.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/components/ha-form/ha-form-conditional.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
import {
 | 
			
		||||
  css,
 | 
			
		||||
  CSSResultGroup,
 | 
			
		||||
  html,
 | 
			
		||||
  LitElement,
 | 
			
		||||
  nothing,
 | 
			
		||||
  PropertyValues,
 | 
			
		||||
} from "lit";
 | 
			
		||||
import { customElement, property } from "lit/decorators";
 | 
			
		||||
import type { HomeAssistant } from "../../types";
 | 
			
		||||
import "./ha-form";
 | 
			
		||||
import type {
 | 
			
		||||
  HaFormDataContainer,
 | 
			
		||||
  HaFormElement,
 | 
			
		||||
  HaFormConditionalSchema,
 | 
			
		||||
  HaFormSchema,
 | 
			
		||||
} from "./types";
 | 
			
		||||
 | 
			
		||||
@customElement("ha-form-conditional")
 | 
			
		||||
export class HaFormConditional extends LitElement implements HaFormElement {
 | 
			
		||||
  @property({ attribute: false }) public hass!: HomeAssistant;
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public data!: HaFormDataContainer;
 | 
			
		||||
 | 
			
		||||
  @property({ attribute: false }) public schema!: HaFormConditionalSchema;
 | 
			
		||||
 | 
			
		||||
  @property({ type: Boolean }) public disabled = false;
 | 
			
		||||
 | 
			
		||||
  @property() public computeLabel?: (
 | 
			
		||||
    schema: HaFormSchema,
 | 
			
		||||
    data?: HaFormDataContainer
 | 
			
		||||
  ) => string;
 | 
			
		||||
 | 
			
		||||
  @property() public computeHelper?: (schema: HaFormSchema) => string;
 | 
			
		||||
 | 
			
		||||
  protected updated(changedProps: PropertyValues): void {
 | 
			
		||||
    if (changedProps.has("schema") || changedProps.has("data")) {
 | 
			
		||||
      this.toggleAttribute("hidden", !this.schema.condition(this.data));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected render() {
 | 
			
		||||
    if (!this.schema.condition(this.data)) {
 | 
			
		||||
      return nothing;
 | 
			
		||||
    }
 | 
			
		||||
    return html`
 | 
			
		||||
      <ha-form
 | 
			
		||||
        .hass=${this.hass}
 | 
			
		||||
        .data=${this.data}
 | 
			
		||||
        .schema=${this.schema.schema}
 | 
			
		||||
        .disabled=${this.disabled}
 | 
			
		||||
        .computeLabel=${this.computeLabel}
 | 
			
		||||
        .computeHelper=${this.computeHelper}
 | 
			
		||||
      ></ha-form>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get styles(): CSSResultGroup {
 | 
			
		||||
    return css`
 | 
			
		||||
      :host([hidden]) {
 | 
			
		||||
        display: none !important;
 | 
			
		||||
      }
 | 
			
		||||
      :host ha-form {
 | 
			
		||||
        display: block;
 | 
			
		||||
      }
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
declare global {
 | 
			
		||||
  interface HTMLElementTagNameMap {
 | 
			
		||||
    "ha-form-conditional": HaFormConditional;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -21,6 +21,7 @@ const LOAD_ELEMENTS = {
 | 
			
		||||
  float: () => import("./ha-form-float"),
 | 
			
		||||
  grid: () => import("./ha-form-grid"),
 | 
			
		||||
  expandable: () => import("./ha-form-expandable"),
 | 
			
		||||
  conditional: () => import("./ha-form-conditional"),
 | 
			
		||||
  integer: () => import("./ha-form-integer"),
 | 
			
		||||
  multi_select: () => import("./ha-form-multi_select"),
 | 
			
		||||
  positive_time_period_dict: () =>
 | 
			
		||||
@@ -189,12 +190,13 @@ export class HaForm extends LitElement implements HaFormElement {
 | 
			
		||||
 | 
			
		||||
  static get styles(): CSSResultGroup {
 | 
			
		||||
    return css`
 | 
			
		||||
      .root {
 | 
			
		||||
        display: grid;
 | 
			
		||||
        row-gap: 24px;
 | 
			
		||||
      }
 | 
			
		||||
      .root > * {
 | 
			
		||||
        display: block;
 | 
			
		||||
      }
 | 
			
		||||
      .root > *:not([own-margin]):not(:last-child) {
 | 
			
		||||
        margin-bottom: 24px;
 | 
			
		||||
      }
 | 
			
		||||
      ha-alert[own-margin] {
 | 
			
		||||
        margin-bottom: 4px;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,8 @@ export type HaFormSchema =
 | 
			
		||||
  | HaFormTimeSchema
 | 
			
		||||
  | HaFormSelector
 | 
			
		||||
  | HaFormGridSchema
 | 
			
		||||
  | HaFormExpandableSchema;
 | 
			
		||||
  | HaFormExpandableSchema
 | 
			
		||||
  | HaFormConditionalSchema;
 | 
			
		||||
 | 
			
		||||
export interface HaFormBaseSchema {
 | 
			
		||||
  name: string;
 | 
			
		||||
@@ -47,6 +48,13 @@ export interface HaFormExpandableSchema extends HaFormBaseSchema {
 | 
			
		||||
  schema: readonly HaFormSchema[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface HaFormConditionalSchema extends HaFormBaseSchema {
 | 
			
		||||
  type: "conditional";
 | 
			
		||||
  name: "";
 | 
			
		||||
  condition: (data: HaFormDataContainer) => boolean;
 | 
			
		||||
  schema: readonly HaFormSchema[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface HaFormSelector extends HaFormBaseSchema {
 | 
			
		||||
  type?: never;
 | 
			
		||||
  selector: Selector;
 | 
			
		||||
@@ -99,7 +107,10 @@ export interface HaFormTimeSchema extends HaFormBaseSchema {
 | 
			
		||||
export type SchemaUnion<
 | 
			
		||||
  SchemaArray extends readonly HaFormSchema[],
 | 
			
		||||
  Schema = SchemaArray[number]
 | 
			
		||||
> = Schema extends HaFormGridSchema | HaFormExpandableSchema
 | 
			
		||||
> = Schema extends
 | 
			
		||||
  | HaFormGridSchema
 | 
			
		||||
  | HaFormExpandableSchema
 | 
			
		||||
  | HaFormConditionalSchema
 | 
			
		||||
  ? SchemaUnion<Schema["schema"]>
 | 
			
		||||
  : Schema;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
import { html, LitElement, nothing } from "lit";
 | 
			
		||||
import { customElement, property, state } from "lit/decorators";
 | 
			
		||||
import memoizeOne from "memoize-one";
 | 
			
		||||
import {
 | 
			
		||||
  array,
 | 
			
		||||
  assert,
 | 
			
		||||
@@ -13,7 +12,10 @@ import {
 | 
			
		||||
} from "superstruct";
 | 
			
		||||
import { fireEvent } from "../../../../common/dom/fire_event";
 | 
			
		||||
import "../../../../components/ha-form/ha-form";
 | 
			
		||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
 | 
			
		||||
import type {
 | 
			
		||||
  HaFormSchema,
 | 
			
		||||
  SchemaUnion,
 | 
			
		||||
} from "../../../../components/ha-form/types";
 | 
			
		||||
import type { HomeAssistant } from "../../../../types";
 | 
			
		||||
import type { GaugeCardConfig } from "../../cards/types";
 | 
			
		||||
import type { LovelaceCardEditor } from "../../types";
 | 
			
		||||
@@ -41,6 +43,75 @@ const cardConfigStruct = assign(
 | 
			
		||||
  })
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const SCHEMA = [
 | 
			
		||||
  {
 | 
			
		||||
    name: "entity",
 | 
			
		||||
    selector: {
 | 
			
		||||
      entity: {
 | 
			
		||||
        domain: ["counter", "input_number", "number", "sensor"],
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "",
 | 
			
		||||
    type: "grid",
 | 
			
		||||
    schema: [
 | 
			
		||||
      { name: "name", selector: { text: {} } },
 | 
			
		||||
      { name: "unit", selector: { text: {} } },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  { name: "theme", selector: { theme: {} } },
 | 
			
		||||
  {
 | 
			
		||||
    name: "",
 | 
			
		||||
    type: "grid",
 | 
			
		||||
    schema: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "min",
 | 
			
		||||
        default: DEFAULT_MIN,
 | 
			
		||||
        selector: { number: { mode: "box" } },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: "max",
 | 
			
		||||
        default: DEFAULT_MAX,
 | 
			
		||||
        selector: { number: { mode: "box" } },
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "",
 | 
			
		||||
    type: "grid",
 | 
			
		||||
    schema: [
 | 
			
		||||
      { name: "needle", selector: { boolean: {} } },
 | 
			
		||||
      { name: "show_severity", selector: { boolean: {} } },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    name: "",
 | 
			
		||||
    type: "conditional",
 | 
			
		||||
    condition: (data) => !!data.show_severity,
 | 
			
		||||
    schema: [
 | 
			
		||||
      {
 | 
			
		||||
        name: "severity",
 | 
			
		||||
        type: "grid",
 | 
			
		||||
        schema: [
 | 
			
		||||
          {
 | 
			
		||||
            name: "green",
 | 
			
		||||
            selector: { number: { mode: "box" } },
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "yellow",
 | 
			
		||||
            selector: { number: { mode: "box" } },
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: "red",
 | 
			
		||||
            selector: { number: { mode: "box" } },
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
] as const satisfies readonly HaFormSchema[];
 | 
			
		||||
 | 
			
		||||
@customElement("hui-gauge-card-editor")
 | 
			
		||||
export class HuiGaugeCardEditor
 | 
			
		||||
  extends LitElement
 | 
			
		||||
@@ -55,81 +126,11 @@ export class HuiGaugeCardEditor
 | 
			
		||||
    this._config = config;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _schema = memoizeOne(
 | 
			
		||||
    (showSeverity: boolean) =>
 | 
			
		||||
      [
 | 
			
		||||
        {
 | 
			
		||||
          name: "entity",
 | 
			
		||||
          selector: {
 | 
			
		||||
            entity: {
 | 
			
		||||
              domain: ["counter", "input_number", "number", "sensor"],
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "",
 | 
			
		||||
          type: "grid",
 | 
			
		||||
          schema: [
 | 
			
		||||
            { name: "name", selector: { text: {} } },
 | 
			
		||||
            { name: "unit", selector: { text: {} } },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
        { name: "theme", selector: { theme: {} } },
 | 
			
		||||
        {
 | 
			
		||||
          name: "",
 | 
			
		||||
          type: "grid",
 | 
			
		||||
          schema: [
 | 
			
		||||
            {
 | 
			
		||||
              name: "min",
 | 
			
		||||
              default: DEFAULT_MIN,
 | 
			
		||||
              selector: { number: { mode: "box" } },
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              name: "max",
 | 
			
		||||
              default: DEFAULT_MAX,
 | 
			
		||||
              selector: { number: { mode: "box" } },
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "",
 | 
			
		||||
          type: "grid",
 | 
			
		||||
          schema: [
 | 
			
		||||
            { name: "needle", selector: { boolean: {} } },
 | 
			
		||||
            { name: "show_severity", selector: { boolean: {} } },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
        ...(showSeverity
 | 
			
		||||
          ? ([
 | 
			
		||||
              {
 | 
			
		||||
                name: "severity",
 | 
			
		||||
                type: "grid",
 | 
			
		||||
                schema: [
 | 
			
		||||
                  {
 | 
			
		||||
                    name: "green",
 | 
			
		||||
                    selector: { number: { mode: "box" } },
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    name: "yellow",
 | 
			
		||||
                    selector: { number: { mode: "box" } },
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    name: "red",
 | 
			
		||||
                    selector: { number: { mode: "box" } },
 | 
			
		||||
                  },
 | 
			
		||||
                ],
 | 
			
		||||
              },
 | 
			
		||||
            ] as const)
 | 
			
		||||
          : []),
 | 
			
		||||
      ] as const
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  protected render() {
 | 
			
		||||
    if (!this.hass || !this._config) {
 | 
			
		||||
      return nothing;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const schema = this._schema(this._config!.severity !== undefined);
 | 
			
		||||
    const data = {
 | 
			
		||||
      show_severity: this._config!.severity !== undefined,
 | 
			
		||||
      ...this._config,
 | 
			
		||||
@@ -139,7 +140,7 @@ export class HuiGaugeCardEditor
 | 
			
		||||
      <ha-form
 | 
			
		||||
        .hass=${this.hass}
 | 
			
		||||
        .data=${data}
 | 
			
		||||
        .schema=${schema}
 | 
			
		||||
        .schema=${SCHEMA}
 | 
			
		||||
        .computeLabel=${this._computeLabelCallback}
 | 
			
		||||
        @value-changed=${this._valueChanged}
 | 
			
		||||
      ></ha-form>
 | 
			
		||||
@@ -153,7 +154,7 @@ export class HuiGaugeCardEditor
 | 
			
		||||
      config = {
 | 
			
		||||
        ...config,
 | 
			
		||||
        severity: {
 | 
			
		||||
          green: config.green || config.severity?.green || 0,
 | 
			
		||||
          green: config.green || config.severity?.green,
 | 
			
		||||
          yellow: config.yellow || config.severity?.yellow || 0,
 | 
			
		||||
          red: config.red || config.severity?.red || 0,
 | 
			
		||||
        },
 | 
			
		||||
@@ -170,9 +171,7 @@ export class HuiGaugeCardEditor
 | 
			
		||||
    fireEvent(this, "config-changed", { config });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private _computeLabelCallback = (
 | 
			
		||||
    schema: SchemaUnion<ReturnType<typeof this._schema>>
 | 
			
		||||
  ) => {
 | 
			
		||||
  private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
 | 
			
		||||
    switch (schema.name) {
 | 
			
		||||
      case "name":
 | 
			
		||||
        return this.hass!.localize(
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user