diff --git a/src/components/ha-expansion-panel.ts b/src/components/ha-expansion-panel.ts
index 47c108e5bd..64a564c454 100644
--- a/src/components/ha-expansion-panel.ts
+++ b/src/components/ha-expansion-panel.ts
@@ -68,8 +68,8 @@ export class HaExpansionPanel extends LitElement {
>
`
: ""}
+
-
{
if (typeof attribute === "object") {
@@ -496,12 +497,18 @@ export class HaServiceControl extends LitElement {
) ||
dataField.name ||
dataField.key}
- >
- ${this._renderSectionDescription(
+ .secondary=${this._getSectionDescription(
dataField,
domain,
serviceName
)}
+ >
+
${Object.entries(dataField.fields).map(([key, field]) =>
this._renderField(
{ key, ...field },
@@ -522,20 +529,14 @@ export class HaServiceControl extends LitElement {
)} `;
}
- private _renderSectionDescription(
+ private _getSectionDescription(
dataField: ExtHassService["fields"][number],
domain: string | undefined,
serviceName: string | undefined
) {
- const description = this.hass!.localize(
+ return this.hass!.localize(
`component.${domain}.services.${serviceName}.sections.${dataField.key}.description`
);
-
- if (!description) {
- return nothing;
- }
-
- return html`
${description}
`;
}
private _renderField = (
diff --git a/src/components/ha-service-section-icon.ts b/src/components/ha-service-section-icon.ts
new file mode 100644
index 0000000000..f8c7fdfbbe
--- /dev/null
+++ b/src/components/ha-service-section-icon.ts
@@ -0,0 +1,53 @@
+import { html, LitElement, nothing } from "lit";
+import { customElement, property } from "lit/decorators";
+import { until } from "lit/directives/until";
+import { HomeAssistant } from "../types";
+import "./ha-icon";
+import "./ha-svg-icon";
+import { serviceSectionIcon } from "../data/icons";
+
+@customElement("ha-service-section-icon")
+export class HaServiceSectionIcon extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property() public service?: string;
+
+ @property() public section?: string;
+
+ @property() public icon?: string;
+
+ protected render() {
+ if (this.icon) {
+ return html`
`;
+ }
+
+ if (!this.service || !this.section) {
+ return nothing;
+ }
+
+ if (!this.hass) {
+ return this._renderFallback();
+ }
+
+ const icon = serviceSectionIcon(this.hass, this.service, this.section).then(
+ (icn) => {
+ if (icn) {
+ return html`
`;
+ }
+ return this._renderFallback();
+ }
+ );
+
+ return html`${until(icon)}`;
+ }
+
+ private _renderFallback() {
+ return nothing;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-service-section-icon": HaServiceSectionIcon;
+ }
+}
diff --git a/src/data/icons.ts b/src/data/icons.ts
index f63a861e08..90baec1907 100644
--- a/src/data/icons.ts
+++ b/src/data/icons.ts
@@ -62,7 +62,7 @@ export interface ComponentIcons {
}
interface ServiceIcons {
- [service: string]: string;
+ [service: string]: { service: string; sections?: { [name: string]: string } };
}
export type IconCategory = "entity" | "entity_component" | "services";
@@ -288,7 +288,8 @@ export const serviceIcon = async (
const serviceName = computeObjectId(service);
const serviceIcons = await getServiceIcons(hass, domain);
if (serviceIcons) {
- icon = serviceIcons[serviceName] as string;
+ const srvceIcon = serviceIcons[serviceName] as ServiceIcons[string];
+ icon = srvceIcon?.service;
}
if (!icon) {
icon = await domainIcon(hass, domain);
@@ -296,6 +297,21 @@ export const serviceIcon = async (
return icon;
};
+export const serviceSectionIcon = async (
+ hass: HomeAssistant,
+ service: string,
+ section: string
+): Promise
=> {
+ const domain = computeDomain(service);
+ const serviceName = computeObjectId(service);
+ const serviceIcons = await getServiceIcons(hass, domain);
+ if (serviceIcons) {
+ const srvceIcon = serviceIcons[serviceName] as ServiceIcons[string];
+ return srvceIcon?.sections?.[section];
+ }
+ return undefined;
+};
+
export const domainIcon = async (
hass: HomeAssistant,
domain: string,