wifi-densepose/frontend
ruv 89190b6c2d feat(homecore-ui iter 2): Edit Entity modal + shadow-DOM focus delegation
CRUD increment 2/6 — clicking any state card on the Dashboard opens
the Add Entity modal in EDIT mode: pre-populated, entity_id locked,
"Save" primary button, idempotent POST to /api/states/<id> (backend
returns 200 if existed, 201 if created — same handler).

frontend/src/components/StateCard.ts:
  - card div is now role="button" tabindex=0, dispatches
    `hc-state-card-click` on click + Enter/Space keydown
  - aria-label="Edit <entity_id>" for screen readers
  - shadowRootOptions delegatesFocus=true so the outer Tab sequence
    can reach the inner focusable div (caught by browser agent —
    without this Tab couldn't pierce the shadow root)

frontend/src/pages/Dashboard.ts:
  - new state: editingState (null = create, StateView = edit)
  - _openEdit() catches `hc-state-card-click` from the grid container
  - modal heading switches: "Add entity" ↔ "Edit <entity_id>"
  - primary button text switches: "Create" ↔ "Save"
  - EntityForm receives .editing=true so entity_id input is disabled
  - submit toast reads "Updated" or "Created" depending on mode

Browser-verified end-to-end (real homecore-server :8123, 12 entities):
  - Click `light.kitchen_ceiling` → modal opens with all 4 attributes
    (brightness=230, color_temp_kelvin=4000, friendly_name,
    supported_color_modes) pre-populated
  - Change state to "off", click Save → toast "Updated
    light.kitchen_ceiling = off", grid card reflects new state
  - Backend curl confirms /api/states/light.kitchen_ceiling.state = "off"
  - Enter key on focused card opens the modal too
  - 0 console errors

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-26 14:48:49 -04:00
..
src feat(homecore-ui iter 2): Edit Entity modal + shadow-DOM focus delegation 2026-05-26 14:48:49 -04:00
.gitignore HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
README.md HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
index.html HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
package-lock.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
package.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
tsconfig.json HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
vite.config.ts HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00
vitest.config.ts HOMECORE: native Rust/WASM/TS port of Home Assistant — ADRs 125-134 implementation (#800) 2026-05-25 22:47:48 -04:00

README.md

@ruvnet/homecore-frontend

HOMECORE web UI — built with Lit 3, TypeScript, and Vite. Design system mirrors the cognitum-v0 / v0-appliance dashboard (ADR-131).

Quick start

cd frontend
npm install
npm run dev          # http://localhost:5173

The Vite dev server proxies /apihttp://localhost:8123, so you need a homecore-api-server (or the wifi-densepose-sensing-server crate) running on :8123.

Scripts

Script Description
npm run dev Start Vite dev server on port 5173
npm run build TypeScript compile + Vite production bundle → dist/
npm run lint ESLint on src/
npm test Vitest unit tests (3 suites, jsdom)

Package layout

frontend/
  src/
    api/
      client.ts        # fetch + WebSocket client (REST + WS)
      types.ts         # TypeScript types matching homecore-api JSON shapes
    components/
      AppShell.ts      # <hc-app-shell> — header + nav + content slot
      StateCard.ts     # <hc-state-card> — single entity state card
    icons/
      lucide.ts        # Tree-shaken Lucide icon wrapper
    styles/
      tokens.css       # 16 CSS custom properties (--hc-*)
      base.css         # Typography reset, page shell, nav layout
    __tests__/         # Vitest unit tests
  index.html           # Shell loading src/main.ts
  vite.config.ts
  tsconfig.json
  vitest.config.ts

Design system

Colors, typography, and components mirror the cognitum-v0 dashboard (http://cognitum-v0:9000/). Dark-only; no light-mode. Key tokens:

  • --hc-primary #19d4e5 — teal (active nav, focus ring, CTA borders)
  • --hc-accent #26d867 — green (success, secondary CTA)
  • --hc-bg #0b0e13 — near-black navy page root
  • Font: Outfit (display) + JetBrains Mono (mono)
  • Icons: Lucide (SVG, stroke: currentColor, no icon font)

See docs/design/HOMECORE-FRONTEND-design-recon.md for the full recon.

Architecture notes

  • Components are standard Lit LitElement custom elements — compatible with any HTML page and with Home Assistant's Lit-based frontend.
  • The REST client uses fetch; the WS client uses WebSocket. Both accept a bearer token and are fully typed against the Rust homecore-api JSON shapes.
  • WASM: vite.config.ts enables .wasm asset import. Hook up via dynamic import('/path/to/module.wasm?init') when WASM bindings are ready.