Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(slider): add animation and step support to slider #521

Merged
merged 2 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/cards/fan-card/controls/fan-percentage-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import { isActive, isAvailable } from "../../../ha/data/entity";
import "../../../shared/slider";
import { getPercentage } from "../utils";
import { computePercentageStep, getPercentage } from "../utils";

@customElement("mushroom-fan-percentage-control")
export class FanPercentageControl extends LitElement {
Expand Down Expand Up @@ -42,6 +42,7 @@ export class FanPercentageControl extends LitElement {
.showActive=${true}
@change=${this.onChange}
@current-change=${this.onCurrentChange}
step=${computePercentageStep(this.entity)}
/>
`;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cards/fan-card/fan-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class FanCard extends MushroomBaseElement implements LovelaceCard {

private onCurrentPercentageChange(e: CustomEvent<{ value?: number }>): void {
if (e.detail.value != null) {
this.percentage = e.detail.value;
this.percentage = Math.round(e.detail.value);
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/cards/fan-card/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ export function getPercentage(entity: HassEntity) {
export function isOscillating(entity: HassEntity) {
return entity.attributes.oscillating != null ? Boolean(entity.attributes.oscillating) : false;
}

export function computePercentageStep(entity: HassEntity) {
if (entity.attributes.percentage_step) {
return entity.attributes.percentage_step;
}
return 1;
}
32 changes: 27 additions & 5 deletions src/shared/slider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators.js";
import { customElement, property, query, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { styleMap } from "lit/directives/style-map.js";
import "hammerjs";
Expand Down Expand Up @@ -33,6 +33,9 @@ export class SliderItem extends LitElement {
@property({ attribute: false, type: Number, reflect: true })
public value?: number;

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

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

Expand All @@ -41,6 +44,8 @@ export class SliderItem extends LitElement {

private _mc?: HammerManager;

@state() controlled: boolean = false;

valueToPercentage(value: number) {
return (value - this.min) / (this.max - this.min);
}
Expand Down Expand Up @@ -84,10 +89,12 @@ export class SliderItem extends LitElement {
let savedValue;
this._mc.on("panstart", () => {
if (this.disabled) return;
this.controlled = true;
savedValue = this.value;
});
this._mc.on("pancancel", () => {
if (this.disabled) return;
this.controlled = false;
this.value = savedValue;
});
this._mc.on("panmove", (e) => {
Expand All @@ -97,13 +104,14 @@ export class SliderItem extends LitElement {
this.dispatchEvent(
new CustomEvent("current-change", {
detail: {
value: Math.round(this.value),
value: Math.round(this.value / this.step) * this.step,
},
})
);
});
this._mc.on("panend", (e) => {
if (this.disabled) return;
this.controlled = false;
const percentage = getPercentageFromEvent(e);
this.value = this.percentageToValue(percentage);
this.dispatchEvent(
Expand All @@ -116,7 +124,7 @@ export class SliderItem extends LitElement {
this.dispatchEvent(
new CustomEvent("change", {
detail: {
value: Math.round(this.value),
value: Math.round(this.value / this.step) * this.step,
},
})
);
Expand All @@ -129,7 +137,7 @@ export class SliderItem extends LitElement {
this.dispatchEvent(
new CustomEvent("change", {
detail: {
value: Math.round(this.value),
value: Math.round(this.value / this.step) * this.step,
},
})
);
Expand All @@ -146,7 +154,13 @@ export class SliderItem extends LitElement {

protected render(): TemplateResult {
return html`
<div class=${classMap({ container: true, inactive: this.inactive || this.disabled })}>
<div
class=${classMap({
container: true,
inactive: this.inactive || this.disabled,
controlled: this.controlled,
})}
>
<div
id="slider"
class="slider"
Expand Down Expand Up @@ -206,6 +220,7 @@ export class SliderItem extends LitElement {
transform: scale3d(var(--value, 0), 1, 1);
transform-origin: left;
background-color: var(--main-color);
transition: transform 180ms ease-in-out;
}
.slider .slider-track-indicator {
position: absolute;
Expand All @@ -216,6 +231,7 @@ export class SliderItem extends LitElement {
border-radius: 3px;
background-color: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
transition: left 180ms ease-in-out;
}
.slider .slider-track-indicator:after {
display: block;
Expand All @@ -241,6 +257,12 @@ export class SliderItem extends LitElement {
.inactive .slider .slider-track-active {
background-color: var(--main-color-inactive);
}
.controlled .slider .slider-track-active {
transition: none;
}
.controlled .slider .slider-track-indicator {
transition: none;
}
`;
}
}