Skip to content

Commit

Permalink
feat(#31): add possibility to use mushroom slider
Browse files Browse the repository at this point in the history
  • Loading branch information
Gh61 committed Sep 29, 2023
1 parent 8f30f7e commit 6690185
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/controls/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ export class HueDialog extends IdLitElement {
padding: 12px;
margin: 4px 0;
}
.hue-heading ha-slider {
.hue-heading .brightness-slider {
width: 100%;
}
/* Disable the bottom border radius */
Expand Down
104 changes: 104 additions & 0 deletions src/controls/mushroom-slider-container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { LitElement, css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { Consts } from '../types/consts';

/*
* This is container for mushroom-slider, which will create margin and style the slider in the way, we need.
*
* using: https://github.com/phischdev/lovelace-mushroom-better-sliders/blob/main/src/shared/slider.ts
* inspiration: https://github.com/phischdev/lovelace-mushroom-better-sliders/blob/main/src/cards/light-card/controls/light-brightness-control.ts
*/

@customElement(HueMushroomSliderContainer.ElementName)
export class HueMushroomSliderContainer extends LitElement {
/**
* Name of this Element
*/
public static readonly ElementName = 'hue-mushroom-slider-container' + Consts.ElementPostfix;

// Consts
private static readonly Margin = 14;
private static readonly Height = 28;

// Property mirrors

@property({ type: Boolean })
public disabled: boolean = false;

@property({ attribute: false, type: Number, reflect: true })
public value?: number;

@property({ type: Number })
public step: number = 1;

@property({ type: Number })
public min: number = 0;

@property({ type: Number })
public max: number = 100;

private onChange(e: CustomEvent<{ value: number }>): void {
this.value = e.detail.value;
this.dispatchEvent(
new CustomEvent('change', {
detail: {
value: this.value
}
})
);
}

private onCurrentChange(e: CustomEvent<{ value?: number }>): void {
const value = e.detail.value;
this.dispatchEvent(
new CustomEvent('current-change', {
detail: {
value
}
})
);
}

protected override render() {
return html`
<mushroom-slider
.disabled=${this.disabled}
.value=${this.value}
.step=${this.step}
.min=${this.min}
.max=${this.max}
.showActive=${true}
@change=${this.onChange}
@current-change=${this.onCurrentChange}
/>
`;
}

public static override get styles() {
return css`
:host {
display: inline;
/* colors */
--slider-color: var(--dark-primary-color, var(--primary-color));
--slider-outline-color: transparent;
--slider-bg-color: rgba(0,0,0,0.3);
}
mushroom-slider {
display: inline-block;
width: calc(100% - ${2 * HueMushroomSliderContainer.Margin}px);
margin-left: ${HueMushroomSliderContainer.Margin}px;
margin-right: ${HueMushroomSliderContainer.Margin}px;
/* colors */
--main-color: var(--slider-color);
--bg-color: var(--slider-bg-color);
--main-outline-color: var(--slider-outline-color);
/* base styles: */
--control-height: var(--mush-control-height, ${HueMushroomSliderContainer.Height}px);
--control-border-radius: var(--mush-control-border-radius, 12px);
}
`;
}
}
50 changes: 38 additions & 12 deletions src/core/view-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { html, nothing } from 'lit';
import { nothing } from 'lit';
import { html, unsafeStatic } from 'lit/static-html.js';
import { styleMap } from 'lit-html/directives/style-map.js';
import { HueLikeLightCardConfig } from '../types/config';
import { Consts } from '../types/consts';
Expand All @@ -8,6 +9,8 @@ import { ILightContainer } from '../types/types-interface';
import { Background } from './colors/background';
import { Color } from './colors/color';
import { HaIcon, IHassWindow } from '../types/types-hass';
import { SliderType } from '../types/types-config';
import { HueMushroomSliderContainer } from '../controls/mushroom-slider-container';

export class ViewUtils {

Expand All @@ -19,12 +22,13 @@ export class ViewUtils {
// To help change themes on the fly
const styles = ThemeHelper.getSwitchThemeStyle();

return html`<ha-switch
.checked=${ctrl.isOn()}
.disabled=${ctrl.isUnavailable()}
.haptic=true
style=${styleMap(styles)}
@change=${(ev: Event) => this.changed(ctrl, onChange, false, ev)}
return html`
<ha-switch
.checked=${ctrl.isOn()}
.disabled=${ctrl.isUnavailable()}
.haptic=true
style=${styleMap(styles)}
@change=${(ev: Event) => this.changed(ctrl, onChange, false, ev)}
></ha-switch>`;
}

Expand All @@ -34,17 +38,39 @@ export class ViewUtils {
*/
public static createSlider(ctrl: ILightContainer, config: HueLikeLightCardConfig, onChange: Action) {

// If the controller doesn't support brightness change, the slider will not be created
if (!ctrl.features.brightness)
// If the controller doesn't support brightness change or slider is disabled, the slider will not be created
if (!ctrl.features.brightness || config.slider == SliderType.None)
return nothing;

const min = config.allowZero ? 0 : 1;
const max = 100;
const step = 1;

return html`<ha-slider .min=${min} .max=${max} .step=${step} .disabled=${config.allowZero ? ctrl.isUnavailable() : ctrl.isOff()} .value=${ctrl.brightnessValue}
pin @change=${(ev: Event) => this.changed(ctrl, onChange, true, ev)}
ignore-bar-touch
if (config.slider == SliderType.Mushroom) {
return html`
<${unsafeStatic(HueMushroomSliderContainer.ElementName)}
class="brightness-slider"
.min=${min}
.max=${max}
.step=${step}
.disabled=${config.allowZero ? ctrl.isUnavailable() : ctrl.isOff()}
.value=${ctrl.brightnessValue}
.showActive=${true}
@change=${(ev: Event) => this.changed(ctrl, onChange, true, ev)}
/>`;

// @current-change=${this.onCurrentChange}
}

return html`
<ha-slider pin ignore-bar-touch
class="brightness-slider"
.min=${min}
.max=${max}
.step=${step}
.disabled=${config.allowZero ? ctrl.isUnavailable() : ctrl.isOff()}
.value=${ctrl.brightnessValue}
@change=${(ev: Event) => this.changed(ctrl, onChange, true, ev)}
></ha-slider>`;
}

Expand Down
14 changes: 13 additions & 1 deletion src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { HomeAssistant } from 'custom-card-helpers';
import { removeDuplicites } from './extensions';
import { ColorExtended } from '../core/colors/color-extended';
import { HassTextTemplate } from '../core/hass-text-template';
import { ClickAction, ClickActionData, ConfigEntityInterface, HueLikeLightCardConfigInterface, KnownIconSize, SceneConfig, SceneOrder } from './types-config';
import { ClickAction, ClickActionData, ConfigEntityInterface, HueLikeLightCardConfigInterface, KnownIconSize, SceneConfig, SceneOrder, SliderType } from './types-config';
import { HassWsClient } from '../core/hass-ws-client';

declare type EntityRelations = {
Expand All @@ -26,6 +26,7 @@ export class HueLikeLightCardConfig implements HueLikeLightCardConfigInterface {
this.icon = plainConfig.icon;
this.iconSize = HueLikeLightCardConfig.getIconSize(plainConfig.iconSize);
this.showSwitch = HueLikeLightCardConfig.getBoolean(plainConfig.showSwitch, true);
this.slider = HueLikeLightCardConfig.getSliderType(plainConfig.slider);
this._scenes = HueLikeLightCardConfig.getScenesArray(plainConfig.scenes);
this.sceneOrder = HueLikeLightCardConfig.getSceneOrder(plainConfig.sceneOrder);
this.offClickAction = HueLikeLightCardConfig.getClickAction(plainConfig.offClickAction);
Expand Down Expand Up @@ -62,6 +63,16 @@ export class HueLikeLightCardConfig implements HueLikeLightCardConfigInterface {
return !!plain;
}

/**
* @returns SliderType valid enum, default for empty or throws exception.
*/
private static getSliderType(plain: SliderType | string | undefined): SliderType {
if (!plain)
return SliderType.Default;

return this.tryParseEnum<SliderType>(SliderType, plain, 'Slider type');
}

/**
* @returns ClickAction valid enum, default for empty or throws exception.
*/
Expand Down Expand Up @@ -164,6 +175,7 @@ export class HueLikeLightCardConfig implements HueLikeLightCardConfigInterface {
public readonly icon?: string;
public readonly iconSize: number;
public readonly showSwitch: boolean;
public readonly slider: SliderType;
public get scenes() { return this._scenes; }
public readonly sceneOrder: SceneOrder;
public readonly offClickAction: ClickAction;
Expand Down
7 changes: 7 additions & 0 deletions src/types/types-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export enum KnownIconSize {
Small = 'small'
}

export enum SliderType {
Default = 'default',
None = 'none',
Mushroom = 'mushroom'
}

export enum ClickAction {
Default = 'default',
NoAction = 'none',
Expand Down Expand Up @@ -179,6 +185,7 @@ export interface HueLikeLightCardConfigInterface extends ConfigEntityInterface {
readonly icon?: string;
readonly iconSize?: string | number;
readonly showSwitch?: boolean;
readonly slider?: string | SliderType;
readonly scenes?: (string | SceneConfig)[];
readonly sceneOrder?: SceneOrder;
readonly offClickAction?: ClickAction;
Expand Down

0 comments on commit 6690185

Please sign in to comment.