Skip to content

Commit

Permalink
New secondary_info type fan-mode-dropdown #10
Browse files Browse the repository at this point in the history
  • Loading branch information
artem-sedykh committed Jun 9, 2020
1 parent cb43a94 commit ee685ca
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 19 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ A minimalistic yet customizable climate card for [Home Assistant](https://github
| toggle: `hide` | boolean | optional | v1.0.2 | Hide button, default value `False`
| toggle: `default` | boolean | optional | v1.0.2 | Default toggle button state, default value `off`.
| **secondary_info** | object | optional | v1.1.0 | secondary_info config. [secondary info examples](#secondary-info)
| secondary_info: `type` | string | optional | v1.1.0 | available types: `last-changed, fan-mode, hvac-mode, hvac-action`
| secondary_info: `icon` | string | optional | v1.1.0 | icon for types: `fan-mode, hvac-mode`, `hvac-action`
| secondary_info: `type` | string | optional | v1.1.0 | available types: `last-changed, fan-mode, fan-mode-dropdown, hvac-mode, hvac-action`
| secondary_info: `icon` | string | optional | v1.1.0 | icon for types: `fan-mode, fan-mode-dropdown, hvac-mode`, `hvac-action`
| secondary_info: `source` | object | optional | v1.2.1 | source available types: `hvac-action`
| secondary_info: `source:{item_name}` | object | optional | v1.2.1 | source item name
| secondary_info: `source:{item_name}:icon` | object | optional | v1.2.1 | Specify a custom icon from any of the available mdi icons.
Expand Down Expand Up @@ -602,6 +602,15 @@ Or you can use one permanent icon
icon: 'mdi:cached'
```

##### fan-mode-dropdown

```yaml
- type: custom:mini-climate
entity: climate.dahatsu
secondary_info: fan-mode-dropdown
```
![image](https://user-images.githubusercontent.com/861063/84180244-d80d0a80-aa8f-11ea-8275-f4e3db85fd31.png)

### Theme variables
The following variables are available and can be set in your theme to change the appearence of the card.
Can be specified by color name, hexadecimal, rgb, rgba, hsl, hsla, basically anything supported by CSS.
Expand Down
9 changes: 9 additions & 0 deletions release_notes/v1.2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,12 @@ Or you can use one permanent icon
type: hvac-action
icon: 'mdi:cached'
```
- Add new secondary_info type: `fan-mode-dropdown` #10

```yaml
- type: custom:mini-climate
entity: climate.dahatsu
secondary_info: fan-mode-dropdown
```
![image](https://user-images.githubusercontent.com/861063/84180244-d80d0a80-aa8f-11ea-8275-f4e3db85fd31.png)
127 changes: 127 additions & 0 deletions src/components/fan-mode-secondary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { LitElement, html, css } from 'lit-element';
import sharedStyle from '../sharedStyle';

class FanModeSecondary extends LitElement {
constructor() {
super();
this.fanMode = {};
this.config = {};
this.timer = undefined;
this._selected = {};
this.source = {};
}

static get properties() {
return {
fanMode: { type: Object },
config: { type: Object },
};
}

get selectedIndex() {
return this.fanMode.source.map(item => item.id).indexOf(this._selected.id);
}

handleChange(e) {
const index = e.target.selected;

if (index === this.selectedIndex || !this.fanMode.source[index])
return;

clearTimeout(this.timer);

const selected = this.fanMode.source[index];
const { entity } = this.fanMode;
const oldSelected = this._selected;
this._selected = selected;

this.timer = setTimeout(async () => {
if (this.fanMode.entity === entity) {
this._selected = oldSelected;
return this.requestUpdate('_selected');
}
}, this.fanMode.actionTimeout);

this.fanMode.handleChange(selected.id);

return this.requestUpdate('_selected');
}

renderFanMode() {
const label = this._selected ? this._selected.name : this.fanMode.state;
const icon = this.config.secondary_info.icon ? this.config.secondary_info.icon
: this.fanMode.icon;

return html`
<ha-icon class='icon' .icon=${icon}></ha-icon>
<span class='name'>${label}</span>
`;
}

renderFanModeDropdown() {
return html`
<paper-menu-button
class='mc-dropdown'
noink no-animations
.horizontalAlign=${'right'}
.verticalAlign=${'top'}
.verticalOffset=${44}
?disabled=${this.fanMode.disabled}
.dynamicAlign=${true}>
<div class="wrap" slot='dropdown-trigger'>
${this.renderFanMode()}
</div>
<paper-listbox slot="dropdown-content" .selected=${this.selectedIndex} @iron-select=${this.handleChange}>
${this.fanMode.source.map(item => html`
<paper-item value=${item.id || item.name}>
<span class='mc-dropdown__item__label'>${item.name}</span>
</paper-item>`)}
</paper-listbox>
</paper-menu-button>
`;
}

render() {
const { type } = this.config.secondary_info;

if (type === 'fan-mode-dropdown') {
return this.renderFanModeDropdown();
}

return this.renderFanMode();
}

updated(changedProps) {
if (changedProps.has('fanMode')) {
clearTimeout(this.timer);
this._selected = this.fanMode.selected;
this.requestUpdate('_selected').then();
}
}

static get styles() {
return [
sharedStyle,
css`
paper-menu-button {
padding: 0;
}
.name {
font-size: calc(var(--mc-unit) * .35);
font-weight: var(--mc-info-font-weight);
line-height: calc(var(--mc-unit) * .5);
vertical-align: middle;
display: inline-block;
}
.icon {
color: var(--mc-icon-color);
height: calc(var(--mc-unit) * .475);
width: calc(var(--mc-unit) * .5);
min-width: calc(var(--mc-unit) * .5);
--mdc-icon-size: calc(var(--mc-unit) * 0.5);
}
`];
}
}

customElements.define('mc-fan-mode-secondary', FanModeSecondary);
15 changes: 2 additions & 13 deletions src/components/secondary-info.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LitElement, html, css } from 'lit-element';
import sharedStyle from '../sharedStyle';
import './fan-mode-secondary';

class SecondaryInfo extends LitElement {
constructor() {
Expand Down Expand Up @@ -44,18 +45,6 @@ class SecondaryInfo extends LitElement {
`;
}

renderFanMode() {
const { selected } = this.fanMode;
const label = selected ? selected.name : this.fanMode.state;
const icon = this.config.secondary_info.icon ? this.config.secondary_info.icon
: this.fanMode.icon;

return html`
<ha-icon class='icon' .icon=${icon}></ha-icon>
<span class='name'>${label}</span>
`;
}

render() {
const { type } = this.config.secondary_info;

Expand All @@ -67,7 +56,7 @@ class SecondaryInfo extends LitElement {
case 'last-changed':
return html`<ha-relative-time .hass=${this.climate.hass} .datetime=${this.climate.lastChanged}></ha-relative-time>`;
default:
return this.renderFanMode();
return html`<mc-fan-mode-secondary .fanMode=${this.fanMode} .config=${this.config}></mc-fan-mode-secondary>`;
}
}

Expand Down
11 changes: 7 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ class MiniClimate extends LitElement {
}

render() {
const handle = this.config.secondary_info.type !== 'fan-mode-dropdown';
return html`
<ha-card
class=${this.computeClasses()}
Expand All @@ -468,8 +469,7 @@ class MiniClimate extends LitElement {
${this.renderIcon()}
<div class='entity__info'>
<div class="wrap">
<div class="entity__info__name_wrap"
@click=${e => this.handlePopup(e)}>
<div class="entity__info__name_wrap" @click=${e => this.handlePopup(e, handle)}>
${this.renderEntityName()}
</div>
<div class="ctl-wrap ellipsis">
Expand All @@ -492,7 +492,10 @@ class MiniClimate extends LitElement {
return this.requestUpdate('targetTemperatureChanging');
}

handlePopup(e) {
handlePopup(e, handle) {
if (!handle)
return;

e.stopPropagation();
handleClick(this, this.hass, this.config.tap_action, this.climate.id);
}
Expand Down Expand Up @@ -558,7 +561,7 @@ class MiniClimate extends LitElement {

renderEntityName() {
return html`
<div class='entity__info__name'>
<div class='entity__info__name' @click=${e => this.handlePopup(e, true)}>
${this.name}
</div>
${this.renderSecondaryInfo()}
Expand Down

0 comments on commit ee685ca

Please sign in to comment.