1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-18 07:56:44 +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, SMALL_SCREEN_CONDITION,
} from "../../lovelace/strategies/helpers/screen-conditions"; } from "../../lovelace/strategies/helpers/screen-conditions";
import type { ToggleGroupCardConfig } from "../../lovelace/cards/types"; 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 { export interface LightViewStrategyConfig {
type: "light"; type: "light";
@@ -51,15 +51,21 @@ const processAreasForLight = (
} }
if (areaCards.length > 0) { if (areaCards.length > 0) {
// Visibility condition: any light is on const lightToggleBadges = computeLightToggleHeadingBadges(
const anyOnCondition = { areaLights,
condition: "or" as const, { area_id: area.area_id },
conditions: areaLights.map((entityId) => ({ {
condition: "state" as const, icon: "mdi:power",
entity: entityId, turnOnText: hass.localize(
state: "on", "ui.panel.lovelace.strategy.light.off"
})), ),
}; turnOffText: hass.localize(
"ui.panel.lovelace.strategy.light.on"
),
turnOffColor: "orange",
extraVisibility: [SMALL_SCREEN_CONDITION],
}
);
cards.push({ cards.push({
heading_style: "subtitle", heading_style: "subtitle",
@@ -71,42 +77,7 @@ const processAreasForLight = (
navigation_path: `/home/areas-${area.area_id}`, navigation_path: `/home/areas-${area.area_id}`,
} }
: undefined, : undefined,
badges: [ badges: lightToggleBadges satisfies LovelaceCardConfig[],
// 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[],
}); });
// Toggle group card for desktop // 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 { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { HeadingCardConfig } from "../../cards/types"; import type { HeadingCardConfig } from "../../cards/types";
import type { ButtonHeadingBadgeConfig } from "../../heading-badges/types"; import { computeLightToggleHeadingBadges } from "../helpers/light-toggle-badges";
import { import {
AREA_STRATEGY_GROUP_ICONS, AREA_STRATEGY_GROUP_ICONS,
computeAreaTileCardConfig, computeAreaTileCardConfig,
@@ -97,50 +97,12 @@ export class AreaViewStrategy extends ReactiveElement {
hass hass
); );
const lightBadges: ButtonHeadingBadgeConfig[] = []; const lightBadges =
lightControlEntities.light.length > 0
if (lightControlEntities.light.length > 0) { ? computeLightToggleHeadingBadges(lightControlEntities.light, {
const anyOnCondition = { entity_id: lightControlEntities.light,
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],
}
);
}
sections.push({ sections.push({
type: "grid", 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],
},
];
};