Compare commits

...

3 Commits

Author SHA1 Message Date
Aidan Timson
fcaabfb326 Use superstruct 2025-08-29 14:34:23 +01:00
Aidan Timson
defc379a92 Max 2025-08-29 14:32:13 +01:00
Aidan Timson
b539ffcc50 Add min/max and step size to volume slider card feature 2025-08-29 14:26:30 +01:00
5 changed files with 139 additions and 4 deletions

View File

@@ -10,7 +10,7 @@ import {
type MediaPlayerEntity,
} from "../../../data/media-player";
import type { HomeAssistant } from "../../../types";
import type { LovelaceCardFeature } from "../types";
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
import { cardFeatureStyles } from "./common/card-feature-styles";
import type {
LovelaceCardFeatureContext,
@@ -58,6 +58,15 @@ class HuiMediaPlayerVolumeSliderCardFeature
};
}
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
await import(
"../editor/config-elements/hui-media-player-volume-slider-card-feature-editor"
);
return document.createElement(
"hui-media-player-volume-slider-card-feature-editor"
);
}
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
if (!config) {
throw new Error("Invalid configuration");
@@ -84,8 +93,9 @@ class HuiMediaPlayerVolumeSliderCardFeature
return html`
<ha-control-slider
.value=${position}
min="0"
max="100"
.min=${this._config.min ?? 0}
.max=${this._config.max ?? 100}
.step=${this._config.step ?? 1}
.showHandle=${stateActive(this._stateObj)}
.disabled=${!this._stateObj || isUnavailableState(this._stateObj.state)}
@value-changed=${this._valueChanged}

View File

@@ -45,6 +45,9 @@ export interface MediaPlayerPlaybackCardFeatureConfig {
export interface MediaPlayerVolumeSliderCardFeatureConfig {
type: "media-player-volume-slider";
min?: number;
max?: number;
step?: number;
}
export interface FanDirectionCardFeatureConfig {

View File

@@ -126,6 +126,7 @@ const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
"fan-preset-modes",
"humidifier-modes",
"lawn-mower-commands",
"media-player-volume-slider",
"numeric-input",
"select-options",
"update-actions",

View File

@@ -0,0 +1,118 @@
import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { assign, assert, number, object, optional } from "superstruct";
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 { LovelaceCardFeatureEditor } from "../../types";
import type {
MediaPlayerVolumeSliderCardFeatureConfig,
LovelaceCardFeatureContext,
} from "../../card-features/types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
const cardConfigStruct = assign(
baseLovelaceCardConfig,
object({
min: optional(number()),
max: optional(number()),
step: optional(number()),
})
);
@customElement("hui-media-player-volume-slider-card-feature-editor")
export class HuiMediaPlayerVolumeSliderCardFeatureEditor
extends LitElement
implements LovelaceCardFeatureEditor
{
@property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
@state() private _config?: MediaPlayerVolumeSliderCardFeatureConfig;
public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
assert(config, cardConfigStruct);
this._config = config;
}
private _schema = memoizeOne(
() =>
[
{
name: "min",
selector: {
number: {
min: 0,
max: 100,
mode: "slider",
},
},
},
{
name: "max",
selector: {
number: {
min: 0,
max: 100,
mode: "slider",
},
},
},
{
name: "step",
selector: {
number: {
min: 1,
max: 40,
mode: "slider",
},
},
},
] as const
);
protected render() {
if (!this.hass || !this._config) {
return nothing;
}
const data: MediaPlayerVolumeSliderCardFeatureConfig = {
min: 0,
max: 100,
step: 1,
...this._config,
};
const schema = this._schema();
return html`
<ha-form
.hass=${this.hass}
.data=${data}
.schema=${schema}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
></ha-form>
`;
}
private _valueChanged(ev: CustomEvent): void {
fireEvent(this, "config-changed", { config: ev.detail.value });
}
private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) =>
this.hass!.localize(
`ui.panel.lovelace.editor.features.types.media-player-volume-slider.${schema.name}`
);
}
declare global {
interface HTMLElementTagNameMap {
"hui-media-player-volume-slider-card-feature-editor": HuiMediaPlayerVolumeSliderCardFeatureEditor;
}
}

View File

@@ -7988,7 +7988,10 @@
"label": "Media player playback controls"
},
"media-player-volume-slider": {
"label": "Media player volume slider"
"label": "Media player volume slider",
"min": "Minimum volume",
"max": "Maximum volume",
"step": "Step size"
},
"vacuum-commands": {
"label": "Vacuum commands",