Update AI coding instructions to match current frontend APIs
Fix outdated references in .github/copilot-instructions.md (symlinked as
CLAUDE.md and AGENTS.md): showAlertDialog import path, ESLint flat config,
ha-dialog width presets, ha-alert slots/props, ha-button variant/appearance
guidance, Web Awesome direction, and the querySelector pitfall.
* Simplify and improve landingpage
* add core download progress
* reduce to 2 seconds
* Use round to display full integer as progress percentage
* Use find to get the job object
* Don't show progress label when progress is at 0
Before download starts, progress is at 0. At this point we may trying
to reach a server (and error out), so we aren't really in downloading
phase just yet. Simply treat 0 as "not started" and hide the progress
label until we have a real progress value.
---------
Co-authored-by: Stefan Agner <stefan@agner.ch>
Filter out updates that are already installing before calling the
update.install service, and disable a group's Update all button when
every update in it is already in progress.
* Create shared related context for quick bar and add automation element
* Provider mixin and dont pass sets when context can be used
* Direct use consume
* Move context provider into class and use in context mixin
* Cleanup
* Match signatures with lazy context provider
* Fix order of operations
* Typing
* Fix popstate on dialog launch/close
* Typing improvement
Drop dependencies that are no longer referenced anywhere in the codebase:
- @material/mwc-base: declared directly but never imported; still pulled
in transitively by the other @material/mwc-* packages, so the explicit
declaration was redundant.
- @types/mocha: the test runner is Vitest (test files import describe/it/
expect from "vitest"); no Mocha globals or namespace are used.
- @types/webspeechapi: no Web Speech API usage in the codebase, and the
modern TypeScript lib.dom already ships these definitions.
- @types/babel__plugin-transform-runtime: the plugin is only referenced by
string name in the Babel config, never imported as a typed module, so the
type stub is unused.
Co-authored-by: MindFreeze <noreply@anthropic.com>
Consume internationalizationContext for locale in ha-selector-date,
ha-selector-datetime, ha-selector-time, ha-selector-button-toggle, and
ha-selector-select (partial: hass kept where passed to children).
* Migrate hui-badge-edit-mode and hui-card-edit-mode to localize context
Replace this.hass.localize with @consumeLocalize(); remove hass prop and
caller .hass bindings from Lovelace edit-mode overlays.
* Migrate hui-view-badges to localize context
* Migrate avatar badges off hass property (Group K)
Consume connectionContext for hassUrl and statesContext plus
consumeEntityState for the user badge person entity picture.
Remove .hass bindings from callers.
* Migrate ha-person-badge and ha-user-badge to connection context
Use connectionContext for hassUrl; ha-user-badge also consumes entity state
for person picture lookup.
* Fix ha-user-badge updates and restore hass binding
Use PropertyValues.has() to detect _states changes. Restore .hass bindings on
ha-user-picker callers and ha-generic-picker, which still require hass.
* Fix type error and restore hass on person subpage
- Type willUpdate with PropertyValues so changedProps.has("_states")
type-checks (matches the other states-context consumers); fixes the
failing lint:types CI check
- Restore .hass on hass-tabs-subpage in ha-config-person, which still
requires hass and was crashing the person config page
- Drop now-dead .hass bindings on ha-user-badge in ha-user-picker
- Only rescan for the person entity when the user changes or the tracked
entity is missing, instead of on every state update
Order the energy fields as discharge then charge to match the power
fields in the energy panel battery settings dialog.
Co-authored-by: MindFreeze <noreply@anthropic.com>
* Migrate ha-relative-time and ha-absolute-time off hass property
Consume localize, locale, and config via Lit context so time primitives
only rerender when i18n or config slices change, and drop obsolete .hass
bindings from callers.
* Consume full i18n context in time display components
Use internationalizationContext directly for both localize and locale in
ha-relative-time and ha-absolute-time, avoiding mixed consumption patterns.
* Render echarts tooltips with Lit templates
Replace raw HTML string interpolation in echarts tooltip formatters with Lit templates so user-controlled fields (entity friendly_name, device names, node labels) are auto-escaped instead of relying on per-string filterXSS. ha-chart-base now wraps any function tooltip.formatter into a stable per-formatter container and handles Lit TemplateResult / nothing / null returns; the public HaECOption type lets charts express Lit-returning formatters without per-callsite casts.
* Simplify
* Refactor _getSeries
* Small fix
* Fix merge mistake
* Marker component and wrapper test
Resending the confirmation email reused the registration code path, so
the flash on the login screen said "Account created!" even though no
new account was created. Pass a message key to _verificationEmailSent
so resend can show "Verification email sent." instead.
_handleResendVerifyEmail also never set _requestInProgress, so the
resend button (and the start-trial button, which share that flag) were
not disabled while a resend was in flight and could be clicked
repeatedly. Set the flag at the start and clear it on terminal errors;
_verificationEmailSent already clears it on success.
Co-authored-by: Claude <noreply@anthropic.com>
* Update dependency echarts to v6.1.0
* Fix axis-proxy patch for echarts 6.1.0 AxisProxy internals
ECharts 6.1.0 uses hostedBy() and _window.value instead of direct model
comparison and _valueWindow. Update the boundaryFilter patch and contract
tests so CI passes with the dependency bump.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Fix stale wake word display after wake word change in satellite wizard
The config re-fetch was fire-and-forgotten, so the step transition to
STEP.WAKEWORD raced ahead with stale assistConfiguration. Awaiting the
fetch ensures the fresh active_wake_words are in place before rendering.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add-on iframe: delegate microphone + camera Permissions Policy
The add-on ingress iframe in ``ha-panel-app.ts`` ships without an
``allow=`` attribute, so the Permissions Policy default of *deny*
applies for ``microphone`` and ``camera`` on the cross-origin
iframe. An add-on that wants to call ``getUserMedia`` — voice
notes, dictation, video calls, photo capture — fails silently with
``NotAllowedError`` before the browser even surfaces the permission
prompt.
The failure is most visible on the Android Companion app, where
there's no "open in a new tab" escape: the user presses the mic
button and nothing happens, no toast, no logs.
Delegate ``microphone``, ``camera``, and ``clipboard-write`` to the
add-on iframe. Add-ons are first-party software the user explicitly
installs, and Chrome's runtime permission prompt still gates the
hardware access — the ``allow=`` attribute just lets the iframe
*request* the prompt instead of being blocked at the policy layer.
``clipboard-write`` is bundled in because the next-most-frequent
silent-fail in add-on land is ``navigator.clipboard.writeText`` for
"copy link" / "copy code" affordances, blocked by the same
mechanism.
* Sandbox add-on ingress iframe without allow-same-origin
Split IFRAME_SANDBOX into two constants: IFRAME_SANDBOX (without
allow-same-origin) for add-on ingress iframes that need origin
isolation, and IFRAME_SANDBOX_SAME_ORIGIN for external iframes
that need same-origin access.
This ensures add-on iframes can't inherit camera/microphone
permissions already granted to the Home Assistant origin, and
prevents same-origin iframes from removing their own sandbox.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Setup add to area page
* Remove 3 buttons, move to single add to button next to add a picture button
* Use normal size buttons
* Restructure layout with picture
* Remove div when both conditions are met
* Use mixin
* Fix imports
Some environments (e.g. Android WebView/emulator) return a UTC offset like
"+00:00" from Intl.DateTimeFormat().resolvedOptions().timeZone instead of an
IANA zone name. Submitting that to saveCoreConfig fails with "invalid time
zone", leaving users stuck on the country step.
Detect this by checking the resolved value against the google-timezones-json
list used by ha-timezone-picker, and surface the picker on the core-config
step when no IANA zone could be detected from the browser or the location
detect API.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add to for devices page
* Rename and reuse original dialogs, drop popover
* Reduce
* Lazy context
* Direct access lazy context
* Default width
* Merge automations and scripts cards
* Format
* Loading state
* Rename key
* Tooltip and move key
* Copy icons used in more info
* Sort
* Merge scenes into one "Related" card
* Adjust
* Fix no labs
* Use same wording for device actions
* Cleanup
* Comments for removal
* Cleanup
* Type check
* Template literals
* Add padding
* Rework weather forecast card features
* Add show labels option
* Some fixes
* Fixes and cleaning
* Update palette
* Add reference floor to precipitation bar scale
Light drizzle no longer fills the bar when it's also the period max.
Observed values above the floor still drive the scale (storms read full).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Feedbacks
* Use weather unit
* Force celcius for gradient
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Allow previews to use a domain
* Allow previews to specify preview entity domain
* Allow repair_flow to use previews
* Pull recent changes
* Add domain to previews for TemplatePreview
* first rough draft of Z-Wave credential mangement
* separate user and credentials, error handling, dialog tweaks
* align with upstream API changes, improve error handling
* align more with Matter, use lock entity for services
* remove get_credential_status service
* address review feedback, clarify user types
* user_index -> user_id, fix some pending states
* address review feedback
* clean up unused code, strongly type credential types
* Clear -> Delete, drop icons
* Simplify flow to 1 PIN/Password credential per user
* cleanup, comments, etc.
* address review feedback
* do not show existing credential data
* fix lint errors after branch update
* ignore non-enterable credential types when editing user
* refactor: use separate storage and display filters in backup page
Apply the two-lists pattern in backup page: _filters (@state, display only) +
_storageFilters (@storage sessionStorage, state: false). _storageFilters
is only updated when not in URL mode (_fromUrl flag). Init moved from
connectedCallback to willUpdate(!hasUpdated).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use separate storage and display filters in scenes page
Apply the two-lists pattern in scenes page: _filters (@state, display only) +
_storageFilters (@storage sessionStorage, state: false, with
serializer/deserializer). _storageFilters is only updated when not in
URL mode (_fromUrl flag). Init moved from firstUpdated to
willUpdate(!hasUpdated). The existing updated() hook already calls
_applyFilters() when _entityReg changes, covering the reconnect case.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use separate storage and display filters in automations page
Apply the two-lists pattern in automations page: _filters (@state, display only) +
_storageFilters (@storage sessionStorage, state: false, with
serializer/deserializer). _storageFilters is only updated when not in
URL mode (_fromUrl flag). _fromUrl is set before the await in the async
_filterBlueprint() to prevent any user change during the fetch from
persisting. Init moved from firstUpdated to willUpdate(!hasUpdated).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use separate storage and display filters in scripts page
Apply the two-lists pattern in scripts page: _filters (@state, display only) +
_storageFilters (@storage sessionStorage, state: false, with
serializer/deserializer). _storageFilters is only updated when not in
URL mode (_fromUrl flag). _fromUrl is set before the await in the async
_filterBlueprint() to prevent any user change during the fetch from
persisting. Init moved from firstUpdated to willUpdate(!hasUpdated).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: don't mix URL filters with storage filters in automation,script and scene pages
When URL params are present, _filters starts empty so URL methods build
from scratch. Previously, _filters was pre-populated from _storageFilters
and the spread in _filterLabel()/_filterBlueprint() would merge storage
filters into the URL-injected ones.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update src/panels/config/backup/ha-config-backup-backups.ts
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
* fix(helpers): clear URL-injected filters on leaving helpers dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(helpers): restore previous filters after URL-injected navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use separate storage and display filters
Apply the same pattern as devices and entities pages: split _filters into
a display-only @state and a _storageFilters persisted to sessionStorage.
_storageFilters is only updated when not in URL mode (_fromUrl flag), so
URL-injected filters never persist to storage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: reapply filters when helper entities load on reconnect
_applyFilters() was never called when _filters was restored from
sessionStorage, leaving _filteredHelperEntityIds undefined and the
table appearing empty. Call it whenever _helperEntities updates and
active filters are present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Setup default add to actions
* Setup default add to actions
* Move event into external only
* Split into sections
* Padding
* Refactor to single type and adapt app interface to frontend style and vice versa
* Refactor to single type and adapt app interface to frontend style and vice versa
* Condition action and navigation actions
* Open dialogs with trigger, condition, action dialogs
* Add divider before add to
* Move add to to the top
* Action
* Triggers and conditions labs feature check
* Suggestion
* Keep query state
* Change to automation_trigger
* Use typed key instead of finding with icon
* Apply suggestions from code review
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
* Finish
* Reset state
* Fix navigation resets
* stated
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
* Split
* Add import, sort imports
---------
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
The arrow-right icon next to the alert icon was decorative noise.
With automation comments (#52090) adding yet another icon, simplify
to a single mdiAlertCircleCheck indicator.
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Update dependency @tsparticles/engine to v4
* Bump @tsparticles/preset-links to v4 to match engine
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Show both power buttons for assumed-state media players when unknown
Media players with assumed state report an unknown state when their
actual power state can't be determined. In that case the entity row and
more info should still expose both turn on and turn off controls so the
user can operate the device.
https://claude.ai/code/session_01JyZojNPCCY65HmRVQaASkG
* Treat media player unknown state like off instead of unavailable
The media player controls lumped the "unknown" state in with
"unavailable" and hid all controls. An unknown state is closer to "off":
the device exists but its power state isn't reported, which is common
for assumed-state players. Only "unavailable" should hide the controls,
so an unknown-state player now shows the turn on button (and both power
buttons when it has an assumed state) in the entity row and more info.
https://claude.ai/code/session_01JyZojNPCCY65HmRVQaASkG
* Adjust comments and variable placement for media player state check
https://claude.ai/code/session_01JyZojNPCCY65HmRVQaASkG
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(entities): clear URL-injected filters on leaving entities dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(entities): restore previous filters after URL-injected navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: use separate storage and display filters
Apply the same pattern as devices page: split _filters into a display-only
@state and a _storageFilters persisted to sessionStorage. _storageFilters
is only updated when not in URL mode (_fromUrl flag), so URL-injected
filters never persist to storage.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(devices): clear URL-injected filters on leaving devices dashboard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(devices): restore previous filters after URL-injected navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(devices): use separate storage and display filters
Replace the disconnect-callback approach with two distinct filter states:
- _storageFilters: persisted to sessionStorage, updated only when not in
URL mode (manual filter changes and clear)
- _filters: display-only state, initialized from _storageFilters on first
render, overwritten by URL params without touching storage
_storageFilters is frozen while _fromUrl is true, preserving the user's
previous manual filters for the next normal visit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update dependency eslint-plugin-lit to v2.3.1
* Fix lit/prefer-query-decorators violations
eslint-plugin-lit 2.3.0 introduced this rule. Replace querySelector
calls with @query/@queryAll decorators where the selector is static.
Use per-line disables for dynamic selectors that can't use decorators.
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
Replaces the per-render scrollHeight read from #52012 with a
ResizeObserver started in firstUpdated, writing --tip-height directly to
the host style. Removes the need for a manual refresh when the viewport
crosses a wrap threshold, drops the unreachable isNaN check, and lets
the @query decorator stand in for the editor-tip id.
fix(filter): prevent badge count from incrementing on panel re-open
Integrations and domains filter panels use lazy rendering: the list is
destroyed on close and recreated on open. On recreation, MWC fires a
`selected` event with a diff for each pre-selected item, which the
diff-based handler interpreted as a new user selection, appending
duplicates to `this.value` on every expansion.
Switch both handlers to the full-set approach (`SelectedDetail<Set<number>>`)
already used by labels, states, and voice-assistants, rebuilding the value
from the complete index set. Add the `preserved` pattern to retain
selections hidden by the search filter. Also add `_value` to the `_domains`
memoize signature to ensure cache invalidation when the selection changes.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix demo mock recorder data end times
The mock recorder was setting the start and end time for each of the samples to be the same value, causing the solar graph in the energy dashboard to render incorrectly.
Fix the recorder to set the end time of each sample to the start time of the next.
Fix empty padding to right of ha-switch
When the label slot for the ha-switch is empty, the initial margin is still present which causes an odd misalignment on the switches in e,g, the entities card.
To fix this, if the label slot is empty, hide the label to remove the unwanted margin.
* feat(lovelace): add mute button to media player volume buttons card feature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add show_mute_button config option to volume buttons feature
* feat: disable show_mute_button option when entity does not support mute
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Apply suggestions from code review
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Migrate ha-drawer to Web Awesome drawer
* Make CI happy
* Implement swipe gesture support for ha-drawer and fix RTL support
* Fix CI
* Fix CI
* Readd border
* Fix sidebar
* Layout fix
* Fix sluggish scroll on mobile
* Fix CI
* Add transition
* add more options for history-graph-card
* add more options for history-graph-card
* Apply suggestion from @MindFreeze
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Add context to statistics panel
* Lazy context
* Cleanup
* Types
* Use api context, use registries, update helpers to only need api
* Infer type
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Remove —
* Format
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Generate third party license file during production build
* Add license check CI step
* Address review comments: use license-checker-rseidelsohn, add version validation for LICENSE_OVERRIDES
* Fix license-checker-rseidelsohn import (CJS module, use require)
* Add link to single integration entry warning
* Refactor single config entry warning: move function to dedicated file and update imports
* Implement single config entry warning dialog and update related functions
* Apply suggestions from code review
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Position statistics chart bars at centre of time range
When displaying 5minute or hourly data periods, position each bar at the midpoint of its start/end time. This mimics the behaviour in the various energy cards for consistency.
* Move limit comparison into pushData
Results in clearer function argument usage.
* Add time range for statistics-chart bar tooltip
When using hour/5minute periods the bars are recentred. Update the tooltips to show time range they cover.
* Omit time from tooltip for bars with periods of day or longer
Don't clutter the tooltip with unnecessary times of 0:00 when using day/month/year timescales on bar charts, just show the date range.
For week/month/year, we now also include the range of dates of the bar rather than just the start date.
* Migrate dialog-expose-entity to new dialog and migrate everything thats needed for this.
* Load virtualizer after dialog show is ready
* Use entities context instead of registries in ha-state-icon
* fix types
* Update src/panels/config/voice-assistants/dialog-expose-entity.ts
---------
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
* Fixes tile card misalignment (#25745)
Removes an unnecessary vertical padding on the tile card content that causes a misalignment within the Android Companion app. This padding isn't needed because the contents are already vertically aligned with flexbox anyway.
* Added a min-height to tile container
As requested in the review, added a minimal height to the content of the
tile container to support non-section layouts.
Fix demo mock recorder data end times
The mock recorder was setting the start and end time for each of the samples to be the same value, causing the solar graph in the energy dashboard to render incorrectly.
Fix the recorder to set the end time of each sample to the start time of the next.
Fix empty padding to right of ha-switch
When the label slot for the ha-switch is empty, the initial margin is still present which causes an odd misalignment on the switches in e,g, the entities card.
To fix this, if the label slot is empty, hide the label to remove the unwanted margin.
* Move buttons to standard footers
* Fix negative margin, use space tokens
* Space tokens with tweaks
* Hide form if empty
* Standardise padding
* Only show skip if no devices are assigned
* Use ref instead of queries
* nothing
* Token
* Typing
* Don't round bar chart end time for hourly periods
If we do this, it causes the last hour of the energy dashboard bar charts to be cut off. This went unnoticed previously because they were placed at times of xx:00, while now they are times of xx:30.
* Round to 30minute for hourly bars rather than leaving unrounded
This better matches the axes with line charts by cutting off padding into the next day, whilst leaving mid-point bars visible.
* Update tests to account for new behaviour
Fix type exception in chart _updateSankeyRoam
When there is no data for some series in the sankey chart, then the series map can contain null entries. This raised an exception as the _updateSankeyRoam tried to access the 'type' property on a null value.
Add an explicit check for null. Using != not !== to also filter undefined in case that ever shows up.
* add a possibility to customize color
* add a possibility to customize color
* add GraphEntityConfig
* add basic color support
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Give less importance to the custom tag and tag id in the UI
* Make an expandable version prefill with a tagID
* Improve Edit tag dialog to be more usable
* Apply manually prettier
* Apply suggestion from @MindFreeze
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* add new ha-list options
* Refactor ha-list components to use ha-list-selectable and ha-list-item-option
* fix types in gallery
* fix filter-floor-areas
* Review
* Fix list aria-label
* make a "description" expandable
* add "about" label for devtools->templates
* Update src/translations/en.json
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* expandedWillChange -> expandedChanged
* Add type annotation to _expandedChanged method
* Add import for HASSDomEvent type
* prettier
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Add descriptions to Jinja2 tags, filters, expressions, tests and variables
All standard Jinja2 tags, filters, and expression completions now carry
info and detail strings so the autocomplete info popover shows meaningful
documentation when users browse them — not just HA-specific functions.
* Add keyboard shortcut tip to the template developer tool
A ha-tip below the editor card now shows users that Ctrl+Space triggers
autocomplete, Ctrl+F opens the search panel, and F11 toggles fullscreen,
making the editor's built-in features more discoverable.
* Add hover tooltips for Jinja2 functions, filters and expressions
Hovering over a function, filter, tag, test, or variable name inside a
Jinja2 template shows a tooltip with its signature and description.
Non-tag completions also get a help-circle icon linking to the
corresponding Home Assistant template-functions documentation page.
The tooltip is rendered as a custom Lit element (ha-code-editor-jinja-hover)
that takes the Completion object and an optional docUrl as properties.
The tooltip source (haJinjaHoverSource) is wired into ha-code-editor
via CodeMirror's hoverTooltip extension. The documentationUrl() helper
is used so the link points to the correct subdomain (www / rc / next)
based on the running HA version.
* Add hover tooltips for Jinja2 hover + arg value tooltips for entity/device/area
Wire haJinjaHoverSource into ha-code-editor via CodeMirror hoverTooltip.
Two types of hover are now shown in jinja2/yaml mode:
- Hovering a function/filter/tag/expression name shows its signature,
description, and a doc-link icon (non-tags only).
- Hovering a string-literal argument of a known HA Jinja function (e.g.
states(), device_name(), area_entities()) shows the friendly name,
current state, device, and area for entity_id arguments; the device
name and area for device_id arguments; and the area name for area_id
arguments. The same applies to states["entity_id"] subscripts.
The arg-value tooltip reuses CompletionItem / ha-code-editor-completion-items
(the same component used for autocomplete info popovers) via a new
ha-code-editor-jinja-arg-hover element. HA registry data is passed from
ha-code-editor via a HassArgHoverContext interface to keep jinja_ha_completions.ts
free of HomeAssistant type imports.
* only add tip for autocomplete
* review
* Expose Z-Wave exclusion instructions when removing device
* text tweaks
* Apply suggestion from @MindFreeze
* Apply suggestions from code review
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* bring back comment
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Ally: Add aria labels to ha-icon-button and hui-root
* use aria-hidden
* Add hidden content for label to satisfy ally review
* Make fix in button instead (probably should update upstream)
* Aria label (pending wa update)
* Add descriptions to Jinja2 tags, filters, expressions, tests and variables
All standard Jinja2 tags, filters, and expression completions now carry
info and detail strings so the autocomplete info popover shows meaningful
documentation when users browse them — not just HA-specific functions.
* Add keyboard shortcut tip to the template developer tool
A ha-tip below the editor card now shows users that Ctrl+Space triggers
autocomplete, Ctrl+F opens the search panel, and F11 toggles fullscreen,
making the editor's built-in features more discoverable.
* Add hover tooltips for Jinja2 functions, filters and expressions
Hovering over a function, filter, tag, test, or variable name inside a
Jinja2 template shows a tooltip with its signature and description.
Non-tag completions also get a help-circle icon linking to the
corresponding Home Assistant template-functions documentation page.
The tooltip is rendered as a custom Lit element (ha-code-editor-jinja-hover)
that takes the Completion object and an optional docUrl as properties.
The tooltip source (haJinjaHoverSource) is wired into ha-code-editor
via CodeMirror's hoverTooltip extension. The documentationUrl() helper
is used so the link points to the correct subdomain (www / rc / next)
based on the running HA version.
* Add hover tooltips for Jinja2 hover + arg value tooltips for entity/device/area
Wire haJinjaHoverSource into ha-code-editor via CodeMirror hoverTooltip.
Two types of hover are now shown in jinja2/yaml mode:
- Hovering a function/filter/tag/expression name shows its signature,
description, and a doc-link icon (non-tags only).
- Hovering a string-literal argument of a known HA Jinja function (e.g.
states(), device_name(), area_entities()) shows the friendly name,
current state, device, and area for entity_id arguments; the device
name and area for device_id arguments; and the area name for area_id
arguments. The same applies to states["entity_id"] subscripts.
The arg-value tooltip reuses CompletionItem / ha-code-editor-completion-items
(the same component used for autocomplete info popovers) via a new
ha-code-editor-jinja-arg-hover element. HA registry data is passed from
ha-code-editor via a HassArgHoverContext interface to keep jinja_ha_completions.ts
free of HomeAssistant type imports.
* only add tip for autocomplete
* review
* Expose Z-Wave exclusion instructions when removing device
* text tweaks
* Apply suggestion from @MindFreeze
* Apply suggestions from code review
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* bring back comment
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Only show events output when there are any, types and margin
* Refactor to use pagination
* Fix
* Simplify, remove pinning and auto-follow, stay on event 1 and allow the user to move around manually
* Show info why only 30 events are keps
* Increase bufffer limit to 100, add explainer and tip when rolls over
* Update disclaimer
* Use buffer position and total instead of event id + total in counter
* Use fixed height and constrain editor
* Cleanup
* Cleanup
* Fix narrow layouts
The old heading "Device created" was a past-tense status message that didn't
communicate what the user needs to do next. The dialog contains a name field
and an area picker, so "Name and assign" better reflects the user's actual
task at this step.
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* Check for unknown value every render if value is unknown
* fix race in pickers that add items from the picker
* fix: use value imports for LitElement, html, nothing from lit
* feat: Split legend interaction (click vs label) with icons and hover effects
* Address review feedback on chart legend split
- Rename `externalHiddenState` to `clickLabelForMoreInfo` and the event
`chart-legend-click` to `legend-label-click` (the `chart-` prefix is
reserved for echarts-proxy events).
- Use proper translation keys
`ui.components.history_charts.{toggle_visibility,show_more_info}`
instead of `ui.common.*` which don't exist.
- Drop the redundant tooltip on the label when it would duplicate the
icon's "Toggle visibility" tooltip.
- Resolve the legend dataset id back to a real `entity_id` before
opening more-info: strip known climate-attribute suffixes for history
charts (`-current_temperature`, `-target_temperature*`, `-heating`/
`-cooling`/`-drying`/`-fan`), and skip `isExternalStatistic` ids for
statistics charts. Only fire `hass-more-info` if `hass.states[id]`
resolves.
* Address followup review feedback on chart legend
- Restore stat-type suffix stripping in statistics chart. When the chart
has a single entity, ha-chart-base falls back to raw series ids
(`${statistic_id}-${type}`) for the legend, so clicking
"sensor.foo (max)" otherwise tries to open `sensor.foo-max`.
- Cover humidifier multi-attribute datasets in the entity-id resolver
alongside climate / water_heater (`-current_humidity`,
`-target_humidity`, `-humidifying`, `-on`; `-drying` is already
contributed by CLIMATE_MODE_CONFIGS). Rename the constant to
ENTITY_DATASET_SUFFIXES to reflect the broader scope.
- Convert the two legend click targets to `<button type="button">` so
Tab navigation, Enter/Space activation, and screen-reader semantics
work. Add `aria-pressed` to the visibility toggle and a
`:focus-visible` outline. Read the dataset id from `data-id` instead
of `parentElement.id` so the handlers don't depend on DOM nesting.
- Scope the label hover underline to `.label-clickable` so charts that
don't opt into more-info (network, sankey, sunburst, energy) keep the
legacy non-underlined toggle behavior. Render the "Show more info"
tooltip only when the click will actually fire.
- Drop the redundant physical `margin-right: 0` on the legend toggle;
`margin-inline-end: 0` alone preserves the click-area extension on
the start side in RTL.
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Modified the chart legend for climate temperature data sets to display the temperature value, not the overall entity state (previously hvac_mode).
* Use the helper computeAttributeValueDisplay in src/common/entity/compute_attribute_display.ts to format the temperature attribute values.
Co-authored-by: Copilot <copilot@github.com>
* Update src/components/chart/state-history-chart-line.ts
---------
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* fix: rebuild ha-panel-custom on reconnect after suspendWhenHidden
Why:
HA's PartialPanelResolver._onHidden() starts a 5-minute timer when a tab
is backgrounded. When it fires, non-iframe / non-app custom panels
(component_name="custom" without embed_iframe) are removed from the DOM,
which triggers ha-panel-custom.disconnectedCallback() -> _cleanupPanel().
That nulls _setProperties and destroys the child custom-panel element.
When the user returns, _onVisible() re-appends the same <ha-panel-custom>
element. ReactiveElement's base connectedCallback schedules an update,
but update() only calls _createPanel(this.panel) when
changedProps.has("panel") && !deepEqual(oldPanel, this.panel) -- the
panel reference hasn't changed, so nothing happens. _setProperties is
also undefined, so the property-forwarding branch exits early too.
Result: <ha-panel-custom> is present in the DOM but empty -- the user
sees a blank panel until they hard-reload.
Add a connectedCallback() override that rebuilds when the element was
previously cleaned up. Three guards keep it scoped to the recovery path:
- !this._setProperties: sentinel for "_cleanupPanel ran".
_setProperties is set inside _createPanel's success paths and only
nulled in _cleanupPanel.
- !this.hasChildNodes(): defends against the async window inside
loadCustomPanel(config).then(...) for non-iframe panels, where a
rapid detach->attach cycle could otherwise call _createPanel twice
and append duplicate elements.
- this.panel: skips first-mount, when the router hasn't assigned a
panel yet. The existing update() path handles initial _createPanel
via the changedProps.has("panel") branch.
Mirrors the existing disconnectedCallback override for symmetry.
10 lines + comment, no other file changes.
Affects every non-iframe sidebar custom panel in the HACS ecosystem
(Alarmo, Browser Mod, Homematic(IP) Local, MeshCore, others -- ~60k
combined HA-analytics installs). Reopens dormant home-assistant/frontend
issue #14510 (filed 2022-12-02, stale-bot closed without a fix).
Tests:
- yarn build succeeds locally; the affected chunk is captured for the
pre-PR local-test on a real HA host.
- Manual repro on user's HA host (10.10.21.221) with the MeshCore
custom panel: baseline (no patch) reproduces the blank-panel symptom
after a 6-minute backgrounded tab. Patched chunk: panel rebuilds
within ~2 seconds of returning. Exemption paths (iframe panel, app
panel, custom panel with embed_iframe=true) verified to remain
unaffected. Original chunk restored after testing.
- yarn lint and yarn test pass before PR submission (run before
Phase 9).
* chore: trigger CLA recheck after author-email link
* increase an active "enlarge" area
Added a class to make the title span enlargeable.
* increase an active "enlarge" area
* increase an active "enlarge" area
* Add entity context to media browser player picker
Show area and device as a secondary line in both the active player pill
and the player picker dropdown, so users can identify speakers when
multiple players share similar names.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update src/panels/media-browser/ha-bar-media-player.ts
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
Remove the unmaintained eslint-config-airbnb-base dependency (last
updated Nov 2021, no flat config support) along with its FlatCompat
shim infrastructure.
Replace with js.configs.recommended as the base config and explicitly
cherry-pick ~40 high-value safety and style rules from airbnb-base
that aren't already covered by other configs.
Remove 27 rule disables that only existed to suppress airbnb opinions,
and 5 dead TypeScript rule disables for rules no longer in the config.
Fix 4 real bugs caught by the newly added no-constant-binary-expression
rule where template literals were always truthy, making fallback values
unreachable.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
If the app config contains a schema field like this one:
```
privileges:
- "list(ALTER|CREATE|...|UPDATE)?"
```
it was rendered incorrectly as a drop-down where only one item can be
selected - but this is wrong because of the preceding `-` denoting it
should be a list containing the listed values. Supervisor translated
this to an entry of type `select` with `multiple: true`. The `multiple`
flag wasn't passed along, with the flag set the field renders as
expected.
Fixes#51533
* Fix history/sensor cards stuck loading after backend restart
- Add { resubscribe: false } to history subscriptions to prevent
corrupt HistoryStream state on auto-resubscription
- Add connection-status handlers to re-subscribe on reconnect
- Add sentinel pattern to prevent re-entrant async subscriptions
- Add shouldUpdate/updated retry when components become available
- Clear sensor device classes cache on WS error
- Clear _error on reconnect so cards can retry
- Add .catch() on unsubscribe to handle dead subscriptions
* Fix type annotation for callWS in getSensorNumericDeviceClasses
* Address review: type connection-status handlers, add reconnect to history panel
- Use HASSDomEvent<ConnectionStatus> instead of (ev as CustomEvent).detail
for proper type safety on all connection-status handlers
- Add connection-status handler to ha-panel-history so it re-subscribes
after backend restart (addresses concern about resubscribe: false)
* Address review: sentinel pattern, reconnect handling, stale data reset
- Add sentinel pattern to ha-more-info-history, ha-panel-history,
hui-history-graph-card to prevent re-entrant subscription races
- Refactor hui-trend-graph-card-feature from SubscribeMixin to manual
subscription management with connection-status reconnect support
- Reset stale history/statistics data on reconnect in
hui-history-graph-card and hui-map-card before re-subscribing
- Wrap fetchStatistics and getSensorNumericDeviceClasses calls in
ha-panel-history with try/catch to handle errors gracefully
- Chain .catch directly on subscribeHistoryStatesTimeWindow in
hui-trend-graph-card-feature to avoid detached-promise race condition
* Centralize history stream reconnect handling in data layer
Move the reconnect logic from every consumer into `subscribeHistoryStream`
in data/history.ts. The helper listens to the connection's `ready` event
itself, and on reconnect creates a fresh `HistoryStream` and rebuilds
params (so `start_time` for the time-window variant is re-anchored to
"now"). `resubscribe: false` stays as an internal implementation detail.
Removes the duplicated `_handleConnectionStatus` boilerplate and
`connection-status` window listeners from all six history consumers.
* Render subscription errors and make _error reactive
`_error` was declared as a plain string field in hui-graph-header-footer
and ha-more-info-history (non-reactive) and typed as Error/string while
being assigned the WS error object. hui-trend-graph-card-feature had it
reactive but never rendered it.
Align all three with the hui-history-graph-card pattern: reactive
`{ code, message }` and a user-visible error branch in render(). Without
this, a failed subscription would leave the component stuck on a spinner
forever.
---------
Co-authored-by: Petar Petrov <MindFreeze@users.noreply.github.com>
* Fix base time inputs reportValidity() function
The queryAll selector returns a NodeList not not an array. Need to spread it to an array before we can use every().
* Validate the date range picker time inputs
Enable auto validation to get the nice red underline on invalid values, and then check validity before accepting the input.
* Fix automatic 24hr value conversion in AM/PM format
When using AM/PM, entering a 24 hour value will automatically convert the first time. For example 15 will become 3. However if you then enter 15 again it will stay as 15 and not update.
To fix this, make sure we trigger an update of the input field once the current update cycle is complete.
* Validate time inputs on save not value update
In the value changed callback, the update 24->12hr input correction will not have been updated and therefore they will report invalid.
Add `white-space: pre-line` to the event description style so that
newlines in the calendar event description are rendered correctly
instead of being collapsed into a single line.
2026-03-26 17:07:32 +01:00
1119 changed files with 44771 additions and 20142 deletions
- ESLint config (flat config) extends TypeScript strict, Lit, Web Components, Accessibility (lit-a11y), and import-x
- Prettier with ES5 trailing commas enforced
- No console statements (`no-console: "error"`) - use proper logging
- Import organization: No unused imports, consistent type imports
@@ -160,7 +160,7 @@ try {
- Defined in `src/resources/theme/core.globals.ts`
- Common values: `--ha-space-2` (8px), `--ha-space-4` (16px), `--ha-space-8` (32px)
- **Mobile-first responsive**: Design for mobile, enhance for desktop
- **Follow Material Design**: Use Material Web Components where appropriate
- **Prefer `ha-*` components**: Build on the Home Assistant component library (many now wrap Web Awesome components); avoid new use of legacy Material Web Components (`mwc-*`), which are being phased out
- **Support RTL**: Ensure all layouts work in RTL languages
- **Primary action**: `appearance="filled"` for emphasis (or the default appearance for a lighter look)
- **Secondary action**: `appearance="plain"` for cancel/dismiss actions
- **Destructive actions**: `variant="danger"` for delete/remove operations (the generic confirmation dialog uses `variant="danger"` for its confirm button — see `src/dialogs/generic/dialog-box.ts`)
- Always place primary action in `slot="primaryAction"` and secondary in `slot="secondaryAction"` within `ha-dialog-footer`
- Don't use`querySelector` - Use refs or component properties
- Don't manually query the DOM with`querySelector` - use the `@query`/`@queryAll` decorators or component properties
- Don't manipulate DOM directly - Let Lit handle rendering
- Don't use global styles - Scope styles to components
- Don't block the main thread - Use web workers for heavy computation
@@ -540,35 +548,24 @@ When creating a pull request, you **must** use the PR template located at `.gith
#### Translation Considerations
- **Add translation keys**: All user-facing text must be translatable
- **Use placeholders**: Support dynamic content in translations
All user-facing text must be translatable — see the **Internationalization** section (under Common Patterns) for the `localize` API and placeholder usage. From a copy perspective:
- **Keep context**: Provide enough context for translators
("Are you sure you want to delete this automation?");
```
- **Avoid concatenation**: Prefer full localized strings with placeholders over stitching translated fragments together
### Common Review Issues (From PR Analysis)
Recurring, easy-to-miss problems surfaced in real PR reviews. These complement the standards above rather than repeating them — items already covered earlier (loading states, error handling, mobile layout, theming, import hygiene) are intentionally not duplicated here.
#### User Experience and Accessibility
- **Form validation**: Always provide proper field labels and validation feedback
- **Form accessibility**: Prevent password managers from incorrectly identifying fields
- **Loading states**: Show clear progress indicators during async operations
- **Error handling**: Display meaningful error messages when operations fail
- **Mobile responsiveness**: Ensure components work well on small screens
- **Hit targets**: Make clickable areas large enough for touch interaction
- **Visual feedback**: Provide clear indication of interactive states
- **Visual feedback**: Provide clear indication of interactive states (hover, active, focus)
#### Dialog and Modal Patterns
- **Dialog width constraints**: Respect minimum and maximum width requirements
- **Interview progress**: Show clear progress for multi-step operations
- **State persistence**: Handle dialog state properly during background operations
- **Cancel behavior**: Ensure cancel/close buttons work consistently
Final pre-submission checklist. Linting and formatting areenforced by tooling, so this focuses on what tools can't catch rather than restating every rule above.
@@ -13,7 +13,7 @@ Our dialogs are based on the latest version of Material Design. Please note that
- Dialogs have a max width of 560px. Alert and confirmation dialogs have a fixed width of 320px. If you need more width, consider a dedicated page instead.
- The close X-icon is on the top left, on all screen sizes. Except for alert and confirmation dialogs, they only have buttons and no X-icon. This is different compared to the Material guidelines.
- Dialogs can't be closed with ESC or clicked outside of the dialog when there is a form that the user needs to fill out. Instead it will animate "no" by a little shake.
- Dialogs can't be closed with ESC or clicked outside of the dialog when there is a form that the user **has made changes to**. Instead it will animate "no" by a little shake.
- Extra icon buttons are on the top right, for example help, settings and expand dialog. More than 2 icon buttons, they will be in an overflow menu.
- The submit button is grouped with a cancel button at the bottom right, on all screen sizes. Fullscreen mobile dialogs have them sticky at the bottom.
- Keep the labels short, for example `Save`, `Delete`, `Enable`.
@@ -399,12 +408,12 @@ export class StateHistoryCharts extends LitElement {
.entry-container{
width: 100%;
overflow: visible;
}
.entry-container.line{
flex: 1;
padding-top: 8px;
overflow: hidden;
}
.entry-container:hover{
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.