Dashboard Studio 1.12.0: new cards, kiosk doorbell, night mode, editor tools, version history

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 15:12:30 +01:00
parent f9822a9c49
commit 7abf7379d8
11 changed files with 1728 additions and 182 deletions
+87
View File
@@ -86,11 +86,98 @@
pause: "M6 4h4v16H6zM14 4h4v16h-4z",
next: "M4 5.2v13.6a.7.7 0 0 0 1.1.6L15 12.6a.7.7 0 0 0 0-1.2L5.1 4.6a.7.7 0 0 0-1.1.6zM17 4h3v16h-3z",
prev: "M20 5.2v13.6a.7.7 0 0 1-1.1.6L9 12.6a.7.7 0 0 1 0-1.2l9.9-6.8a.7.7 0 0 1 1.1.6zM4 4h3v16H4z",
// rooms
bed: "M3 18v-7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7M3 15h18M7 9V7a1 1 0 0 1 1-1h3a1 1 0 0 1 1 1v2M3 18v2M21 18v2",
bath: "M4 12h16v3a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zM6 12V6a2 2 0 0 1 3.5-1.3M7 19l-1 2M17 19l1 2",
shower: "M4 21V8a4 4 0 0 1 8 0M9 8h6M11 12v.01M13 14v.01M15 12v.01M11 16v.01M15 16v.01M13 18v.01",
kitchen: "M4 10h16v6a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zM2 10h20M9 6c0-1 1-1.5 1-2.5M14 6c0-1 1-1.5 1-2.5",
dining: "M7 3v8M5 3v4a2 2 0 0 0 4 0V3M7 11v10M17 3c-2 0-3 2-3 5s1 4 3 4v9",
desk: "M3 10h18M5 10v9M19 10v9M14 14h5M8 4h8v6H8z",
kids: "M12 21a7 7 0 1 0 0-14 7 7 0 0 0 0 14zM9.5 13h.01M14.5 13h.01M10 16.5c1 .7 3 .7 4 0M7 8.5 5 6M17 8.5 19 6",
laundry: "M4 9h16l-1.5 11a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM8 9l3-5M16 9l-3-5M9 13v4M15 13v4",
stairs: "M3 20h5v-4h4v-4h4V8h5",
tree: "M12 22v-6M12 16a5 5 0 0 0 5-5 5 5 0 0 0-2-4 4 4 0 0 0-6 0 5 5 0 0 0-2 4 5 5 0 0 0 5 5z",
plant: "M12 21v-8M12 13c0-4 3-7 7-7 0 4-3 7-7 7zM12 15c0-3-2.5-5.5-6-5.5 0 3.5 2.5 5.5 6 5.5zM8 21h8",
// tools
wrench: "M14.7 6.3a4 4 0 0 0-5.4 5.2L3 17.8V21h3.2l6.3-6.3a4 4 0 0 0 5.2-5.4l-2.6 2.6-2.4-.6-.6-2.4z",
hammer: "M14 6l4 4M11 3l6 6-2 2-6-6zM13 9l-9 9a1.5 1.5 0 0 0 2 2l9-9",
toolbox: "M3 9h18v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zM8 9V6a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v3M3 14h18M10 14v2M14 14v2",
sliders: "M4 6h10M18 6h2M4 12h4M12 12h8M4 18h12M14 4v4M8 10v4M16 16v4",
key: "M8 15a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM12 11h9M18 11v3M15 11v2",
// appliances
fridge: "M6 2h12a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zM5 10h14M9 5v2M9 13v3",
oven: "M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM3 8h18M7 5.5h.01M11 5.5h.01M7 12h10v5H7z",
microwave: "M3 5h18a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM5 8h11v8H5zM19 8v.01M19 11v.01M19 14v2",
kettle: "M6 9h10l1 10a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1zM7 9l1-4h6l1 4M16 11h2a2 2 0 0 1 0 4h-1.5M9 3h4",
coffee: "M5 9h11v6a5 5 0 0 1-5 5h-1a5 5 0 0 1-5-5zM16 11h1.5a2.5 2.5 0 0 1 0 5H16M8 3c0 1 1 1.5 1 2.5M12 3c0 1 1 1.5 1 2.5",
tv: "M3 5h18a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1zM8 21h8M12 18v3",
radiator: "M6 4v16M10 4v16M14 4v16M18 4v16M4 7h16M4 17h16",
purifier: "M7 3h10a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zM9 7h6M9 10h6M12 17a2 2 0 1 0 0-4 2 2 0 0 0 0 4z",
aircon: "M3 5h18a1 1 0 0 1 1 1v6H2V6a1 1 0 0 1 1-1zM5 9h14M7 15c0 1.5-1 2-1 3M12 15c0 1.5-1 2-1 3M17 15c0 1.5-1 2-1 3",
// devices
phone: "M8 2h8a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zM11 18h2",
laptop: "M5 5h14a1 1 0 0 1 1 1v9H4V6a1 1 0 0 1 1-1zM2 18h20l-1.5 2h-17z",
wifi: "M2 9a15 15 0 0 1 20 0M5 12.5a10 10 0 0 1 14 0M8.5 16a5 5 0 0 1 7 0M12 19.5v.01",
printer: "M7 8V3h10v5M17 16h4v-6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v6h4M7 13h10v8H7z",
server: "M4 3h16v7H4zM4 14h16v7H4zM8 6.5h.01M8 17.5h.01",
gamepad: "M6 8h12a4 4 0 0 1 4 4v1a4 4 0 0 1-7 2.6L14 15h-4l-1 .6A4 4 0 0 1 2 13v-1a4 4 0 0 1 4-4zM7 10v4M5 12h4M15.5 11.5v.01M17.5 13.5v.01",
headphones: "M4 15v-3a8 8 0 0 1 16 0v3M4 15a2 2 0 0 1 2-2h1v7H6a2 2 0 0 1-2-2zM20 15a2 2 0 0 0-2-2h-1v7h1a2 2 0 0 0 2-2z",
bell: "M6 16v-5a6 6 0 0 1 12 0v5l2 2H4zM10 20a2 2 0 0 0 4 0",
smoke: "M12 9a3 3 0 1 0 0 6 3 3 0 0 0 0-6zM4 12a8 8 0 0 0 16 0M7 4.5c1.5-1 3-1.5 5-1.5s3.5.5 5 1.5",
leak: "M12 3s5 5.5 5 9a5 5 0 0 1-10 0c0-3.5 5-9 5-9zM3 21h18M6 18h.01M18 18h.01",
solar: "M4 4h16l2 10H2zM2 14h20M8 4l-1 10M16 4l1 10M3 9h18M12 14v4M8 21h8",
charger: "M6 3h8a1 1 0 0 1 1 1v17H5V4a1 1 0 0 1 1-1zM3 21h14M15 9h2a2 2 0 0 1 2 2v5a1.5 1.5 0 0 0 3 0V8l-3-3M10 7l-2 4h4l-2 4",
lamp: "M9 3h6l3 7H6zM12 10v10M8 21h8",
ceiling: "M12 2v5M7 12a5 5 0 0 1 10 0zM9 15l-1 2M12 15v3M15 15l1 2",
ledstrip: "M3 8h18v8H3zM6 11v2M10 11v2M14 11v2M18 11v2",
blinds: "M4 3h16M5 3v18M19 3v18M5 7h14M5 11h14M5 15h14M12 15v4",
curtain: "M3 3h18M5 3c0 6 1 12 3 18M19 3c0 6-1 12-3 18M8 3c0 4 .5 9 2 13M16 3c0 4-.5 9-2 13",
fence: "M3 21V7l3-3 3 3v14M15 21V7l3-3 3 3v14M3 11h18M3 17h18",
mailbox: "M4 10a4 4 0 0 1 8 0v9H4zM12 10h6a2 2 0 0 1 2 2v7h-8M8 19v2M16 8V3h3v2h-3",
paw: "M12 13c-3 0-5 3-5 5a2 2 0 0 0 2 2c1 0 2-.5 3-.5s2 .5 3 .5a2 2 0 0 0 2-2c0-2-2-5-5-5zM4.5 9.5a1.5 2 0 1 0 3 0 1.5 2 0 1 0-3 0M16.5 9.5a1.5 2 0 1 0 3 0 1.5 2 0 1 0-3 0M8 5.5a1.5 2 0 1 0 3 0 1.5 2 0 1 0-3 0M13 5.5a1.5 2 0 1 0 3 0 1.5 2 0 1 0-3 0",
bike: "M2 17.5a3.5 3.5 0 1 0 7 0 3.5 3.5 0 1 0-7 0M15 17.5a3.5 3.5 0 1 0 7 0 3.5 3.5 0 1 0-7 0M5.5 17.5 9 10h6l3.5 7.5M9 10 8 7H6M15 10l-2.5 7.5",
// for the new cards and the editor
sunrise: "M12 3v5M8.5 6.5 12 3l3.5 3.5M6.3 14.3 5 13M17.7 14.3 19 13M8 18a4 4 0 0 1 8 0M2 21h20",
sunset: "M12 8V3M8.5 4.5 12 8l3.5-3.5M6.3 14.3 5 13M17.7 14.3 19 13M8 18a4 4 0 0 1 8 0M2 21h20",
umbrella: "M3 12a9 9 0 0 1 18 0zM12 12v7a2 2 0 0 0 4 0",
timer: "M12 21a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM12 9v4l2.5 2M10 2h4M19 5l1.5-1.5",
checkbox: "M5 4h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM8 12l3 3 5-6",
circle: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18z",
history: "M3 12a9 9 0 1 0 3-6.7M3 4v5h5M12 7v5l3 2",
search: "M11 18a7 7 0 1 0 0-14 7 7 0 0 0 0 14zM21 21l-5-5",
people: "M9 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM3 20v-1a6 6 0 0 1 12 0v1M16 5a3 3 0 0 1 0 6M21 20v-1a5 5 0 0 0-3-4.6",
palette: "M12 21a9 9 0 1 1 9-9c0 2-1.5 3-3 3h-2a2 2 0 0 0-1.5 3.3A1.5 1.5 0 0 1 12 21zM7.5 11.5v.01M10 7.5v.01M14.5 7.5v.01M17 11.5v.01",
keypad: "M6 4h.01M12 4h.01M18 4h.01M6 10h.01M12 10h.01M18 10h.01M6 16h.01M12 16h.01M18 16h.01M12 21h.01",
"arrow-up": "M12 19V5M5 12l7-7 7 7",
"arrow-down": "M12 5v14M19 12l-7 7-7-7",
"copy-to": "M9 9h11v11H9zM5 15H4V4h11v1M13 14.5h4M15 12.5l2 2-2 2",
};
const FILLED = new Set(["play", "pause", "next", "prev"]);
// Dutch (and some English) words for the icon search, so "keuken" or "slaapkamer" find something.
const WORDS = {
bed: "slaapkamer bedroom", bath: "badkamer bad bathroom", shower: "douche badkamer", kitchen: "keuken koken pan", dining: "eetkamer eten bestek",
desk: "kantoor bureau werkkamer office", kids: "kinderkamer kind baby", laundry: "was wasmand washok", stairs: "trap overloop", tree: "tuin boom garden",
plant: "plant bloem", sofa: "woonkamer bank living", garage: "garage", home: "huis thuis", wrench: "gereedschap moersleutel tool",
hammer: "hamer gereedschap klus", toolbox: "gereedschapskist klus", sliders: "instellingen regelaar", key: "sleutel", fridge: "koelkast vriezer",
oven: "oven fornuis", microwave: "magnetron", kettle: "waterkoker thee", coffee: "koffie", tv: "televisie scherm", radiator: "verwarming radiator heater",
purifier: "luchtreiniger luchtbevochtiger", aircon: "airco koeling", phone: "telefoon mobiel", laptop: "laptop computer", wifi: "wifi router netwerk internet",
printer: "printer", server: "server nas", gamepad: "spelcomputer games console", headphones: "koptelefoon", bell: "deurbel bel melding",
smoke: "rookmelder brand", leak: "lekkage water", solar: "zonnepanelen zon", charger: "laadpaal auto laden", lamp: "lamp staande lamp",
ceiling: "plafondlamp hanglamp", ledstrip: "ledstrip", blinds: "jaloezie lamellen rolluik", curtain: "gordijn", fence: "hek poort", mailbox: "brievenbus post",
paw: "huisdier hond kat", bike: "fiets", bulb: "lamp licht", plug: "stopcontact stekker", fan: "ventilator", thermometer: "temperatuur thermostaat",
droplet: "water vocht", washer: "wasmachine", dryer: "droger", dishwasher: "vaatwasser", vacuum: "stofzuiger robot", car: "auto", lock: "slot",
camera: "camera", speaker: "speaker luidspreker", music: "muziek", door: "deur", window: "raam", timer: "timer kookwekker", people: "personen familie",
};
/** Icon names matching a search, by name or by the words above. */
function search(filter) {
const f = String(filter || "").trim().toLowerCase();
return Object.keys(P).filter((n) => !FILLED.has(n)).sort().filter((n) => !f || n.includes(f) || (WORDS[n] || "").includes(f));
}
window.Icons = {
names: Object.keys(P).filter((n) => !FILLED.has(n)),
search,
has: (n) => Object.prototype.hasOwnProperty.call(P, n),
svg(name, cls = "") {
if (!this.has(name)) return "";