diff --git a/custom_components/houseplan/const.py b/custom_components/houseplan/const.py
index 876219c..a1d63f5 100755
--- a/custom_components/houseplan/const.py
+++ b/custom_components/houseplan/const.py
@@ -11,7 +11,7 @@ PLANS_DIR = "houseplan/plans" # relative to the HA configuration directory
FILES_URL = "/houseplan_files/files"
FILES_DIR = "houseplan/files"
CONF_ADMIN_ONLY = "admin_only"
-VERSION = "1.18.0"
+VERSION = "1.18.1"
DEFAULT_CONFIG: dict = {
"spaces": [],
diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js
index 883ccdf..127bc52 100755
--- a/custom_components/houseplan/frontend/houseplan-card.js
+++ b/custom_components/houseplan/frontend/houseplan-card.js
@@ -239,6 +239,11 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
z-index: 1;
}
.roomlabel:active { cursor: grabbing; }
+ .measurelayer {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ }
.measurelabel {
position: absolute;
transform: translate(12px, -150%);
@@ -1126,8 +1131,8 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
${s.map(t=>this._renderDevice(t,n))}
${a.showNames&&!this._markup?e.rooms.map(t=>this._renderRoomLabel(t,e,n,a)):K}
- ${this._markup&&"draw"===this._tool&&this._path.length&&this._cursorPt&&!this._contourClosed?this._renderMeasureLabel(n):K}
+ ${this._markup&&"draw"===this._tool&&this._path.length&&this._cursorPt&&!this._contourClosed?j`${this._renderMeasureLabel(n)}
`:K}
${this._zoom>1?j`${Math.round(100*this._zoom)}%
`:K}
@@ -1428,4 +1433,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
- `}}ue.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},ue.styles=Vt,customElements.get("houseplan-card")||customElements.define("houseplan-card",ue),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.18.0 ","background:#3ea6ff;color:#04121f;font-weight:700","");
+ `}}ue.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},ue.styles=Vt,customElements.get("houseplan-card")||customElements.define("houseplan-card",ue),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.18.1 ","background:#3ea6ff;color:#04121f;font-weight:700","");
diff --git a/custom_components/houseplan/manifest.json b/custom_components/houseplan/manifest.json
index e41947e..d75fb47 100755
--- a/custom_components/houseplan/manifest.json
+++ b/custom_components/houseplan/manifest.json
@@ -16,5 +16,5 @@
"issue_tracker": "https://github.com/Matysh/houseplan-card/issues",
"requirements": [],
"single_config_entry": true,
- "version": "1.18.0"
+ "version": "1.18.1"
}
diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js
index 883ccdf..127bc52 100755
--- a/dist/houseplan-card.js
+++ b/dist/houseplan-card.js
@@ -239,6 +239,11 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
z-index: 1;
}
.roomlabel:active { cursor: grabbing; }
+ .measurelayer {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ }
.measurelabel {
position: absolute;
transform: translate(12px, -150%);
@@ -1126,8 +1131,8 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
${s.map(t=>this._renderDevice(t,n))}
${a.showNames&&!this._markup?e.rooms.map(t=>this._renderRoomLabel(t,e,n,a)):K}
- ${this._markup&&"draw"===this._tool&&this._path.length&&this._cursorPt&&!this._contourClosed?this._renderMeasureLabel(n):K}
+ ${this._markup&&"draw"===this._tool&&this._path.length&&this._cursorPt&&!this._contourClosed?j`${this._renderMeasureLabel(n)}
`:K}
${this._zoom>1?j`${Math.round(100*this._zoom)}%
`:K}
@@ -1428,4 +1433,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
- `}}ue.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},ue.styles=Vt,customElements.get("houseplan-card")||customElements.define("houseplan-card",ue),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.18.0 ","background:#3ea6ff;color:#04121f;font-weight:700","");
+ `}}ue.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},ue.styles=Vt,customElements.get("houseplan-card")||customElements.define("houseplan-card",ue),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.18.1 ","background:#3ea6ff;color:#04121f;font-weight:700","");
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 27f5772..7743ac2 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -1,5 +1,15 @@
# Changelog
+## v1.18.1 — 2026-07-16 (fix: the drawing ruler was invisible)
+- Fix on top of v1.18.0: the length badge never showed up while drawing. It was rendered
+ inside `.devlayer`, and `.stage.markup .devlayer { display: none }` hides that whole layer
+ in markup mode (so icons do not get in the way) — the badge was in the DOM but invisible.
+ It now lives in its own `.measurelayer` (absolute, `pointer-events: none`), which markup
+ mode does not hide. Verified visually on a real drawn segment ("3.60 m" on screen).
+- Testing lesson (see docs/TESTING.md): asserting on `textContent` is not enough — a DOM
+ query passes on elements hidden by an ancestor. Check `offsetParent`/rect or look at a
+ screenshot.
+
## v1.18.0 — 2026-07-14 (live measurements while drawing rooms + per-space scale)
- **Ruler while drawing.** In room-markup "draw" mode, a badge follows the cursor showing the
length of the current segment (last placed vertex → cursor). Units come from the HA unit
diff --git a/docs/STATUS.md b/docs/STATUS.md
index b140d5a..12cd718 100644
--- a/docs/STATUS.md
+++ b/docs/STATUS.md
@@ -13,7 +13,7 @@
| Item | State |
|---|---|
-| Version | **v1.18.0** everywhere (manifest, const.py, package.json, CARD_VERSION) |
+| Version | **v1.18.1** everywhere (manifest, const.py, package.json, CARD_VERSION) |
| GitHub | https://github.com/Matysh/houseplan-card — branch `main`, releases v1.9.3…v1.11.2 |
| CI | `.github/workflows/validate.yml` (hacs + hassfest + frontend + backend) — **fully green** since v1.11.1; `release.yml` auto-attaches the card bundle (needs `permissions: contents: write`, fixed) |
| HACS | Works as custom repository (id 1290210112 on the home instance). **Inclusion PR: https://github.com/hacs/default/pull/9004** (queue ≈2 months as of 2026-07). Lesson: #8995 was auto-closed by hacs-bot — the PR body MUST be their exact template with every checkbox ticked and all 3 links (release, HACS action run, hassfest run); a custom body gets closed without discussion |
diff --git a/package.json b/package.json
index 1fefcb1..edbeb3c 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "houseplan-card",
- "version": "1.18.0",
+ "version": "1.18.1",
"description": "Interactive house plan Lovelace card for Home Assistant",
"license": "MIT",
"type": "module",
diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts
index 533bbb3..ca8eaf0 100755
--- a/src/houseplan-card.ts
+++ b/src/houseplan-card.ts
@@ -27,7 +27,7 @@ import './space-card';
import { cardStyles } from './styles';
import { langOf, t, type I18nKey } from './i18n';
-const CARD_VERSION = '1.18.0';
+const CARD_VERSION = '1.18.1';
const LS_KEY = 'houseplan_card_layout_v1';
const LS_CFG = 'houseplan_card_cfg_v1'; // cache of the server config+layout for instant rendering
const LS_ZOOM = 'houseplan_card_zoom_v1';
@@ -2025,10 +2025,10 @@ class HouseplanCard extends LitElement {
${disp.showNames && !this._markup
? space.rooms.map((r) => this._renderRoomLabel(r, space, view, disp))
: nothing}
- ${this._markup && this._tool === 'draw' && this._path.length && this._cursorPt && !this._contourClosed
- ? this._renderMeasureLabel(view)
- : nothing}
+ ${this._markup && this._tool === 'draw' && this._path.length && this._cursorPt && !this._contourClosed
+ ? html`${this._renderMeasureLabel(view)}
`
+ : nothing}
${this._zoom > 1
? html`${Math.round(this._zoom * 100)}%
`
diff --git a/src/styles.ts b/src/styles.ts
index 7e57c9c..cf07c26 100644
--- a/src/styles.ts
+++ b/src/styles.ts
@@ -236,6 +236,11 @@ export const cardStyles = css`
z-index: 1;
}
.roomlabel:active { cursor: grabbing; }
+ .measurelayer {
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ }
.measurelabel {
position: absolute;
transform: translate(12px, -150%);