Skip to content

fix: entity chip list dropped the picked entity on newer HA frontends - #137

Draft
WJDDesigns wants to merge 95 commits into
mainfrom
feat/esm-multi-file-phase1
Draft

fix: entity chip list dropped the picked entity on newer HA frontends#137
WJDDesigns wants to merge 95 commits into
mainfrom
feat/esm-multi-file-phase1

Conversation

@WJDDesigns

Copy link
Copy Markdown
Owner

Summary

Two bugs in the shared entity chip list (ultra-chip-list, used by every module with an "add entities" list) surfaced on current Home Assistant frontends while building the Train module for #136:

  1. Picker rendered as an empty box. Newer HA calls entityFilter with the state object instead of an entity-id string; our filter called .split() on it and threw inside ha-entity-picker's render (TypeError: e.split is not a function). Both ultra-chip-list and uc-entity-picker now accept either shape.
  2. Picking an entity added it and then immediately removed it. ha-entity-picker's own value-changed is composed, so it escaped the chip list's shadow root and reached the module's listener on <ultra-chip-list>, which expects a string[]. The leaked string (or empty value on picker reset) overwrote the list right after our array event. The picker's event is now stopped inside the component, and renderChipListField ignores any non-array payload.

Verification

  • Reproduced the leak with a temporary jsdom test (host received [['sensor.a','sensor.b'], 'sensor.b', …] before, exactly [['sensor.a','sensor.b']] after); test removed before commit.
  • tsc --noEmit, eslint (0 errors), vitest: 1371 passed; the 10 surface-goldens failures pre-exist on this branch.
Open in Web Open in Cursor 

The template colour parser kept the strict var(--x) pattern the colour
picker had, so a template that rendered var(--x, #000) was discarded and
replaced with the default colour.
The template colour parser kept the strict var(--x) pattern the colour
picker had, so a template that rendered var(--x, #000) was discarded and
replaced with the default colour.
…as with Ultra Cards

Registers ll-strategy-dashboard-ultra-dashboard (+ an ultra-dashboard-area
view strategy) and a window.customStrategies entry so it appears under
Community dashboards in HA 2026.5+. generate() builds a Home page (clock/
weather header, room tiles per floor, people, alerts, batteries, updates)
and one sections page per area or floor, every card a custom:ultra-card
composed from the modules' createDefault() with Free modules only. Four
styles (classic/soft/glass/bold), an ha-form config editor, sync registry
fast path with WS fallback. Generator and editor live in the lazy
uc-strategy chunk; the entry only carries the element shim.
…w Dashboard dialog

Home Assistant's dialog only shows images for its built-in strategies today;
the entry carries images: { light, dark } in the built-in shape (inline SVG so
it ships inside ultra-card.js) and is paired with an upstream frontend patch
that reads it.
… create flow

- configRequired = true so Add dashboard shows the style/areas editor before
  the name step, as the tile description promises
- rooms are composed from the module that suits each thing: light scenes and
  sliders, thermostat card and 24h chart, appliance cards, status rows for
  security, tap grids for switches and scenes, level bars for air quality
- light groups hide their members; WLED strips show one light, not segments
- per-room accent colours (except Bold), style-specific slider and bar looks
- config/diagnostic, hidden and mobile_app entities never reach a room page;
  unavailable controls fold into More instead of dead buttons
- thin areas with nothing to control no longer get their own page
- area_summary prefers a live temperature/humidity sensor and hides
  'unavailable' readings
…ary, editor, import/export and apply-to-dashboard
…s, trust scanner, submit dialog, Hub catalog + My submissions
…rayscale token; picker hover only on pointer devices
A palette that pins --primary-text-color (Hillary's navy) but not the
surfaces modules paint with (--secondary-background-color, input fills,
--text-primary-color) produced navy on charcoal under dark HA. The theme
service now derives those companions from literal palette colours:
stepped nested surfaces, on-primary text by WCAG contrast, disabled /
secondary / divider tints, MDC surface + ink. Explicit values win and
var() palettes derive nothing. Adds an on_primary palette key
(Monochrome uses it: paper on ink), an AA audit test over all built-in
palettes (darkened Hillary's taupe to 5.1:1), and pins light ink on the
UniFi dark/glass rack, which previously inherited the page colour.
Pine #1F3B2E for primary and ink, gold #D4AF6C for accent and piping,
linen #EAE2D6 cards, taupe #8B7355 hairlines, navy-tinted shadow. Brand
taupe is 3.5:1 on linen so secondary text uses a deepened taupe (5.1:1)
to keep the AA audit green.
Dark cocoa hide cards, antler-cream text (11.8:1), tan secondary text
(6.1:1), saddle-brown primary with derived white on top (5.8:1), antler
velvet accent and hairlines, rustic slab serif. Passes the AA audit.
…me CSS

Metallic: brushed-steel plate (diagonal sheen + vertical grain gradients),
machined bevel via inset shadows, gunmetal primary, blued-steel accent,
metallic module surfaces, recessed nested panels.

Beach: sand card with inline SVG waves lapping the bottom edge, a rope
hairline under the top edge, sand-grain texture, a sun glow, deep-water
text, ocean primary, coral accent, rounded sans.

The sanitiser (TS and PHP mirror) now accepts url() when the argument is
a data:image/* URI. SVG-as-image cannot run script or fetch, and the
decoded payload is still refused if it contains <script>, on*= handlers,
foreignObject, external hrefs or url(). Any other url() stays forbidden.
CSS cap raised to 40k to leave room for artwork; the trust scanner lists
inline artwork as a finding. svgDataUrl() helper encodes SVG for CSS.
Midnight-purple card with an inline SVG striped sunset sun in the corner,
a cyan perspective grid running off the bottom edge, a faint scanline
overlay, pink haze and a neon rim. Hot-pink primary with derived dark
text (5.6:1), cyan accent, neon-glow controls, blueprint UniFi rack.

Sanitiser now permits url(#id) paint-server references inside inline
SVG (gradients, clip paths) while still refusing any external url().
Classic duplicated HA Native and Soft was a weaker Material. Cards and
dashboards saved with those ids alias (classic → HA Native, soft →
material) in both the theme service and the dashboard strategy, and a
user theme installed under a legacy id still wins. Ultra Dashboard now
defaults to material.

Material is now MD3 by the spec: elevated card = HA surface + 5% primary
surface tint (tonal elevation level 1) with the level-1 key/ambient
shadow, no outline, 12dp medium corner; controls are full pills (radius
20), icon buttons circular, nested surfaces at the level-3 tint, Roboto
with body-medium tracking. Everything is in HA variables so it follows
the active HA colour scheme.
Nobody shipped with them, so no alias table in the theme service or the
dashboard strategy. Unknown ids fall through to the global default / HA
Native as before.
Each Ultra Card now receives a stable --uc-card-hue (FNV-1a of its first
row id, so editing modules keeps the colour) whenever a theme applies.
Gummy uses it to give every card its own candy flavour: bright jelly body,
white top highlight, saturated pool at the foot, sugar-glass rim and a
coloured drop shadow. Ink is one dark plum that clears AA on every hue
(worst 5.6:1 on blue); liquorice primary with white on top. Hue-following
companions (secondary bg, input fills) are set in the theme CSS.
A walnut plank whose grain is generated by SVG fractal-noise filters
stretched along the board (dark figure, pale early-wood streaks, fine pore
texture) over the base colour, plus a routed edge, top light and warm
shadow. Cream ink (7.1:1), dark-walnut primary, brass accent, embossed
controls, nested surfaces carved as recesses.
The default card config ships id 'row1', so seeding from the first row id
gave every default-derived card the same Gummy flavour.
Hard-coded px border radii inside module styles (rows, tiles, chips,
tracks, inner images: 823 sites across 90 modules) now read
calc(Npx * var(--uc-radius-scale, 1)). The theme service sets
--uc-radius-scale = card radius / 12 (the default the modules were
designed against), clamped to 0..1.75, so a square theme squares every
nested element and a round one rounds them, while HA Native (no variable)
renders byte-for-byte as before. Pills (>=28px), percentages, user Design
tab values and already-variable radii are untouched.
Module-side radii now read var(--uc-r-N, Npx). Inside a themed card the base CSS
defines each --uc-r-N as min(N * --uc-radius-scale, --uc-radius-inner), where
--uc-radius-inner is the largest radius a first-level nested surface may have:
radius - padding when that fits, otherwise held between half the card radius and
4px inside it, and 0 for square themes. Fixes tiles authored near the default card
radius (UniFi camera cards) landing at or above the outer radius under round themes.
The unifi sub-directory styles, missed by the first sweep, are included. Outside a
themed card the variables are unset and the Npx fallback renders as before.
Gummy: inline SVG shine marks (curved specular swoosh, hot spot, fleck) top-left,
a floor reflection bottom-right, subsurface glow that deepens toward the rim, a
refraction line along the bottom edge and a coloured drop shadow; nested surfaces
are smaller gummies with their own shine.

Metallic: procedural anisotropic brushing (three noise layers stretched along the
plate), a banded specular sheen, a chamfered edge with light catch and shadow, and
a slotted screw head in each corner; text is etched, nested surfaces are milled
recesses. Shadow token cap raised to 600 chars for layered materials.
cursoragent and others added 30 commits September 8, 2026 00:18
Wire the next solid wrappers onto --uc-pane-* with data-uc-role=pane so
Theme Engine glass surfaces apply. Calendar views announce the role while
shared CSS consumes pane tokens; extend the coverage gate for this batch.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
…nar, sports

Theme Engine glass surfaces now cover map popups, external-card placeholders,
scroll-row arrows, lunar theme backgrounds, sports scorecards, vehicle card
defaults, and climate mode popup buttons. Extend the pane-role coverage gate.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
…liance

Wire remaining live card-background surfaces onto --uc-pane-* tokens and
announce data-uc-role=pane on screensaver footers. Extend the coverage gate
for this residual batch.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
Propagate --uc-pane-bg through residual card-background paints across entity
and layout modules, convert separator title chips, and extend the pane-role
coverage gate. Editor-only chrome (gauge/nav/slider/virtual-pet/bar) left as-is.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
Adopt --uc-pane-bg + data-uc-role=pane on the last editor/live holdouts
(bar, gauge, navigation, slider-control, virtual-pet) and settings chrome.
Harden the coverage gate so no non-carve-out module can paint raw
card-background without a pane fallback.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
… bar module (white with a dark shadow) instead of the card text colour, which vanished on tinted themes like Terminal
…rc apex no room); Vapor cards draw a sun, a moon or a bare sky and show or skip the grid from their seeds so neighbours stop repeating. Plugin 1.3.39 bundles the new JSON
…s and sunk tracks; Vapor drops the moon and shows the sun on fewer cards at any size and height; Beach loses the shell. Bar value text follows --uc-bar-text so light-card themes get dark text with a light halo (module default unchanged). Plugin 1.3.40
… so type on them keeps AA; secondary ink darkened to match. Plugin 1.3.41
…g in a lighter alloy raised off it, spun controls on top. Plugin 1.3.42
…he controls' conic sweep (dark plate, lighter panes) and the diagonal brushing is gone. Plugin 1.3.43
…nd become a faint glaze so the spun plate shows through instead of flat grey slabs. Plugin 1.3.44
…ared field helpers, consistent labels/resets/placeholders, arrow-key stepping keeps units, HA selects show Default/None; bridge includes text_shadow_* and transform_* so saved values show when reopening a module; new unit tests

Co-authored-by: Cursor <cursoragent@cursor.com>
…lti-file-phase1

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…blished after assets are attached and verified

scripts/release.js used to run 'gh release create' right after pushing the
tag, ~2 minutes before the Release workflow uploaded ultra-card.js and the
uc-*.js chunks. HACS (content_in_root: false) saw a release with no
ultra-card.js asset, fell back to the repo root, and installed the committed
entry file with none of its chunks: no editor, modules stuck loading, and a
permanent 'Ultra Card was updated, reload' toast. 3.10.0-beta8 shipped like
that (the workflow then failed a stale test, so the assets never came) and
beta9 exposed the same window to anyone who updated in those two minutes.

- release.yml: softprops creates a DRAFT with fail_on_unmatched_files, a
  step verifies ultra-card.js and at least one uc-*.js are attached, then
  'gh release edit --draft=false' publishes. HACS never sees drafts.
- release.js: no longer creates the release; pushes the tag, watches the
  workflow run and reports the published asset count.
- docs/bundle-strategy.md: record the failure mode next to the HACS facts.

Co-authored-by: Cursor <cursoragent@cursor.com>
Button containers previously forced height:auto, breaking the percentage
height chain inside Stack Overlay (#132). Respect design sizes, propagate
height through the preview wrapper, and mirror image-module stack fill CSS
so full-tile tap targets work with layer/design height 100%.

Co-authored-by: Cursor <cursoragent@cursor.com>
ha-entity-picker's own value-changed event is composed, so it escaped the
chip list's shadow root and hit the module's array listener with a string
(or an empty value on reset), wiping the entity that had just been added.
Stop the picker's event inside ultra-chip-list and make the base helper
ignore any non-array payload.

Also accept the state object that newer HA passes to entityFilter (older
frontends pass the entity id); calling .split on it threw inside the
picker's render and left the field blank.

Co-authored-by: Wayne Drescher <WJDDesigns@users.noreply.github.com>
Restores the boiler/train work that was stashed when the cloud agent was
started, on top of the chip-list fix (1305122) so picked departure
sensors are no longer wiped by the picker's composed value-changed event.

Co-authored-by: Cursor <cursoragent@cursor.com>
The train is a front view, so the track now runs away beneath it: two
rails converging downward over sleepers that roll away, drawn inside each
train's SVG instead of the side-view dashed stubs between icons. The
undercarriage is a head-on bogie with a wheel tread at each side rather
than two skateboard-like pods.

LED board: windows, door seam and lamp rings are carved out in the board
colour with dim lit panes, headlights stay on, the dot pitch is coarser and
the glow is tight and in the train's own colour, so the shape no longer
collapses into a blob. Dotted text is denser and a point larger; the
countdown ellipsizes instead of running into the times. Modern trains get
a soft drop shadow. Preview regenerated.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rails start at the wheel treads and fan out toward the bottom; sleepers spread
apart and roll toward the viewer. Done with a rotateX plane under a perspective
container so the foreshortening is real rather than drawn. LED board masks the
track into its dot grid.

Co-authored-by: Cursor <cursoragent@cursor.com>
The train is heading toward the viewer, so the ground ahead of it runs up under
the wheels. The frame between the two wheel treads is gone; just the treads show
under the bumper.

Co-authored-by: Cursor <cursoragent@cursor.com>
3c8f106 stopped forcing height:auto on .button-module-container so a
Button can fill a Stack Overlay layer; the ten button goldens still
carried the old declaration. No other change in the snapshots.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants