1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-02 00:27:49 +01:00

Extract shared light toggle heading badges helper

Move the dual turn_on/turn_off badge pattern into a shared
computeLightToggleHeadingBadges helper used by both area-view-strategy
and light-view-strategy.

https://claude.ai/code/session_01QYArBydHUEkFt5K2SwVZfY
This commit is contained in:
Claude
2026-03-19 10:10:18 +00:00
parent 857bf7b1cf
commit 6e205cd681
3 changed files with 88 additions and 91 deletions

View File

@@ -17,7 +17,7 @@ import {
SMALL_SCREEN_CONDITION,
} from "../../lovelace/strategies/helpers/screen-conditions";
import type { ToggleGroupCardConfig } from "../../lovelace/cards/types";
import type { ButtonHeadingBadgeConfig } from "../../lovelace/heading-badges/types";
import { computeLightToggleHeadingBadges } from "../../lovelace/strategies/helpers/light-toggle-badges";
export interface LightViewStrategyConfig {
type: "light";
@@ -51,15 +51,21 @@ const processAreasForLight = (
}
if (areaCards.length > 0) {
// Visibility condition: any light is on
const anyOnCondition = {
condition: "or" as const,
conditions: areaLights.map((entityId) => ({
condition: "state" as const,
entity: entityId,
state: "on",
})),
};
const lightToggleBadges = computeLightToggleHeadingBadges(
areaLights,
{ area_id: area.area_id },
{
icon: "mdi:power",
turnOnText: hass.localize(
"ui.panel.lovelace.strategy.light.off"
),
turnOffText: hass.localize(
"ui.panel.lovelace.strategy.light.on"
),
turnOffColor: "orange",
extraVisibility: [SMALL_SCREEN_CONDITION],
}
);
cards.push({
heading_style: "subtitle",
@@ -71,42 +77,7 @@ const processAreasForLight = (
navigation_path: `/home/areas-${area.area_id}`,
}
: undefined,
badges: [
// Toggle buttons for mobile
{
type: "button",
icon: "mdi:power",
text: hass.localize("ui.panel.lovelace.strategy.light.off"),
tap_action: {
action: "perform-action",
perform_action: "light.turn_on",
target: {
area_id: area.area_id,
},
},
visibility: [
SMALL_SCREEN_CONDITION,
{
condition: "not",
conditions: [anyOnCondition],
},
],
} satisfies ButtonHeadingBadgeConfig,
{
type: "button",
icon: "mdi:power",
color: "orange",
text: hass.localize("ui.panel.lovelace.strategy.light.on"),
tap_action: {
action: "perform-action",
perform_action: "light.turn_off",
target: {
area_id: area.area_id,
},
},
visibility: [SMALL_SCREEN_CONDITION, anyOnCondition],
} satisfies ButtonHeadingBadgeConfig,
] satisfies LovelaceCardConfig[],
badges: lightToggleBadges satisfies LovelaceCardConfig[],
});
// Toggle group card for desktop

View File

@@ -8,7 +8,7 @@ import type { LovelaceSectionRawConfig } from "../../../../data/lovelace/config/
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types";
import type { HeadingCardConfig } from "../../cards/types";
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
import { computeLightToggleHeadingBadges } from "../helpers/light-toggle-badges";
import {
AREA_STRATEGY_GROUP_ICONS,
computeAreaTileCardConfig,
@@ -97,50 +97,12 @@ export class AreaViewStrategy extends ReactiveElement {
hass
);
const lightBadges: ButtonHeadingBadgeConfig[] = [];
if (lightControlEntities.light.length > 0) {
const anyOnCondition = {
condition: "or" as const,
conditions: lightControlEntities.light.map((entityId) => ({
condition: "state" as const,
entity: entityId,
state: "on",
})),
};
lightBadges.push(
{
type: "button",
icon: "mdi:lightbulb",
tap_action: {
action: "perform-action",
perform_action: "light.turn_on",
target: {
entity_id: lightControlEntities.light,
},
},
visibility: [
{
condition: "not",
conditions: [anyOnCondition],
},
],
},
{
type: "button",
icon: "mdi:lightbulb",
tap_action: {
action: "perform-action",
perform_action: "light.turn_off",
target: {
entity_id: lightControlEntities.light,
},
},
visibility: [anyOnCondition],
}
);
}
const lightBadges =
lightControlEntities.light.length > 0
? computeLightToggleHeadingBadges(lightControlEntities.light, {
entity_id: lightControlEntities.light,
})
: [];
sections.push({
type: "grid",

View File

@@ -0,0 +1,64 @@
import type { HassServiceTarget } from "home-assistant-js-websocket";
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types";
import type { Condition } from "../../common/validate-condition";
/**
* Creates two heading badges for toggling lights: one visible when all lights
* are off (calls turn_on), another when any light is on (calls turn_off).
*/
export const computeLightToggleHeadingBadges = (
entityIds: string[],
target: HassServiceTarget,
options?: {
icon?: string;
turnOnText?: string;
turnOffText?: string;
turnOffColor?: string;
extraVisibility?: Condition[];
}
): ButtonHeadingBadgeConfig[] => {
const icon = options?.icon ?? "mdi:lightbulb";
const anyOnCondition: Condition = {
condition: "or",
conditions: entityIds.map((entityId) => ({
condition: "state" as const,
entity: entityId,
state: "on",
})),
};
const extraVisibility = options?.extraVisibility ?? [];
return [
{
type: "button",
icon: icon,
...(options?.turnOnText ? { text: options.turnOnText } : {}),
tap_action: {
action: "perform-action",
perform_action: "light.turn_on",
target: target,
},
visibility: [
...extraVisibility,
{
condition: "not",
conditions: [anyOnCondition],
},
],
},
{
type: "button",
icon: icon,
...(options?.turnOffText ? { text: options.turnOffText } : {}),
...(options?.turnOffColor ? { color: options.turnOffColor } : {}),
tap_action: {
action: "perform-action",
perform_action: "light.turn_off",
target: target,
},
visibility: [...extraVisibility, anyOnCondition],
},
];
};