Tile card editor improvements (#24373)
* Add selector support * Feedbacks * Use select box fields in tile card editor
@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="40" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="39" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M40 14C40 10.6863 42.6863 8 46 8H65C68.3137 8 71 10.6863 71 14C71 17.3137 68.3137 20 65 20H46C42.6863 20 40 17.3137 40 14Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M40 28C40 25.7909 41.7909 24 44 24H77C79.2091 24 81 25.7909 81 28C81 30.2091 79.2091 32 77 32H44C41.7909 32 40 30.2091 40 28Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 652 B |
@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="40" rx="8" fill="black"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="39" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<circle cx="20" cy="20" r="12" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M40 14C40 10.6863 42.6863 8 46 8H65C68.3137 8 71 10.6863 71 14C71 17.3137 68.3137 20 65 20H46C42.6863 20 40 17.3137 40 14Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M40 28C40 25.7909 41.7909 24 44 24H77C79.2091 24 81 25.7909 81 28C81 30.2091 79.2091 32 77 32H44C41.7909 32 40 30.2091 40 28Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 652 B |
@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="72" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="71" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<circle cx="47" cy="20" r="12" fill="black" fill-opacity="0.12"/>
|
||||||
|
<path d="M31.5 46C31.5 42.6863 34.1863 40 37.5 40H56.5C59.8137 40 62.5 42.6863 62.5 46C62.5 49.3137 59.8137 52 56.5 52H37.5C34.1863 52 31.5 49.3137 31.5 46Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
<path d="M26.5 60C26.5 57.7909 28.2909 56 30.5 56H63.5C65.7091 56 67.5 57.7909 67.5 60C67.5 62.2091 65.7091 64 63.5 64H30.5C28.2909 64 26.5 62.2091 26.5 60Z" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 699 B |
@ -0,0 +1,7 @@
|
|||||||
|
<svg width="94" height="72" viewBox="0 0 94 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="72" rx="8" fill="black"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="71" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<circle cx="47" cy="20" r="12" fill="white" fill-opacity="0.24"/>
|
||||||
|
<path d="M31.5 46C31.5 42.6863 34.1863 40 37.5 40H56.5C59.8137 40 62.5 42.6863 62.5 46C62.5 49.3137 59.8137 52 56.5 52H37.5C34.1863 52 31.5 49.3137 31.5 46Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
<path d="M26.5 60C26.5 57.7909 28.2909 56 30.5 56H63.5C65.7091 56 67.5 57.7909 67.5 60C67.5 62.2091 65.7091 64 63.5 64H30.5C28.2909 64 26.5 62.2091 26.5 60Z" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 699 B |
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="48" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="47" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<rect x="8" y="8" width="78" height="12" rx="3" fill="black" fill-opacity="0.12"/>
|
||||||
|
<rect x="8" y="28" width="78" height="12" rx="3" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="48" viewBox="0 0 94 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="48" rx="8" fill="black"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="47" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<rect x="8" y="8" width="78" height="12" rx="3" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="8" y="28" width="78" height="12" rx="3" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="28" viewBox="0 0 94 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="28" rx="8" fill="white"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="27" rx="7.5" stroke="black" stroke-opacity="0.12"/>
|
||||||
|
<rect x="8" y="8" width="35" height="12" rx="3" fill="black" fill-opacity="0.12"/>
|
||||||
|
<rect x="51" y="8" width="35" height="12" rx="3" fill="black" fill-opacity="0.32"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="94" height="28" viewBox="0 0 94 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="94" height="28" rx="8" fill="black"/>
|
||||||
|
<rect x="0.5" y="0.5" width="93" height="27" rx="7.5" stroke="white" stroke-opacity="0.24"/>
|
||||||
|
<rect x="8" y="8" width="35" height="12" rx="3" fill="white" fill-opacity="0.24"/>
|
||||||
|
<rect x="51" y="8" width="35" height="12" rx="3" fill="white" fill-opacity="0.48"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 414 B |
@ -115,7 +115,7 @@ export class HuiTileCardEditor
|
|||||||
localize: LocalizeFunc,
|
localize: LocalizeFunc,
|
||||||
entityId: string | undefined,
|
entityId: string | undefined,
|
||||||
hideState: boolean,
|
hideState: boolean,
|
||||||
vertical: boolean,
|
isDark: boolean,
|
||||||
displayActions: AdvancedActions[] = []
|
displayActions: AdvancedActions[] = []
|
||||||
) =>
|
) =>
|
||||||
[
|
[
|
||||||
@ -175,41 +175,20 @@ export class HuiTileCardEditor
|
|||||||
] as const satisfies readonly HaFormSchema[])
|
] as const satisfies readonly HaFormSchema[])
|
||||||
: []),
|
: []),
|
||||||
{
|
{
|
||||||
name: "",
|
name: "content_layout",
|
||||||
type: "grid",
|
required: true,
|
||||||
schema: [
|
selector: {
|
||||||
{
|
select: {
|
||||||
name: "content_layout",
|
mode: "box",
|
||||||
required: true,
|
options: ["horizontal", "vertical"].map((value) => ({
|
||||||
selector: {
|
label: localize(
|
||||||
select: {
|
`ui.panel.lovelace.editor.card.tile.content_layout_options.${value}`
|
||||||
mode: "dropdown",
|
),
|
||||||
options: ["horizontal", "vertical"].map((value) => ({
|
value,
|
||||||
label: localize(
|
image: `/static/images/form/tile_content_layout_${value}${isDark ? "_dark" : ""}.svg`,
|
||||||
`ui.panel.lovelace.editor.card.tile.content_layout_options.${value}`
|
})),
|
||||||
),
|
|
||||||
value,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
name: "features_position",
|
|
||||||
required: true,
|
|
||||||
selector: {
|
|
||||||
select: {
|
|
||||||
mode: "dropdown",
|
|
||||||
options: ["bottom", "inline"].map((value) => ({
|
|
||||||
label: localize(
|
|
||||||
`ui.panel.lovelace.editor.card.tile.features_position_options.${value}`
|
|
||||||
),
|
|
||||||
value,
|
|
||||||
disabled: vertical && value === "inline",
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -250,6 +229,29 @@ export class HuiTileCardEditor
|
|||||||
] as const satisfies readonly HaFormSchema[]
|
] as const satisfies readonly HaFormSchema[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private _featuresSchema = memoizeOne(
|
||||||
|
(localize: LocalizeFunc, vertical: boolean, isDark: boolean) =>
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "features_position",
|
||||||
|
required: true,
|
||||||
|
selector: {
|
||||||
|
select: {
|
||||||
|
mode: "box",
|
||||||
|
options: ["bottom", "inline"].map((value) => ({
|
||||||
|
label: localize(
|
||||||
|
`ui.panel.lovelace.editor.card.tile.features_position_options.${value}`
|
||||||
|
),
|
||||||
|
value,
|
||||||
|
image: `/static/images/form/tile_features_position_${value}${isDark ? "_dark" : ""}.svg`,
|
||||||
|
disabled: vertical && value === "inline",
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as const satisfies readonly HaFormSchema[]
|
||||||
|
);
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.hass || !this._config) {
|
if (!this.hass || !this._config) {
|
||||||
return nothing;
|
return nothing;
|
||||||
@ -262,10 +264,16 @@ export class HuiTileCardEditor
|
|||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
entityId,
|
entityId,
|
||||||
this._config.hide_state ?? false,
|
this._config.hide_state ?? false,
|
||||||
this._config.vertical ?? false,
|
this.hass.themes.darkMode,
|
||||||
this._displayActions
|
this._displayActions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const featuresSchema = this._featuresSchema(
|
||||||
|
this.hass.localize,
|
||||||
|
this._config.vertical ?? false,
|
||||||
|
this.hass.themes.darkMode
|
||||||
|
);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
...this._config,
|
...this._config,
|
||||||
content_layout: this._config.vertical ? "vertical" : "horizontal",
|
content_layout: this._config.vertical ? "vertical" : "horizontal",
|
||||||
@ -293,6 +301,15 @@ export class HuiTileCardEditor
|
|||||||
)}
|
)}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<ha-form
|
||||||
|
class="features-form"
|
||||||
|
.hass=${this.hass}
|
||||||
|
.data=${data}
|
||||||
|
.schema=${featuresSchema}
|
||||||
|
.computeLabel=${this._computeLabelCallback}
|
||||||
|
.computeHelper=${this._computeHelperCallback}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></ha-form>
|
||||||
<hui-card-features-editor
|
<hui-card-features-editor
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.stateObj=${stateObj}
|
.stateObj=${stateObj}
|
||||||
@ -381,7 +398,9 @@ export class HuiTileCardEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
private _computeLabelCallback = (
|
||||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
schema:
|
||||||
|
| SchemaUnion<ReturnType<typeof this._schema>>
|
||||||
|
| SchemaUnion<ReturnType<typeof this._featuresSchema>>
|
||||||
) => {
|
) => {
|
||||||
switch (schema.name) {
|
switch (schema.name) {
|
||||||
case "color":
|
case "color":
|
||||||
@ -405,13 +424,22 @@ export class HuiTileCardEditor
|
|||||||
};
|
};
|
||||||
|
|
||||||
private _computeHelperCallback = (
|
private _computeHelperCallback = (
|
||||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
schema:
|
||||||
|
| SchemaUnion<ReturnType<typeof this._schema>>
|
||||||
|
| SchemaUnion<ReturnType<typeof this._featuresSchema>>
|
||||||
) => {
|
) => {
|
||||||
switch (schema.name) {
|
switch (schema.name) {
|
||||||
case "color":
|
case "color":
|
||||||
return this.hass!.localize(
|
return this.hass!.localize(
|
||||||
`ui.panel.lovelace.editor.card.tile.${schema.name}_helper`
|
`ui.panel.lovelace.editor.card.tile.${schema.name}_helper`
|
||||||
);
|
);
|
||||||
|
case "features_position":
|
||||||
|
if (this._config?.vertical) {
|
||||||
|
return this.hass!.localize(
|
||||||
|
`ui.panel.lovelace.editor.card.tile.${schema.name}_helper_vertical`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -7158,6 +7158,7 @@
|
|||||||
"bottom": "Bottom",
|
"bottom": "Bottom",
|
||||||
"inline": "Inline"
|
"inline": "Inline"
|
||||||
},
|
},
|
||||||
|
"features_position_helper_vertical": "Always displayed at the bottom if the content layout is vertical",
|
||||||
"content_layout": "Content layout",
|
"content_layout": "Content layout",
|
||||||
"content_layout_options": {
|
"content_layout_options": {
|
||||||
"horizontal": "Horizontal",
|
"horizontal": "Horizontal",
|
||||||
|