Compare commits

...

2 Commits

Author SHA1 Message Date
Aidan Timson b574aaa084 Type feature event handlers (#53461)
* Type feature event handlers

* Address event handler review feedback

Co-authored-by: timmo001 <28114703+timmo001@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-08-04 08:28:13 +03:00
dependabot[bot] c1dca9b377 Bump postcss from 8.5.19 to 8.5.25 (#53465)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.19 to 8.5.25.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.19...8.5.25)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.25
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 08:25:14 +03:00
17 changed files with 108 additions and 61 deletions
@@ -6,14 +6,20 @@ import type { ByWeekday, Options, WeekdayStr } from "rrule";
import { RRule, Weekday } from "rrule";
import { formatDate, formatTime } from "../../common/datetime/calc_date";
import { firstWeekdayIndex } from "../../common/datetime/first_weekday";
import type {
HASSDomCurrentTargetEvent,
HASSDomTargetEvent,
} from "../../common/dom/fire_event";
import type { LocalizeKeys } from "../../common/translations/localize";
import "../../components/chips/ha-chip-set";
import "../../components/chips/ha-filter-chip";
import type { HaFilterChip } from "../../components/chips/ha-filter-chip";
import "../../components/ha-date-input";
import "../../components/ha-select";
import type { HaSelectSelectEvent } from "../../components/ha-select";
import "../../components/input/ha-input";
import type { HomeAssistant } from "../../types";
import type { HaInput } from "../../components/input/ha-input";
import type { HomeAssistant, ValueChangedEvent } from "../../types";
import type {
MonthlyRepeatItem,
RepeatEnd,
@@ -321,8 +327,8 @@ export class RecurrenceRuleEditor extends LitElement {
`;
}
private _onIntervalChange(e: Event) {
this._interval = (e.target! as any).value;
private _onIntervalChange(e: HASSDomTargetEvent<HaInput>) {
this._interval = Number(e.target.value);
}
private _onRepeatSelected(e: HaSelectSelectEvent<RepeatFrequency>) {
@@ -351,9 +357,12 @@ export class RecurrenceRuleEditor extends LitElement {
this._monthday = selectedItem.bymonthday;
}
private _onWeekdayToggle(e: MouseEvent) {
const target = e.currentTarget as any;
const value = target.value as WeekdayStr;
private _onWeekdayToggle(
e: MouseEvent &
HASSDomCurrentTargetEvent<HaFilterChip & { value: WeekdayStr }>
) {
const target = e.currentTarget;
const value = target.value;
if (this._weekday.has(value)) {
this._weekday.delete(value);
} else {
@@ -385,11 +394,11 @@ export class RecurrenceRuleEditor extends LitElement {
e.stopPropagation();
}
private _onCountChange(e: Event) {
this._count = (e.target! as any).value;
private _onCountChange(e: HASSDomTargetEvent<HaInput>) {
this._count = Number(e.target.value);
}
private _onUntilChange(e: CustomEvent) {
private _onUntilChange(e: ValueChangedEvent<string>) {
e.stopPropagation();
this._untilDay = new Date(
new TZDate(e.detail.value + "T00:00:00", this.timezone).getTime()
@@ -436,7 +445,7 @@ export class RecurrenceRuleEditor extends LitElement {
);
// rrule.js can't compute some UNTIL variations so we compute that ourself. Must be
// in the same format as dtstart.
let newUntilValue;
let newUntilValue: string;
if (this.allDay) {
// For all-day events, only use the date part
newUntilValue = until.toISOString().split("T")[0].replace(/-/g, "");
+1 -1
View File
@@ -147,7 +147,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
handleAction(this, this.hass!, this._config!, ev.detail.action!);
}
private _handleIconAction(ev: CustomEvent) {
private _handleIconAction(ev: ActionHandlerEvent) {
ev.stopPropagation();
const config = {
entity: this._config!.entity,
+12 -4
View File
@@ -4,6 +4,10 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { STATES_OFF } from "../../../common/const";
import type {
HASSDomCurrentTargetEvent,
HASSDomTargetEvent,
} from "../../../common/dom/fire_event";
import { computeDomain } from "../../../common/entity/compute_domain";
import parseAspectRatio from "../../../common/util/parse-aspect-ratio";
import "../../../components/ha-camera-stream";
@@ -378,9 +382,11 @@ export class HuiImage extends LitElement {
this._loadState = LoadState.Error;
}
private async _onImageLoad(ev: Event): Promise<void> {
private async _onImageLoad(
ev: HASSDomTargetEvent<HTMLImageElement>
): Promise<void> {
this._loadState = LoadState.Loaded;
const imgEl = ev.target as HTMLImageElement;
const imgEl = ev.target;
if (this._ratio && this._ratio.w > 0 && this._ratio.h > 0) {
this._loadedImageSrc = imgEl.src;
}
@@ -388,9 +394,11 @@ export class HuiImage extends LitElement {
this._lastImageHeight = imgEl.offsetHeight;
}
private async _onVideoLoad(ev: Event): Promise<void> {
private async _onVideoLoad(
ev: HASSDomCurrentTargetEvent<HaCameraStream>
): Promise<void> {
this._loadState = LoadState.Loaded;
const videoEl = ev.currentTarget as HaCameraStream;
const videoEl = ev.currentTarget;
await this.updateComplete;
this._lastImageHeight = videoEl.offsetHeight;
}
@@ -15,7 +15,7 @@ import type { LocalizeFunc } from "../../../../../common/translations/localize";
import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../../../../types";
import type { ImageElementConfig } from "../../../elements/types";
import type { LovelacePictureElementEditor } from "../../../types";
import { ACTION_RELATED_CONTEXT } from "../../../components/hui-action-editor";
@@ -159,7 +159,7 @@ export class HuiImageElementEditor
: {}),
}));
private _valueChanged(ev: CustomEvent): void {
private _valueChanged(ev: ValueChangedEvent<ImageElementConfig>): void {
fireEvent(this, "config-changed", { config: ev.detail.value });
}
@@ -20,7 +20,7 @@ import "../../../../components/ha-card";
import "../../../../components/ha-form/ha-form";
import "../../../../components/ha-icon";
import "../../../../components/ha-switch";
import type { HomeAssistant } from "../../../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../../../types";
import {
PREVIEW_CLICK_CALLBACK,
type PictureElementsCardConfig,
@@ -29,6 +29,7 @@ import type { LovelaceCardEditor } from "../../types";
import "../hui-sub-element-editor";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import type { EditDetailElementEvent, SubElementEditorConfig } from "../types";
import type { UIConfigChangedEvent } from "../hui-element-editor";
import { configElementStyle } from "./config-elements-style";
import "../hui-picture-elements-card-row-editor";
import type { LovelaceElementConfig } from "../../elements/types";
@@ -228,7 +229,7 @@ export class HuiPictureElementsCardEditor
: {}),
}));
private _formChanged(ev: CustomEvent): void {
private _formChanged(ev: ValueChangedEvent<PictureElementsCardConfig>): void {
ev.stopPropagation();
if (!this._config || !this.hass) {
return;
@@ -261,7 +262,9 @@ export class HuiPictureElementsCardEditor
}
}
private _handleSubElementChanged(ev: CustomEvent): void {
private _handleSubElementChanged(
ev: UIConfigChangedEvent<LovelaceElementConfig>
): void {
ev.stopPropagation();
if (!this._config || !this.hass) {
return;
@@ -12,7 +12,12 @@ import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { until } from "lit/directives/until";
import { fireEvent, type HASSDomEvent } from "../../common/dom/fire_event";
import { fireEvent } from "../../common/dom/fire_event";
import type {
HASSDomCurrentTargetEvent,
HASSDomEvent,
HASSDomTargetEvent,
} from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain";
import { computeEntityPickerDisplay } from "../../common/entity/compute_entity_name_display";
import { supportsFeature } from "../../common/entity/supports-feature";
@@ -582,14 +587,15 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
this._volumeSlider.value = this._volumeValue;
}
private _handleControlClick(e: MouseEvent): void {
const action = (e.currentTarget! as HTMLElement).getAttribute("action")!;
private _handleControlClick(
e: MouseEvent & HASSDomCurrentTargetEvent<HTMLElement>
): void {
const action = e.currentTarget.getAttribute("action")!;
if (!this._browserPlayer) {
handleMediaControlClick(
this.hass!,
this._stateObj!,
(e.currentTarget as HTMLElement).getAttribute("action")!
e.currentTarget.getAttribute("action")!
);
return;
}
@@ -600,12 +606,12 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) {
}
}
private _handleMediaSeekChanged(e: Event): void {
private _handleMediaSeekChanged(e: HASSDomTargetEvent<HaSlider>): void {
if (this.entityId === BROWSER_PLAYER || !this._stateObj) {
return;
}
const newValue = (e.target as HaSlider).value;
const newValue = e.target.value;
this.hass.callService("media_player", "media_seek", {
entity_id: this._stateObj.entity_id,
seek_position: newValue,
@@ -16,7 +16,7 @@ import type {
} from "../../data/data_entry_flow";
import { DirtyStateProviderMixin } from "../../mixins/dirty-state-provider-mixin";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../types";
let instance = 0;
@@ -229,7 +229,7 @@ class HaMfaModuleSetupFlow extends DirtyStateProviderMixin<
});
}
private _stepDataChanged(ev: CustomEvent) {
private _stepDataChanged(ev: ValueChangedEvent<Record<string, unknown>>) {
this._stepData = ev.detail.value;
this._updateDirtyState(this._stepData);
}
@@ -2,6 +2,7 @@ import type { TemplateResult } from "lit";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomTargetEvent } from "../../common/dom/fire_event";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
import "../../components/item/ha-row-item";
@@ -33,8 +34,8 @@ class HaEnableShortcutsRow extends LitElement {
`;
}
private async _checkedChanged(ev: Event) {
const enabled = (ev.target as HaSwitch).checked;
private async _checkedChanged(ev: HASSDomTargetEvent<HaSwitch>) {
const enabled = ev.target.checked;
if (enabled === this.hass.enableShortcuts) {
return;
}
+3 -2
View File
@@ -2,6 +2,7 @@ import type { TemplateResult } from "lit";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomTargetEvent } from "../../common/dom/fire_event";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
import "../../components/item/ha-row-item";
@@ -31,8 +32,8 @@ class HaForcedNarrowRow extends LitElement {
`;
}
private async _checkedChanged(ev: Event) {
const newValue = (ev.target as HaSwitch).checked;
private async _checkedChanged(ev: HASSDomTargetEvent<HaSwitch>) {
const newValue = ev.target.checked;
if (newValue === (this.hass.dockedSidebar === "always_hidden")) {
return;
}
@@ -3,6 +3,7 @@ import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomCurrentTargetEvent } from "../../common/dom/fire_event";
import { copyToClipboard } from "../../common/util/copy-clipboard";
import { withViewTransition } from "../../common/util/view-transition";
import "../../components/ha-alert";
@@ -11,6 +12,7 @@ import "../../components/ha-dialog";
import "../../components/ha-dialog-footer";
import "../../components/ha-svg-icon";
import "../../components/input/ha-input";
import type { HaInput } from "../../components/input/ha-input";
import { DirtyStateProviderMixin } from "../../mixins/dirty-state-provider-mixin";
import type { HomeAssistant } from "../../types";
import { showToast } from "../../util/toast";
@@ -190,8 +192,10 @@ export class HaLongLivedAccessTokenDialog extends DirtyStateProviderMixin<string
`;
}
private _nameChanged(ev: Event) {
this._name = (ev.currentTarget as HTMLInputElement).value;
private _nameChanged(
ev: HASSDomCurrentTargetEvent<Omit<HaInput, "value"> & { value: string }>
) {
this._name = ev.currentTarget.value;
this._errorMessage = undefined;
this._updateDirtyState(this._name);
}
@@ -5,9 +5,11 @@ import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
import { relativeTime } from "../../common/datetime/relative_time";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomCurrentTargetEvent } from "../../common/dom/fire_event";
import "../../components/ha-button";
import "../../components/ha-card";
import "../../components/ha-icon-button";
import type { HaIconButton } from "../../components/ha-icon-button";
import "../../components/ha-settings-row";
import type { RefreshToken } from "../../data/refresh_token";
import {
@@ -110,8 +112,10 @@ class HaLongLivedTokens extends LitElement {
});
}
private async _deleteToken(ev: Event): Promise<void> {
const token = (ev.currentTarget as any).token;
private async _deleteToken(
ev: HASSDomCurrentTargetEvent<HaIconButton & { token: RefreshToken }>
): Promise<void> {
const token = ev.currentTarget.token;
if (
!(await showConfirmationDialog(this, {
title: this.hass.localize(
+4 -1
View File
@@ -16,6 +16,7 @@ import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-button";
import "../../components/ha-card";
import "../../components/ha-dropdown";
import type { HaDropdownSelectEvent } from "../../components/ha-dropdown";
import "../../components/ha-dropdown-item";
import "../../components/ha-icon-button";
import "../../components/item/ha-list-item-base";
@@ -221,7 +222,9 @@ class HaRefreshTokens extends LitElement {
}
private _handleDropdownSelect(
ev: CustomEvent<{ item: { action: string; token: RefreshToken } }>
ev: HaDropdownSelectEvent<string> & {
detail: { item: { action: string; token: RefreshToken } };
}
) {
if (ev.detail.item.action === "toggle_expiration") {
this._toggleTokenExpiration(ev.detail.item.token);
+9 -6
View File
@@ -1,7 +1,10 @@
import type { TemplateResult } from "lit";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import type { HASSDomEvent } from "../../common/dom/fire_event";
import type {
HASSDomEvent,
HASSDomTargetEvent,
} from "../../common/dom/fire_event";
import { fireEvent } from "../../common/dom/fire_event";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
@@ -15,9 +18,9 @@ declare global {
}
// for add event listener
interface HTMLElementEventMap {
"hass-suspend-when-hidden": HASSDomEvent<{
suspend: HomeAssistant["suspendWhenHidden"];
}>;
"hass-suspend-when-hidden": HASSDomEvent<
HASSDomEvents["hass-suspend-when-hidden"]
>;
}
}
@@ -43,8 +46,8 @@ class HaSetSuspendRow extends LitElement {
`;
}
private async _checkedChanged(ev: Event) {
const suspend = (ev.target as HaSwitch).checked;
private async _checkedChanged(ev: HASSDomTargetEvent<HaSwitch>) {
const suspend = ev.target.checked;
if (suspend === this.hass.suspendWhenHidden) {
return;
}
+3 -2
View File
@@ -2,6 +2,7 @@ import type { TemplateResult } from "lit";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomTargetEvent } from "../../common/dom/fire_event";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
import "../../components/item/ha-row-item";
@@ -30,8 +31,8 @@ class HaSetVibrateRow extends LitElement {
`;
}
private async _checkedChanged(ev: Event) {
const vibrate = (ev.target as HaSwitch).checked;
private async _checkedChanged(ev: HASSDomTargetEvent<HaSwitch>) {
const vibrate = ev.target.checked;
if (vibrate === this.hass.vibrate) {
return;
}
+11 -8
View File
@@ -6,16 +6,19 @@ import memoizeOne from "memoize-one";
import { formatShortDateTimeWithConditionalYear } from "../../common/datetime/format_date_time";
import { resolveTimeZone } from "../../common/datetime/resolve-time-zone";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomTargetEvent } from "../../common/dom/fire_event";
import { computeStateName } from "../../common/entity/compute_state_name";
import { supportsFeature } from "../../common/entity/supports-feature";
import { supportsMarkdownHelper } from "../../common/translations/markdown_support";
import "../../components/ha-alert";
import "../../components/ha-button";
import "../../components/ha-checkbox";
import type { HaCheckbox } from "../../components/ha-checkbox";
import "../../components/ha-date-input";
import "../../components/ha-dialog";
import "../../components/ha-dialog-footer";
import "../../components/ha-textarea";
import type { HaTextArea } from "../../components/ha-textarea";
import "../../components/ha-time-input";
import "../../components/input/ha-input";
import type { HaInput } from "../../components/input/ha-input";
@@ -30,7 +33,7 @@ import {
import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box";
import { DirtyStateProviderMixin } from "../../mixins/dirty-state-provider-mixin";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../types";
import type { TodoItemEditDialogParams } from "./show-dialog-todo-item-editor";
interface TodoItemFormState {
@@ -166,7 +169,7 @@ class DialogTodoItemEditor extends DirtyStateProviderMixin<TodoItemFormState>()(
<div class="flex">
<ha-checkbox
.checked=${this._checked}
@change=${this._checkedCanged}
@change=${this._checkedChanged}
.disabled=${isCreate || !canUpdate}
></ha-checkbox>
<ha-input
@@ -338,22 +341,22 @@ class DialogTodoItemEditor extends DirtyStateProviderMixin<TodoItemFormState>()(
return new Date(tzDate.getTime());
}
private _checkedCanged(ev) {
private _checkedChanged(ev: HASSDomTargetEvent<HaCheckbox>) {
this._checked = ev.target.checked;
this._updateDirtyState(this._currentState());
}
private _handleSummaryChanged(ev: InputEvent) {
this._summary = (ev.target as HaInput).value ?? "";
private _handleSummaryChanged(ev: InputEvent & HASSDomTargetEvent<HaInput>) {
this._summary = ev.target.value ?? "";
this._updateDirtyState(this._currentState());
}
private _handleDescriptionChanged(ev) {
private _handleDescriptionChanged(ev: HASSDomTargetEvent<HaTextArea>) {
this._description = ev.target.value;
this._updateDirtyState(this._currentState());
}
private _dueDateChanged(ev: CustomEvent) {
private _dueDateChanged(ev: ValueChangedEvent<string | undefined>) {
if (!ev.detail.value) {
this._due = undefined;
this._updateDirtyState(this._currentState());
@@ -364,7 +367,7 @@ class DialogTodoItemEditor extends DirtyStateProviderMixin<TodoItemFormState>()(
this._updateDirtyState(this._currentState());
}
private _dueTimeChanged(ev: CustomEvent) {
private _dueTimeChanged(ev: ValueChangedEvent<string>) {
this._hasTime = true;
this._due = this._parseDate(
`${this._formatDate(this._due || new Date())}T${ev.detail.value}`
+3 -2
View File
@@ -15,6 +15,7 @@ import memoizeOne from "memoize-one";
import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { storage } from "../../common/decorators/storage";
import { fireEvent } from "../../common/dom/fire_event";
import type { HASSDomCurrentTargetEvent } from "../../common/dom/fire_event";
import { computeStateName } from "../../common/entity/compute_state_name";
import { supportsFeature } from "../../common/entity/supports-feature";
import { navigate } from "../../common/navigate";
@@ -396,8 +397,8 @@ class PanelTodo extends LitElement {
}
}
private _setEntityId(ev: Event) {
const item = ev.currentTarget as HaDropdownItem;
private _setEntityId(ev: HASSDomCurrentTargetEvent<HaDropdownItem>) {
const item = ev.currentTarget;
this._entityId = item.value;
}
+5 -5
View File
@@ -11942,7 +11942,7 @@ __metadata:
languageName: node
linkType: hard
"nanoid@npm:^3.3.12":
"nanoid@npm:^3.3.16":
version: 3.3.16
resolution: "nanoid@npm:3.3.16"
bin:
@@ -12832,13 +12832,13 @@ __metadata:
linkType: hard
"postcss@npm:^8.5.16":
version: 8.5.19
resolution: "postcss@npm:8.5.19"
version: 8.5.25
resolution: "postcss@npm:8.5.25"
dependencies:
nanoid: "npm:^3.3.12"
nanoid: "npm:^3.3.16"
picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1"
checksum: 10/f51162887cd683afc02fa6c1f06b6485ebc18c62eec7dc2841c8fe0a0c4b53b9a834cc26aa1a233e87f0e3a10179db916a276464c0ee1d00354d1670ebc32953
checksum: 10/68aaeb314a1b2407e11e926acc0462b01b3e911d3d9e755d06adc5b2ececdefe8432dc3c3c93eacc07138952e17997d4674529061b8e3a338a7ac4c1accfdf98
languageName: node
linkType: hard