Dashboard Studio 1.13.1: car card battery bar along the bottom
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.13.1
|
||||||
|
|
||||||
|
- Car card: the battery bar is always shown now, along the bottom of the card, with the charge limit marked. It turns green with the charging details while the car charges. On the wide card it runs the full width.
|
||||||
|
|
||||||
## 1.13.0
|
## 1.13.0
|
||||||
|
|
||||||
- **Car card redesigned in the style of the Tesla app,** with a square and a wide design. The square card shows the car from the front, the wide card from the side with the numbers beside it. Both have the battery and range, a green charging bar with the power, time left and charge limit, and plain icon buttons for the doors, climate, charging and location. Tall square cards add rows for the climate, location and odometer.
|
- **Car card redesigned in the style of the Tesla app,** with a square and a wide design. The square card shows the car from the front, the wide card from the side with the numbers beside it. Both have the battery and range, a green charging bar with the power, time left and charge limit, and plain icon buttons for the doors, climate, charging and location. Tall square cards add rows for the climate, location and odometer.
|
||||||
|
|||||||
@@ -165,10 +165,10 @@ Two optional extra fields: **Time until full** (a sensor in minutes or an end ti
|
|||||||
|
|
||||||
The card follows the style of the Tesla app, with two designs:
|
The card follows the style of the Tesla app, with two designs:
|
||||||
|
|
||||||
- **Square** (for example 3×4): the car from the front in its own color, with the name and a status such as *Charging · Home* or *Parked · Away* at the top left, and a battery icon with the charge level and range at the top right. While the car is plugged in, a green charging bar shows the charging power, the time left and the charge limit. Plain icon buttons along the bottom lock or unlock the doors (orange while unlocked), switch the climate, start or stop charging and show the location. A tall square card adds rows for the climate (with the inside temperature), the location and the odometer; tap a row for details.
|
- **Square** (for example 3×4): the car from the front in its own color, with the name and a status such as *Charging · Home* or *Parked · Away* at the top left, and a battery icon with the charge level and range at the top right. Plain icon buttons lock or unlock the doors (orange while unlocked), switch the climate, start or stop charging and show the location. The battery bar runs along the bottom, with the charge limit marked; while the car is plugged in it turns green and shows the charging power, the time left and when it will be full. A tall square card adds rows for the climate (with the inside temperature), the location and the odometer; tap a row for details.
|
||||||
- **Wide** (for example 6×3 or 8×4): the car from the side on the right, with the name, the charge level and range in large numbers, and the charging bar on the left. The buttons sit under the car.
|
- **Wide** (for example 6×3 or 8×4): the car from the side on the right, with the name and the charge level and range in large numbers on the left, and the buttons under the car. The battery bar runs along the full width of the bottom.
|
||||||
|
|
||||||
**Layout** picks the design: *Automatic* (the default) uses the wide design when the card is clearly wider than it is tall. **Car color** paints the car in any color, for example `#b3261e` for red; it's silver by default. A short card shows the car smaller from the side, and a very short card just the battery and the charging bar. With your own car photo (by URL), the photo replaces the drawing. Images you put in Home Assistant's `www` folder are available at `/local/…`.
|
**Layout** picks the design: *Automatic* (the default) uses the wide design when the card is clearly wider than it is tall. **Car color** paints the car in any color, for example `#b3261e` for red; it's silver by default. A short card shows the car smaller from the side, and a very short card just the battery and the battery bar. With your own car photo (by URL), the photo replaces the drawing. Images you put in Home Assistant's `www` folder are available at `/local/…`.
|
||||||
|
|
||||||
## Conditional widgets
|
## Conditional widgets
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Dashboard Studio
|
name: Dashboard Studio
|
||||||
version: "1.13.0"
|
version: "1.13.1"
|
||||||
slug: dashboard_studio
|
slug: dashboard_studio
|
||||||
description: Drag-and-drop dashboard builder with a free-form grid, live entity widgets and themes.
|
description: Drag-and-drop dashboard builder with a free-form grid, live entity widgets and themes.
|
||||||
url: https://git.melvanveen.nl/veenm/ha-dashboard-studio
|
url: https://git.melvanveen.nl/veenm/ha-dashboard-studio
|
||||||
|
|||||||
@@ -976,7 +976,7 @@ body.kiosk #tabnav { top: 6px; max-height: calc(100vh - 20px); }
|
|||||||
.car-act .i { font-size: 18px; }
|
.car-act .i { font-size: 18px; }
|
||||||
/* car: in the style of the Tesla app. Square cards show the car from the front, wide ones from the side. */
|
/* car: in the style of the Tesla app. Square cards show the car from the front, wide ones from the side. */
|
||||||
.tz { --tz-c: var(--d-text); --tz-paint: color-mix(in srgb, var(--d-text) 22%, #b9bec6);
|
.tz { --tz-c: var(--d-text); --tz-paint: color-mix(in srgb, var(--d-text) 22%, #b9bec6);
|
||||||
display: grid; grid-template-areas: "head" "art" "charge" "ctrls" "rows"; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto auto auto; row-gap: 10px; height: 100%; min-height: 0; min-width: 0; }
|
display: grid; grid-template-areas: "head" "art" "ctrls" "charge" "rows"; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto auto auto; row-gap: 10px; height: 100%; min-height: 0; min-width: 0; }
|
||||||
.tz.charging { --tz-c: var(--ok); }
|
.tz.charging { --tz-c: var(--ok); }
|
||||||
.tz.low { --tz-c: var(--crit); }
|
.tz.low { --tz-c: var(--crit); }
|
||||||
.tz.fuel:not(.low) { --tz-c: var(--warn); }
|
.tz.fuel:not(.low) { --tz-c: var(--warn); }
|
||||||
@@ -1014,7 +1014,6 @@ body.kiosk #tabnav { top: 6px; max-height: calc(100vh - 20px); }
|
|||||||
.tz.charging .tz-port, .tz.charging .tz-bar i { animation: tz-pulse 2s ease-in-out infinite; }
|
.tz.charging .tz-port, .tz.charging .tz-bar i { animation: tz-pulse 2s ease-in-out infinite; }
|
||||||
@keyframes tz-pulse { 50% { opacity: .55; } }
|
@keyframes tz-pulse { 50% { opacity: .55; } }
|
||||||
.tz-charge { grid-area: charge; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
.tz-charge { grid-area: charge; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
||||||
.tz-charge.tz-idle { display: none; }
|
|
||||||
.tz-cl, .tz-cs { display: flex; justify-content: space-between; gap: 8px; min-width: 0; }
|
.tz-cl, .tz-cs { display: flex; justify-content: space-between; gap: 8px; min-width: 0; }
|
||||||
.tz-ct { font-size: 13px; font-weight: 600; white-space: nowrap; flex: none; }
|
.tz-ct { font-size: 13px; font-weight: 600; white-space: nowrap; flex: none; }
|
||||||
.tz.charging .tz-ct { color: var(--ok); }
|
.tz.charging .tz-ct { color: var(--ok); }
|
||||||
@@ -1062,7 +1061,7 @@ body.kiosk #tabnav { top: 6px; max-height: calc(100vh - 20px); }
|
|||||||
.tz-btn { width: 36px; height: 36px; font-size: 18px; }
|
.tz-btn { width: 36px; height: 36px; font-size: 18px; }
|
||||||
}
|
}
|
||||||
/* wide: the car from the side on the right, the numbers on the left */
|
/* wide: the car from the side on the right, the numbers on the left */
|
||||||
.tz.tz-wide { grid-template-areas: "head art" "big art" "charge ctrls"; grid-template-columns: minmax(170px, .8fr) minmax(0, 1.2fr); grid-template-rows: auto minmax(0, 1fr) auto; column-gap: 24px; }
|
.tz.tz-wide { grid-template-areas: "head art" "big art" "big ctrls" "charge charge"; grid-template-columns: minmax(170px, .8fr) minmax(0, 1.2fr); grid-template-rows: auto minmax(0, 1fr) auto auto; column-gap: 24px; }
|
||||||
.tz.tz-wide .tz-batt { display: none; }
|
.tz.tz-wide .tz-batt { display: none; }
|
||||||
.tz.tz-wide .tz-big { display: flex; }
|
.tz.tz-wide .tz-big { display: flex; }
|
||||||
.tz.tz-wide .tz-front { display: none; }
|
.tz.tz-wide .tz-front { display: none; }
|
||||||
@@ -1073,7 +1072,7 @@ body.kiosk #tabnav { top: 6px; max-height: calc(100vh - 20px); }
|
|||||||
.tz.tz-wide .tz-art { align-self: stretch; }
|
.tz.tz-wide .tz-art { align-self: stretch; }
|
||||||
.tz.tz-wide .tz-big { align-self: start; }
|
.tz.tz-wide .tz-big { align-self: start; }
|
||||||
@container (min-aspect-ratio: 8 / 5) {
|
@container (min-aspect-ratio: 8 / 5) {
|
||||||
.tz.tz-auto { grid-template-areas: "head art" "big art" "charge ctrls"; grid-template-columns: minmax(170px, .8fr) minmax(0, 1.2fr); grid-template-rows: auto minmax(0, 1fr) auto; column-gap: 24px; }
|
.tz.tz-auto { grid-template-areas: "head art" "big art" "big ctrls" "charge charge"; grid-template-columns: minmax(170px, .8fr) minmax(0, 1.2fr); grid-template-rows: auto minmax(0, 1fr) auto auto; column-gap: 24px; }
|
||||||
.tz.tz-auto .tz-batt { display: none; }
|
.tz.tz-auto .tz-batt { display: none; }
|
||||||
.tz.tz-auto .tz-big { display: flex; }
|
.tz.tz-auto .tz-big { display: flex; }
|
||||||
.tz.tz-auto .tz-front { display: none; }
|
.tz.tz-auto .tz-front { display: none; }
|
||||||
@@ -1087,10 +1086,10 @@ body.kiosk #tabnav { top: 6px; max-height: calc(100vh - 20px); }
|
|||||||
|
|
||||||
/* very short, whatever the width: name, battery and the bar */
|
/* very short, whatever the width: name, battery and the bar */
|
||||||
@container (max-height: 170px) {
|
@container (max-height: 170px) {
|
||||||
.tz.tz { grid-template-areas: "head" "charge" "ctrls"; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr auto; }
|
.tz.tz { grid-template-areas: "head" "ctrls" "charge"; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr auto; }
|
||||||
.tz.tz .tz-art, .tz.tz .tz-big, .tz.tz .tz-cs, .tz.tz .tz-rows { display: none; }
|
.tz.tz .tz-art, .tz.tz .tz-big, .tz.tz .tz-cs, .tz.tz .tz-rows { display: none; }
|
||||||
.tz.tz .tz-batt { display: grid; }
|
.tz.tz .tz-batt { display: grid; }
|
||||||
.tz.tz .tz-charge, .tz.tz .tz-charge.tz-idle { display: flex; align-self: center; }
|
.tz.tz .tz-ctrls { align-self: center; }
|
||||||
}
|
}
|
||||||
@container (max-height: 120px) { .tz.tz .tz-ctrls { display: none; } }
|
@container (max-height: 120px) { .tz.tz .tz-ctrls { display: none; } }
|
||||||
|
|
||||||
|
|||||||
@@ -1235,7 +1235,7 @@
|
|||||||
const bar = pct != null ? `<div class="tz-bar"><i style="width:${p}%"></i>${limPct != null ? `<b style="left:${Math.max(0, Math.min(100, limPct))}%"></b>` : ""}</div>` : "";
|
const bar = pct != null ? `<div class="tz-bar"><i style="width:${p}%"></i>${limPct != null ? `<b style="left:${Math.max(0, Math.min(100, limPct))}%"></b>` : ""}</div>` : "";
|
||||||
const chargeInfo = plugged
|
const chargeInfo = plugged
|
||||||
? `<div class="tz-charge"><div class="tz-cl"><span class="tz-ct">${charging ? t("Charging") : t("Plugged in")}${charging && power && Number(power.state) > 0 ? ` <span class="num">${esc(fmtState(power))}</span>` : ""}</span><span class="tz-cr num">${esc(left || (limPct != null ? t("Charges to {0}%", Math.round(limPct)) : ""))}</span></div>${bar}${fullAt || limPct != null ? `<div class="tz-cs"><span>${esc(fullAt)}</span><span>${limPct != null ? esc(t("Limit {0}%", Math.round(limPct))) : ""}</span></div>` : ""}</div>`
|
? `<div class="tz-charge"><div class="tz-cl"><span class="tz-ct">${charging ? t("Charging") : t("Plugged in")}${charging && power && Number(power.state) > 0 ? ` <span class="num">${esc(fmtState(power))}</span>` : ""}</span><span class="tz-cr num">${esc(left || (limPct != null ? t("Charges to {0}%", Math.round(limPct)) : ""))}</span></div>${bar}${fullAt || limPct != null ? `<div class="tz-cs"><span>${esc(fullAt)}</span><span>${limPct != null ? esc(t("Limit {0}%", Math.round(limPct))) : ""}</span></div>` : ""}</div>`
|
||||||
: `<div class="tz-charge tz-idle">${bar}</div>`;
|
: bar ? `<div class="tz-charge tz-idle">${bar}</div>` : "";
|
||||||
|
|
||||||
// icon buttons
|
// icon buttons
|
||||||
const ctrl = (act, eid, ico, label, cls = "", extra = "") => `<button class="tz-btn wbtn ${cls}" data-act="${act}" data-e="${esc(eid)}" ${extra} aria-label="${esc(label)}" title="${esc(label)}">${Icons.svg(ico)}</button>`;
|
const ctrl = (act, eid, ico, label, cls = "", extra = "") => `<button class="tz-btn wbtn ${cls}" data-act="${act}" data-e="${esc(eid)}" ${extra} aria-label="${esc(label)}" title="${esc(label)}">${Icons.svg(ico)}</button>`;
|
||||||
@@ -1259,8 +1259,8 @@
|
|||||||
<div class="tz-head"><div class="tz-title"><div class="tz-name">${esc(c.name || t("Car"))}</div>${status ? `<div class="tz-status">${esc(status)}</div>` : ""}</div>${batt}</div>
|
<div class="tz-head"><div class="tz-title"><div class="tz-name">${esc(c.name || t("Car"))}</div>${status ? `<div class="tz-status">${esc(status)}</div>` : ""}</div>${batt}</div>
|
||||||
${big}
|
${big}
|
||||||
<div class="tz-art">${art}</div>
|
<div class="tz-art">${art}</div>
|
||||||
${chargeInfo}
|
|
||||||
${ctrls.length ? `<div class="tz-ctrls">${ctrls.join("")}</div>` : ""}
|
${ctrls.length ? `<div class="tz-ctrls">${ctrls.join("")}</div>` : ""}
|
||||||
|
${chargeInfo}
|
||||||
${rows ? `<div class="tz-rows">${rows}</div>` : ""}
|
${rows ? `<div class="tz-rows">${rows}</div>` : ""}
|
||||||
</div>`;
|
</div>`;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user