Skip to content

Commit

Permalink
feat(slider): add animation and step support to slider (#521)
Browse files Browse the repository at this point in the history
* feat(slider): add animation and step support to slider

* feat(slider): add animation of slider indicator
  • Loading branch information
piitaya committed May 24, 2022
1 parent f5a5d4b commit 7ffe5b5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 7 deletions.
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;
}
`;
}
}

0 comments on commit 7ffe5b5

Please sign in to comment.