diff --git a/dashboard_studio/CHANGELOG.md b/dashboard_studio/CHANGELOG.md index 203571f..26d4e1d 100644 --- a/dashboard_studio/CHANGELOG.md +++ b/dashboard_studio/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.3.1 + +- **Light card:** the colors now wait behind a palette button next to the brightness. Tap it to show them; picking one folds them away again. + ## 2.3.0 - **Light card, redesigned:** the card is the lamp. On, it takes the lamp's color and the brightness fills it from the left; drag anywhere across it to dim. The brightness is the large figure, the switch sits top right, and the bulb opens colors and settings. diff --git a/dashboard_studio/DOCS.md b/dashboard_studio/DOCS.md index c495b06..8bd77cb 100644 --- a/dashboard_studio/DOCS.md +++ b/dashboard_studio/DOCS.md @@ -83,7 +83,7 @@ More editing tools: - **Light and dark versions:** turn on **Switch to a dark or light version with the device** under a theme to use a matching dark version of a light theme when the device is in dark mode, and the other way round. *System* always does this. - **Theme:** *System* follows your device's light or dark appearance. The other 23 themes are fixed: Light, Dark, Nord, Dusk, Forest, Graphite, Indigo, Rose, Ocean, Sunrise, Lavender, Mint, Sand, Midnight (true black, for OLED screens), Espresso, Ember, Lagoon, Paper, Arctic, Moss, Sakura, Concrete, and High contrast for maximum readability. Text meets accessibility contrast levels in every theme. Changing any color switches the theme to *Custom*. - **Tile style:** *Cards* puts every widget on a tile. *Outlined* draws a thin border instead. *Plain* removes the cards completely, so widgets sit straight on the background. You can also turn off the background for a single widget under **Style → No background**. -- **Lights that are on** glow: the light card turns warm, or takes on the bulb's color for color lights, and its brightness fills it from the left in a deeper shade. Drag anywhere across a light card to dim it; the switch at the top right turns it on or off, and tapping the bulb opens its colors and settings. A light that can only switch on and off turns on or off when you tap the card. +- **Lights that are on** glow: the light card turns warm, or takes on the bulb's color for color lights, and its brightness fills it from the left in a deeper shade. Drag anywhere across a light card to dim it; the switch at the top right turns it on or off, the palette button next to the brightness shows its colors (pick one and they fold away again), and tapping the bulb opens all its settings. A light that can only switch on and off turns on or off when you tap the card. - **Icons:** widgets pick an icon automatically. To change one, click the icon next to the field to open the icon picker (over 130 icons for rooms, appliances, tools and devices, searchable in English and Dutch), type an icon name, or paste an emoji. ## Widgets diff --git a/dashboard_studio/config.yaml b/dashboard_studio/config.yaml index 4042e3d..7e21cc2 100644 --- a/dashboard_studio/config.yaml +++ b/dashboard_studio/config.yaml @@ -1,5 +1,5 @@ name: Dashboard Studio -version: "2.3.0" +version: "2.3.1" slug: dashboard_studio 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 diff --git a/dashboard_studio/web/app.js b/dashboard_studio/web/app.js index 3a14637..e5877d1 100644 --- a/dashboard_studio/web/app.js +++ b/dashboard_studio/web/app.js @@ -2094,7 +2094,9 @@ else if (act === "light-color") { const [kind, val] = a.dataset.v.split(":"); ha.callService("light", "turn_on", kind === "k" ? { color_temp_kelvin: Number(val) } : { rgb_color: val.split(",").map(Number) }, eid); + if (caches[a.closest(".w[data-id]")?.dataset.id]?.colors) toggleLightColors(a); // a colour picked: the row closes again } + else if (act === "light-colors") toggleLightColors(a); else if (act === "light-popup") lightPopup(eid); else if (act === "todo-add") todoAdd(a.closest(".todo-add")); else if (act === "alarm-key") { @@ -2183,6 +2185,14 @@ if (t.dataset.act === "cover-tilt") ha.callService("cover", "set_cover_tilt_position", { tilt_position: Number(t.value) }, eid); }); + /** The light card's colours, behind their button: open or closed, kept on this device and not saved. */ + function toggleLightColors(btn) { + const box = btn.closest(".w[data-id]"), id = box?.dataset.id, cache = (caches[id] ||= {}); + cache.colors = !cache.colors; + const w = findWidget(id); // also finds a light card inside a scroll or swipe card + if (w) renderWidget(w, box, { child: box.classList.contains("child") }); + } + // ------------------------------------------------------------ dialogs let modalClose = null; function openModal(html, onClick) { diff --git a/dashboard_studio/web/i18n.js b/dashboard_studio/web/i18n.js index 16241cf..5cfa435 100644 --- a/dashboard_studio/web/i18n.js +++ b/dashboard_studio/web/i18n.js @@ -783,6 +783,8 @@ "are open": "staan open", "is open": "staat open", "Hide these entities": "Deze entiteiten verbergen", + "Close colors": "Kleuren sluiten", + "Colors for {0}": "Kleuren voor {0}", "Today": "Vandaag", "Tomorrow": "Morgen", "All day": "Hele dag", "Busy": "Bezet", }; diff --git a/dashboard_studio/web/style.css b/dashboard_studio/web/style.css index ec72ba3..d8635de 100644 --- a/dashboard_studio/web/style.css +++ b/dashboard_studio/web/style.css @@ -1955,8 +1955,6 @@ button.fader-input { cursor: pointer; } .lf-row.on .lf-pct { color: inherit; } .lf-row .switch { transform: scale(.85); } /* not much room: the colours go (the bulb opens them) */ -@container (max-height: 150px) { .lt-foot .swatches { display: none; } } -@container (max-width: 260px) { .lt-foot .swatches { display: none; } } /* room: the name and what's going on, the climate in large figures, then its devices as tiles that light up */ .rm { display: flex; flex-direction: column; gap: 12px; height: 100%; min-height: 0; } @@ -2001,3 +1999,10 @@ button.fader-input { cursor: pointer; } .rm-head .rm-ico { display: none; } } @container (max-width: 200px) and (max-height: 190px) { .lt-sub { display: none; } .lt-big { font-size: 28px; } .lt-main { gap: 4px; } } + +/* the light's colours, behind a palette button */ +.lt-pal { flex: none; width: var(--c-ctl); height: var(--c-ctl); border-radius: 50%; display: grid; place-items: center; font-size: 18px; border: 1.5px solid color-mix(in srgb, currentColor 28%, transparent); box-sizing: border-box; } +.lt.on .lt-pal { color: var(--lit-text); } +.lt-colors { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; } +.lt-colors .swatches { flex: 1; min-width: 0; margin: 0; justify-content: flex-start; } +.lt-colors .swatch { width: 28px; height: 28px; } diff --git a/dashboard_studio/web/widgets.js b/dashboard_studio/web/widgets.js index c80782f..bc779dd 100644 --- a/dashboard_studio/web/widgets.js +++ b/dashboard_studio/web/widgets.js @@ -259,14 +259,19 @@ entities: (c, ha) => [c.entity, ...(ha?.states[c.entity]?.attributes.entity_id || [])].filter(Boolean), // The card is the lamp: when it's on, the brightness fills the card from the left in the lamp's colour, // and dragging anywhere across it dims. A group adds a row per light, each its own little fader. - render(c, { ha }) { + render(c, { ha, cache }) { const s = ha.states[c.entity]; if (!s) return missing(c.entity, "a light"); const members = c.members !== false && Array.isArray(s.attributes.entity_id) ? s.attributes.entity_id.filter((e) => ha.states[e]) : []; const name = friendly(s, c.name); const onCount = members.filter((e) => ha.states[e].state === "on").length; const sub = members.length ? (onCount ? t("{0} of {1} on", onCount, members.length) : t("All off")) : lightNote(s); - const colors = c.colors !== false && !members.length ? swatches(c.entity, s, { compact: true }) : ""; + // The colours wait behind a palette button; opened, they take the figure's place until one is picked. + const hasColors = c.colors !== false && (canTemp(s) || canColor(s)); + const open = hasColors && cache.colors; + const foot = open + ? `