Files
houseplan-card/docs/data-hp-contract.json
T
Codex d21fba11d6 feat(card): the LED strip tool in the Devices editor (#780)
Stage 4 of #780 (ТЗ §4–§5). «LED strip» next to «Add» draws a chain with
clean clicks only (pan, pinch, a second finger, cancel and the synthetic
click after navigation add nothing), snaps to the grid and to physical wall
faces / zero-wall axes, stops at the first face of masonry, partitions,
columns and windows (doors, gates and passages are cut by geometry), Shift
gives 45°. Ctrl+Z removes the chain's own point first, Esc finishes, a
double click or a click on the first point (≥3 vertices) closes; fewer than
two distinct points write nothing. A finished strip opens the device picker
(lights first, taken markers explained, «New device…» binds in that
dialog's own write, «Later» keeps unbound geometry).

A selected strip shows its vertex handles (a drag re-checks both neighbours
and the whole path) and a new Devices tray branch: device settings,
bind/change, unbind, show as icon, delete. The device dialog gets the
representation section: show as strip (restores a hidden shape at once or
draws one for this marker, behind the dialog's own save/discard guard),
show as icon, unbind/delete for a hidden shape. Every geometry or
representation change is one optimistic write and one LED command of the
device history; Undo/Redo restores only its own strip record and refuses
when a newer change sits on it. A rebinding renames the link in the marker
save, a deleted marker leaves an unbound strip, a bound marker may not move
to another space. Plan/Background show strips as a passive translucent mark.

The tool, its `led` dictionary (en static, ru/de/fr lazy) and placement
geometry are a new lazy `led-strip-editor` chunk (9.5 KB gzip), loaded only
on the tool, an editable strip in the shown space or a strip device's
dialog. The initial graph gets the loader and delegation only
(src/led-strip-card.ts); the lazy editor graph +122 B, inside its ceiling.
Mutant anchors follow the moved code (marker dialog guard, static LED layer).

Issue: #780
User-Visible: no
2026-10-02 20:54:50 +03:00

285 lines
6.6 KiB
JSON

{
"schemaVersion": 1,
"attribute": "data-hp",
"stability": {
"removalPolicy": "changelog-and-one-stable-version-transition",
"additionsAreCompatible": true
},
"hooks": {
"create-space": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"decor": {
"elements": ["ellipse", "image", "line", "path", "rect", "text"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"device": {
"elements": ["div"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"dialog": {
"elements": ["hp-dialog"],
"since": "1.73.0-beta.7",
"audience": ["test"],
"attributes": {
"data-kind": [
"backup",
"confirm",
"decor",
"device-inbox",
"import",
"info",
"kiosk",
"led-picker",
"marker",
"onboarding",
"opening",
"pdf",
"physical",
"room",
"rules",
"settings",
"space",
"stairs",
"summary",
"support",
"vacuum"
]
}
},
"dialog-cancel": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"dialog-confirm": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"editor-close": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"empty": {
"elements": ["div"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"header-menu": {
"elements": ["button"],
"since": "1.78.0-beta.3",
"audience": ["styling", "test"]
},
"header-menu-item": {
"elements": ["button"],
"since": "1.78.0-beta.3",
"audience": ["styling", "test"],
"attributes": { "data-id": ["mode-plan", "mode-devices", "mode-decor", "space-settings", "space-add", "settings", "pdf", "support", "summary-settings", "summary-toggle"] }
},
"header-menu-scrim": {
"elements": ["div"],
"since": "1.78.0-beta.3",
"audience": ["test"]
},
"mode-tab": {
"elements": ["button"],
"since": "1.78.0-beta.2",
"audience": ["test"],
"attributes": { "data-mode": ["plan", "devices", "decor"] }
},
"opening": {
"elements": ["g"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"opening-tunnel": {
"elements": ["g", "path"],
"since": "1.60.2",
"audience": ["styling", "test"]
},
"panel-menu": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"panel-title": {
"elements": ["div"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"partition": {
"elements": ["path"],
"since": "1.60.2-beta.1",
"audience": ["styling", "test"]
},
"pdf": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"room": {
"elements": ["path", "polygon", "rect"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"room-label": {
"elements": ["div"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"room-settings": {
"elements": ["button"],
"since": "1.67.0-rc.2",
"audience": ["styling", "test"]
},
"settings": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"space-add": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"space-settings": {
"elements": ["ha-icon"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"space-tab": {
"elements": ["button"],
"since": "1.59.0-beta.3",
"audience": ["styling", "test"]
},
"stair": {
"elements": ["g"],
"since": "1.78.0-beta.5",
"audience": ["styling", "test"]
},
"stair-frame": {
"elements": ["g"],
"since": "1.78.0-beta.6",
"audience": ["styling", "test"]
},
"support": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"toast": {
"elements": ["div"],
"since": "1.73.0-beta.7",
"audience": ["test"],
"attributes": {
"data-kind": ["message"]
}
},
"tool": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"],
"attributes": {
"data-tool": [
"add-device",
"backdrop",
"column",
"delete-room",
"device-inbox",
"draw",
"ellipse",
"erase",
"furniture",
"icon-rules",
"image",
"line",
"merge",
"opening",
"rect",
"resize",
"select",
"split",
"stairs",
"text",
"wall-thickness"
]
}
},
"toolbar": {
"elements": ["div"],
"since": "1.73.0-beta.7",
"audience": ["test"],
"attributes": {
"data-kind": ["decor", "device", "plan"]
}
},
"tray": {
"elements": ["div"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"wall": {
"elements": ["path"],
"since": "1.59.0-beta.4",
"audience": ["styling", "test"]
},
"wall-column": {
"elements": ["path"],
"since": "1.60.2-beta.1",
"audience": ["styling", "test"]
},
"zoom-fit": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"zoom-in": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
},
"zoom-out": {
"elements": ["button"],
"since": "1.73.0-beta.7",
"audience": ["test"]
}
},
"rootAttributes": {
"data-hp-mode": {
"element": "ha-card",
"values": ["view", "plan", "devices", "decor"],
"since": "1.73.0-beta.7"
},
"data-hp-state": {
"element": "ha-card",
"values": ["booting", "ready"],
"since": "1.73.0-beta.7"
}
},
"retiredHooks": {
"room-draft": {
"elements": ["line"],
"since": "1.60.2-beta.1",
"retired": "1.73.0-beta.1",
"reason": "Unfinished room contours were replaced by ordinary partitions in issue #478."
}
},
"internalPrefixes": [
"hidden-wall-",
"iso-",
"plan-snap-",
"resize-",
"zigbee-topology-"
],
"internalExactValues": [
"opening-orphan",
"vacuum-route-missing-group"
]
}