Files
houseplan-card/docs/UX-MODES.md
T

218 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UX redesign: three modes (approved 2026-07-21)
> Approved design for reorganizing all card interactions into three tab-like modes.
> Driven by the owner's mandate and confirmed by real user feedback
> ([issue #3](https://github.com/Matysh/houseplan-card/issues/3): *"When moving the
> map around, I sometimes move the doors/sensors around"*). This document is the
> source of truth for the implemented mode architecture and later iterations.
## Principle
A segmented control in the card header with three tabs; the active one is visually
highlighted, and edit modes add a colored frame around the stage so the mode is
obvious at a glance:
**[ 📐 Plan editor ] [ 🔧 Device editor ] [ ✏️ Background editor ]** — View has
NO tab (since v1.30.2). The Background editor (v1.33.0) manages a purely visual
decor layer (lines/rects/ovals/text in `space.decor`, drawn under the rooms,
inert everywhere outside its editor).
- **View** is the implicit default state: no editor tab is active. Navigation
persistence remembers only the last space. Reloading the page or leaving
House Plan for another Home Assistant route and returning always opens View
for that space; editor mode, selection and open editor dialogs are session
state. A purely technical same-route Lovelace remount may preserve an
unfinished editor session so an internal DOM rebuild does not destroy work.
- Activating an editor tab highlights it and opens that editor's bottom toolbar
(all three editors have one). The toolbar and the active tab each
carry an **X** that closes the editor back to View; re-clicking the active tab
does nothing; editors switch directly with a short content fade and an
interpolation between their measured toolbar heights, including wrapped
multi-row layouts. Toolbar height, usable plan height, zoom/centre, canvas
background and editor-specific layers move on one short timeline, so opening
an editor never flashes a default scale or a mixed dark/white frame. A rapid
second choice retargets from the visible intermediate frame. Reduced-motion
preferences apply the same final state immediately.
- An editor's primary toolbar contains only persistent tools. Close is pinned
in its own end cap. Selection actions, active-tool parameters, operation
hints and palettes appear in one translucent context tray over the top of the
stage, so they do not shrink/refit the plan or move Close. The tray is also
the shared second-level surface for future explicitly approved tool groups;
existing tools are not grouped automatically.
- All editor tabs are shown only to admins when
`admin_only` is on.
## Input support policy
`TOUCH-SUPPORT.md` is authoritative for input parity:
- View and kiosk are fully supported touch surfaces. Essential information and
safe actions may not depend on hover, a fine pointer or keyboard modifiers.
- Plan, Device and Background editors are desktop-first. Mouse/keyboard in a
desktop browser is the reference editing environment.
- Editor operation on touch is best effort. A gesture or precision operation
may be awkward, reduced or absent when correct parity is disproportionately
expensive.
- Best effort never relaxes data integrity, permissions, destructive
confirmations or protection against a pinch/pointer cancellation being saved
as an unintended edit.
The presence of editor tabs on a tablet is not a promise of complete editor
support. User documentation recommends desktop for creation and maintenance.
## View — display and device interaction only
Allowed: pan/zoom (wheel, pinch, buttons), switching spaces, device tap
(info / more-info / toggle per settings), long-press → info card, opening tap →
door/lock info card (with an explicit Unlock/Lock button when a lock is bound —
the only way to operate a lock from the card; plan-icon taps never toggle locks),
room-card link icon → HA area (room taps do nothing since v1.40.1), room hover
highlight, hover tooltips (name, clean-floor area, temperature, signal).
Removed from this mode (they move, not die):
- icon dragging ("drag anywhere", v1.9 — consciously reversed),
- room-label dragging,
- opening dragging along walls and double-click properties (v1.23.1),
- every edit button in the header (+device, 👁 show-all, ↺ reset, ⬡ rules, ⚙ general,
per-space gear, markup toggle).
Header in View: space tabs, device count, zoom cluster. Nothing else.
## Plan — geometry and appearance of the space
- Toolbar tools: **Walls** / room outline (with its session wall-thickness field
immediately on the right, default 15 cm — docs/WALL-THICKNESS.md §6), Delete
room, Merge, Split, Resize, Partition, Column,
Opening (place / drag along walls / properties), Boundary, Thickness
(docs/WALL-THICKNESS.md — click a wall, set cm/inches from HA's unit system;
empty/0 clears), Room labels (drag positions — labels are part of the plan).
- Space gear dialog (title, plan image / hand-drawn, scale, Display section, show_lqi),
add space, floors import, delete space. Saving a **new** space opens this
editor with the draw tool armed (an empty floor has nothing useful in View).
- ⚙ General settings (fill palette) lives here — it is about the plan's appearance.
- Independent partitions and columns are masonry for hit testing as well as
area/light: room hover stops at their physical bodies just as it stops at a
thick room wall. This does not split the room or change its HA area.
- Boundary is contextual: two points on one solid shared wall make the selected
stretch virtual; one click on an existing dashed stretch restores it whole.
Outer walls and room boundaries hidden under independent masonry are not
edited through the object above them.
### What a space may choose not to draw (2026-08-05)
Three switches in the space's Display section decide how much of the plan is
inked. All of them are **display only** — nothing is deleted, nothing changes
meaning, and each layer stays visible in the editor that owns it, because a
layer you cannot see is a layer you cannot edit.
| Setting | Off (default) | On | Always drawn in |
|---|---|---|---|
| `show_borders` — «Всегда отображать границы комнат» | in View, borders and dashed **virtual walls** are hidden | both are drawn | room borders: Plan; virtual walls: all editors |
| `hide_decor` — «Скрыть декоративный слой» | decor is drawn | lines, shapes, labels and furniture are hidden | the Background editor |
| `hide_openings` — «Скрыть проёмы» | doors, windows and gates are drawn | their symbols are hidden | the Plan editor |
- **Virtual walls follow `show_borders` in View** (owner, 2026-08-05). They are
walls — dashed ones. Drawing them on a View with no borders left a plan whose
only walls were a few floating dashed stretches. Every editor deliberately
shows them regardless of the switch: hiding geometry while editing a plan,
device placement or its underlay makes those modes visually ambiguous.
- **Their geometry and their presentation are separate.** Every virtual span
still ends on the real wall centreline. In View the thick wall body is
painted over the dash ends, so they visually stop at its faces; editors paint
the full dash (and live preview) over the body for unambiguous editing.
- **`hide_openings` hides the symbol, not the opening.** Light still spills
through it, the sun still enters at a window, a contact sensor still opens
it, and the resize tool still anchors to it. Anything else would be a second
meaning for one setting.
- Both new switches store **nothing when off** (the key is omitted, as
`bg_color` is), so a plan written before this reads back byte-for-byte.
Backend: `hide_decor` / `hide_openings`, strictly `bool`, both optional.
## Devices — placement and marker configuration
- Icon dragging (ONLY here). Click on a device opens the **edit dialog directly**
(binding, name, icon, size/angle, display as icon / icon + activity / value,
activity color and size, tap override,
model/link/description/PDFs, room).
- + add device/entity/virtual, the bottom-left "Hide" / "Show" action in an
existing device dialog (the one hiding mechanism, docs/FILTERING.md), ↺ reset layout,
👁 "Show hidden" (local editor tool; replaced the shared show-all toggle),
⬡ icon rules.
## Background — the decor underlay
- Toolbar tools: Select / optional Plan backdrop / Line / Rectangle / Oval /
Text / Furniture / Erase, plus contour colour+opacity, physical width,
optional fill colour+opacity and shared Undo/Redo. Shapes are drag-drawn
with grid/decor/room snap and a live preview.
- In **Select**, double click always means “edit this object”. Text opens its
text/HA-variable form; a line, rectangle, oval or furniture symbol opens the
complete numeric/style form, with Fill where the shape supports it. Every
selected kind has the common move/resize/rotate controller; lines use end
handles. The image is transformed only in its own tool and fades to 0.5
below the other Background tools.
- **Live size badge** (owner 2026-08-04): while a LINE is being dragged out, the
same `.measurelabel` the Plan editor puts on a wall shows «length · angle» —
`segmentCm` over the space's `cell_cm`, metres or feet per the HA unit system,
green on a 45° multiple. It rides the MIDDLE of the segment (a wall badge
follows the cursor because the cursor is the wall's free end; a decor line is
pulled out by both ends at once), updates on every move and disappears the
moment the shape is committed. Rectangles show size and area; circles show
`R`, and non-circular ovals `Rx × Ry`; a draft with no size shows nothing.
## Plan — independent physical objects
- **Walls** still draws room contours. An unfinished contour is saved after
every completed segment and can be resumed from either free endpoint. A
click on the endpoint of another saved outline joins both records; branching
from the middle of a segment is intentionally not supported.
- **Partition** draws one physical wall segment; **Column** places a square
column whose side is the current Thickness value. Neither object creates a
room or HA area. A closed partition ring subtracts only its wall body from
the original room floor.
- **Select** is the only mode in which these objects intercept input. It offers
rigid grid-bound drag, double-click/tap properties, Delete, and a rotate
handle for square columns (5° steps; Shift is free). Draft Delete removes the
whole outline; its properties dialog separately offers segment deletion.
- Physical objects are inert in View/kiosk. `show_borders: false` hides their
paint in View without changing area or light physics.
## Deprecations decided
1. "Drag anywhere" (v1.9) — reversed by this design.
2. Opening drag / dbl-click properties in view (v1.23.1) — moved into Plan.
3. The markup toggle button — replaced by the Plan tab.
4. Legacy localStorage mode (card without the integration) — candidate for removal
in the next major; adds branching for a half-working scenario.
## Approved follow-up features (from issue #3, by priority)
1. State-reflecting icons (open/closed door variants etc., like core HA).
2. `display: value` — show the measurement instead of an icon.
3. Light color in the activity effect (RGB lights). *(Shipped in v1.27.0;
superseded in v1.52.0: the colour lives in the glow spot and the activity
fallback only, the icon tint was removed by the owner's rule.)*
4. Alarm visual (leak/smoke/doorbell): red pulse overlay.
5. Rooms as sub-areas without an HA area + manual device placement by room id.
6. Backlog (not planned): music notes for players, directional TV effects.
## Implementation iterations
- **It.1 — mode shell:** the segmented control, mode state, View-mode gating of all
edit interactions/buttons (biggest UX win, smallest surface).
- **It.2 — Plan tab:** move markup tools + space dialogs + labels drag + openings
editing under Plan; colored frame indicator.
- **It.3 — Devices tab:** drag + direct-edit click + filtering tools under Devices.
- **It.4+:** follow-up features 1–5 above, each its own release.
## Kiosk mode (v1.41.0)
`kiosk: true` on the card is the fourth interaction surface: the full View
experience with the header removed and editors hard-blocked (even for
admins). Swipe switches spaces at 1:1 zoom only (zoomed gestures pan;
double tap resets zoom); `cycle: N` auto-advances spaces with a 60 s pause
after any touch; a 3 s long-press on empty plan opens the per-screen size
popover (localStorage). Nav persistence never restores an editor here.