Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script Editor to Ha Form #11601

Merged
merged 11 commits into from
Feb 14, 2022
4 changes: 4 additions & 0 deletions build-scripts/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) =>
require.resolve(
path.resolve(paths.polymer_dir, "src/components/ha-icon.ts")
),
isHassioBuild &&
require.resolve(
path.resolve(paths.polymer_dir, "src/components/ha-icon-picker.ts")
),
].filter(Boolean);

module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
Expand Down
6 changes: 6 additions & 0 deletions gallery/src/pages/components/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ const SCHEMAS: {
select: { options: ["Everyone Home", "Some Home", "All gone"] },
},
},
{
name: "icon",
selector: {
icon: {},
},
},
],
},
{
Expand Down
1 change: 1 addition & 0 deletions gallery/src/pages/components/ha-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const SCHEMAS: {
name: "Select",
selector: { select: { options: ["Option 1", "Option 2"] } },
},
icon: { name: "Icon", selector: { icon: {} } },
},
},
];
Expand Down
22 changes: 17 additions & 5 deletions src/components/ha-form/ha-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ export class HaForm extends LitElement implements HaFormElement {

@property() public computeError?: (schema: HaFormSchema, error) => string;

@property() public computeLabel?: (schema: HaFormSchema) => string;
@property() public computeLabel?: (
schema: HaFormSchema,
data?: HaFormDataContainer
) => string;

@property() public computeHelper?: (schema: HaFormSchema) => string;

public focus() {
const root = this.shadowRoot?.querySelector(".root");
Expand Down Expand Up @@ -71,6 +76,7 @@ export class HaForm extends LitElement implements HaFormElement {
: ""}
${this.schema.map((item) => {
const error = getValue(this.error, item);

return html`
${error
? html`
Expand All @@ -85,14 +91,15 @@ export class HaForm extends LitElement implements HaFormElement {
.hass=${this.hass}
.selector=${item.selector}
.value=${getValue(this.data, item)}
.label=${this._computeLabel(item)}
.label=${this._computeLabel(item, this.data)}
.disabled=${this.disabled}
zsarnett marked this conversation as resolved.
Show resolved Hide resolved
.helper=${this._computeHelper(item)}
.required=${item.required || false}
></ha-selector>`
: dynamicElement(`ha-form-${item.type}`, {
schema: item,
data: getValue(this.data, item),
label: this._computeLabel(item),
label: this._computeLabel(item, this.data),
disabled: this.disabled,
})}
`;
Expand All @@ -107,21 +114,26 @@ export class HaForm extends LitElement implements HaFormElement {
root.addEventListener("value-changed", (ev) => {
ev.stopPropagation();
const schema = (ev.target as HaFormElement).schema as HaFormSchema;

fireEvent(this, "value-changed", {
value: { ...this.data, [schema.name]: ev.detail.value },
});
});
return root;
}

private _computeLabel(schema: HaFormSchema) {
private _computeLabel(schema: HaFormSchema, data: HaFormDataContainer) {
return this.computeLabel
? this.computeLabel(schema)
? this.computeLabel(schema, data)
: schema
? schema.name
: "";
}

private _computeHelper(schema: HaFormSchema) {
return this.computeHelper ? this.computeHelper(schema) : "";
}

private _computeError(error, schema: HaFormSchema | HaFormSchema[]) {
return this.computeError ? this.computeError(error, schema) : error;
}
Expand Down
39 changes: 39 additions & 0 deletions src/components/ha-selector/ha-selector-icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import "../ha-icon-picker";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { HomeAssistant } from "../../types";
import { IconSelector } from "../../data/selector";
import { fireEvent } from "../../common/dom/fire_event";

@customElement("ha-selector-icon")
export class HaIconSelector extends LitElement {
@property() public hass!: HomeAssistant;

@property() public selector!: IconSelector;

@property() public value?: string;

@property() public label?: string;

@property({ type: Boolean, reflect: true }) public disabled = false;

protected render() {
return html`
<ha-icon-picker
.label=${this.label}
.value=${this.value}
@value-changed=${this._valueChanged}
></ha-icon-picker>
`;
}

private _valueChanged(ev: CustomEvent) {
fireEvent(this, "value-changed", { value: ev.detail.value });
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-selector-icon": HaIconSelector;
}
}
16 changes: 10 additions & 6 deletions src/components/ha-selector/ha-selector-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { stopPropagation } from "../../common/dom/stop_propagation";
import { SelectSelector } from "../../data/selector";
import { SelectOption, SelectSelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
import "@material/mwc-select/mwc-select";
import "@material/mwc-list/mwc-list-item";
Expand All @@ -17,6 +17,8 @@ export class HaSelectSelector extends LitElement {

@property() public label?: string;

@property() public helper?: string;

@property({ type: Boolean }) public disabled = false;

protected render() {
Expand All @@ -25,15 +27,17 @@ export class HaSelectSelector extends LitElement {
naturalMenuWidth
.label=${this.label}
.value=${this.value}
.helper=${this.helper}
.disabled=${this.disabled}
@closed=${stopPropagation}
@selected=${this._valueChanged}
>
${this.selector.select.options.map(
(item: string) => html`
<mwc-list-item .value=${item}>${item}</mwc-list-item>
`
)}
${this.selector.select.options.map((item: string | SelectOption) => {
const value = typeof item === "object" ? item.value : item;
const label = typeof item === "object" ? item.label : item;
Comment on lines +36 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the object better, but not sure how well it translates to the backend

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can switch it but I also like object better... the other is very ambiguous it seems


return html`<mwc-list-item .value=${value}>${label}</mwc-list-item>`;
})}
</mwc-select>`;
}

Expand Down
4 changes: 4 additions & 0 deletions src/components/ha-selector/ha-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import "./ha-selector-select";
import "./ha-selector-target";
import "./ha-selector-text";
import "./ha-selector-time";
import "./ha-selector-icon";

@customElement("ha-selector")
export class HaSelector extends LitElement {
Expand All @@ -28,6 +29,8 @@ export class HaSelector extends LitElement {

@property() public label?: string;

@property() public helper?: string;

@property() public placeholder?: any;

@property({ type: Boolean }) public disabled = false;
Expand All @@ -52,6 +55,7 @@ export class HaSelector extends LitElement {
placeholder: this.placeholder,
disabled: this.disabled,
required: this.required,
helper: this.helper,
id: "selector",
})}
`;
Expand Down
15 changes: 13 additions & 2 deletions src/data/selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export type Selector =
| ActionSelector
| StringSelector
| ObjectSelector
| SelectSelector;
| SelectSelector
| IconSelector;

export interface EntitySelector {
entity: {
Expand Down Expand Up @@ -133,8 +134,18 @@ export interface ObjectSelector {
object: {};
}

export interface SelectOption {
value: string;
label: string;
}

export interface SelectSelector {
select: {
options: string[];
options: string[] | SelectOption[];
};
}

export interface IconSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
icon: {};
}