Skip to content

Commit

Permalink
Add new design to thermostat card (#18709)
Browse files Browse the repository at this point in the history
* Add new design for thermostat card

* Add feature to thermostat card

* Fix margin

* Add current

* use big number component

* Add current

* Fix translations

* Add theme and name options

* Reduce margin on small card

* Fix types

* Add hvac mode to default dashboard

* Don't put feature full size

* Full width for features

* Improve design on small screen
  • Loading branch information
piitaya authored Nov 22, 2023
1 parent 1526209 commit c787c92
Show file tree
Hide file tree
Showing 16 changed files with 578 additions and 796 deletions.
114 changes: 114 additions & 0 deletions src/components/ha-big-number.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { CSSResultGroup, LitElement, css, html } from "lit";
import { customElement, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { formatNumber } from "../common/number/format_number";
import { blankBeforeUnit } from "../common/translations/blank_before_unit";
import { HomeAssistant } from "../types";

@customElement("ha-big-number")
export class HaBigNumber extends LitElement {
@property() public value!: number;

@property() public unit?: string;

@property({ attribute: "unit-position" })
public unitPosition: "top" | "bottom" = "top";

@property({ attribute: false })
public hass?: HomeAssistant;

@property({ attribute: false })
public formatOptions: Intl.NumberFormatOptions = {};

protected render() {
const formatted = formatNumber(
this.value,
this.hass?.locale,
this.formatOptions
);
const [integer] = formatted.includes(".")
? formatted.split(".")
: formatted.split(",");

const temperatureDecimal = formatted.replace(integer, "");

const formattedValue = `${this.value}${
this.unit ? `${blankBeforeUnit(this.unit)}${this.unit}` : ""
}`;

const unitBottom = this.unitPosition === "bottom";

return html`
<p class="value">
<span aria-hidden="true" class="displayed-value">
<span>${integer}</span>
<span class="addon ${classMap({ bottom: unitBottom })}">
<span class="decimal">${temperatureDecimal}</span>
<span class="unit">${this.unit}</span>
</span>
</span>
<span class="visually-hidden">${formattedValue}</span>
</p>
`;
}

static get styles(): CSSResultGroup {
return [
css`
:host {
font-size: 57px;
line-height: 1.12;
letter-spacing: -0.25px;
}
.value {
display: flex;
margin: 0;
direction: ltr;
}
.displayed-value {
display: inline-flex;
flex-direction: row;
align-items: flex-end;
}
.addon {
display: flex;
flex-direction: column-reverse;
padding: 4px 0;
}
.addon.bottom {
flex-direction: row;
align-items: baseline;
}
.addon.bottom .unit {
margin-bottom: 4px;
margin-left: 2px;
}
.value .decimal {
font-size: 0.42em;
line-height: 1.33;
}
.value .unit {
font-size: 0.33em;
line-height: 1.26;
}
/* Accessibility */
.visually-hidden {
position: absolute;
overflow: hidden;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
padding: 0;
border: 0;
}
`,
];
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-big-number": HaBigNumber;
}
}
4 changes: 3 additions & 1 deletion src/components/ha-control-circular-slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,11 @@ export class HaControlCircularSlider extends LitElement {
--control-circular-slider-high-color: var(
--control-circular-slider-color
);
width: 320px;
display: block;
}
svg {
width: 320px;
width: 100%;
display: block;
}
#slider {
Expand Down
2 changes: 1 addition & 1 deletion src/components/ha-control-number-buttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class HaControlNumberButton extends LitElement {

@property() public unit?: string;

@property({ attribute: "false" })
@property({ attribute: false })
public formatOptions: Intl.NumberFormatOptions = {};

@query("#input") _input!: HTMLDivElement;
Expand Down
2 changes: 1 addition & 1 deletion src/components/ha-control-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export class HaControlSelect extends LitElement {
position: relative;
flex: 1;
height: 100%;
width: 100%;
width: 40px;
display: flex;
align-items: center;
justify-content: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { mdiMinus, mdiPlus } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import { stateActive } from "../../../../common/entity/state_active";
import { domainStateColorProperties } from "../../../../common/entity/state_color";
import { supportsFeature } from "../../../../common/entity/supports-feature";
import { clamp } from "../../../../common/number/clamp";
import { debounce } from "../../../../common/util/debounce";
import "../../../../components/ha-big-number";
import "../../../../components/ha-control-circular-slider";
import "../../../../components/ha-outlined-icon-button";
import "../../../../components/ha-svg-icon";
Expand All @@ -22,6 +24,9 @@ export class HaMoreInfoClimateHumidity extends LitElement {

@property({ attribute: false }) public stateObj!: ClimateEntity;

@property({ attribute: "show-current", type: Boolean })
public showCurrent?: boolean;

@state() private _targetHumidity?: number;

protected willUpdate(changedProp: PropertyValues): void {
Expand Down Expand Up @@ -87,9 +92,7 @@ export class HaMoreInfoClimateHumidity extends LitElement {

return html`
<p class="label">
${this.hass.localize(
"ui.dialogs.more_info_control.climate.humidity_target"
)}
${this.hass.localize("ui.card.climate.humidity_target")}
</p>
`;
}
Expand All @@ -114,20 +117,37 @@ export class HaMoreInfoClimateHumidity extends LitElement {
}

private _renderTarget(humidity: number) {
const rounded = Math.round(humidity);
const formatted = this.hass.formatEntityAttributeValue(
this.stateObj,
"humidity",
rounded
);
const formatOptions = {
maximumFractionDigits: 0,
};

return html`
<div class="target">
<p class="value" aria-hidden="true">
${rounded}<span class="unit">%</span>
</p>
<p class="visually-hidden">${formatted}</p>
</div>
<ha-big-number
.value=${humidity}
unit="%"
unit-position="bottom"
.hass=${this.hass}
.formatOptions=${formatOptions}
></ha-big-number>
`;
}

private _renderCurrentHumidity(humidity?: number) {
if (!this.showCurrent || humidity == null) {
return html`<p class="label">&nbsp;</p>`;
}

return html`
<p class="label">
<ha-svg-icon .path=${mdiWaterPercent}></ha-svg-icon>
<span>
${this.hass.formatEntityAttributeValue(
this.stateObj,
"current_humidity",
humidity
)}
</span>
</p>
`;
}

Expand Down Expand Up @@ -174,10 +194,10 @@ export class HaMoreInfoClimateHumidity extends LitElement {
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
<div class="target-container">
${this._renderTarget(targetHumidity)}
</div>
${this._renderLabel()} ${this._renderTarget(targetHumidity)}
${this._renderCurrentHumidity(
this.stateObj.attributes.current_humidity
)}
</div>
${this._renderButtons()}
</div>
Expand All @@ -195,32 +215,17 @@ export class HaMoreInfoClimateHumidity extends LitElement {
>
</ha-control-circular-slider>
<div class="info">
<div class="label-container">${this._renderLabel()}</div>
${this._renderLabel()}
${this._renderCurrentHumidity(
this.stateObj.attributes.current_humidity
)}
</div>
</div>
`;
}

static get styles(): CSSResultGroup {
return [
moreInfoControlCircularSliderStyle,
css`
/* Elements */
.target-container {
margin-bottom: 30px;
}
.target .value {
font-size: 58px;
line-height: 1;
letter-spacing: -0.25px;
}
.target .value .unit {
font-size: 0.4em;
line-height: 1;
margin-left: 2px;
}
`,
];
return moreInfoControlCircularSliderStyle;
}
}

Expand Down
Loading

0 comments on commit c787c92

Please sign in to comment.