Switch to css grid and code refactor (#132)
* Switch to css grid and code refactor * Ability to specify the width of the card * Update documentation * Fix invalid CSS value * requested changes and bugfix
This commit is contained in:
parent
37a8b89256
commit
21c60bb033
61
README.md
61
README.md
|
@ -20,7 +20,7 @@ Lovelace Button card for your entities.
|
|||
- state display (optional)
|
||||
- custom color (optional), or based on light rgb value
|
||||
- custom state definition with customizable color, icon and style (optional)
|
||||
- custom size (optional)
|
||||
- [custom size of the icon, width and height](#Play-with-width-height-and-icon-size) (optional)
|
||||
- custom icon (optional)
|
||||
- custom css style (optional)
|
||||
- multiple [layout](#Layout) support
|
||||
|
@ -408,6 +408,65 @@ You can make the whole button blink:
|
|||
icon: mdi:shield-check
|
||||
```
|
||||
|
||||
### Play with width, height and icon size
|
||||
|
||||
Through the `styles` you can specify the `width` and `height` of the card, and also the icon size through the main `size` option. Playing with icon size will growth the card unless a `height` is specified.
|
||||
|
||||
If you specify a width for the card, it has to be in `px`. All the cards without a `width` defined will use the remaining space on the line.
|
||||
|
||||
![height-width](examples/width_height.png)
|
||||
|
||||
```yaml
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color: auto
|
||||
name: s:default h:200px
|
||||
style:
|
||||
- height: 200px
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color_type: card
|
||||
color: auto
|
||||
name: s:100% h:200px
|
||||
size: 100%
|
||||
style:
|
||||
- height: 200px
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color_type: card
|
||||
color: auto
|
||||
size: 10%
|
||||
name: s:10% h:200px
|
||||
style:
|
||||
- height: 200px
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color: auto
|
||||
name: 60px
|
||||
style:
|
||||
- height: 60px
|
||||
- width: 60px
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color_type: card
|
||||
color: auto
|
||||
name: 80px
|
||||
style:
|
||||
- height: 80px
|
||||
- width: 30px
|
||||
- type: "custom:button-card"
|
||||
entity: light.test_light
|
||||
color_type: card
|
||||
color: auto
|
||||
name: 300px
|
||||
style:
|
||||
- height: 300px
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
- [ciotlosm](https://github.com/ciotlosm) for the readme template and the awesome examples
|
||||
|
|
|
@ -3656,27 +3656,10 @@ const styles = css`
|
|||
letter-spacing: normal;
|
||||
width: 100%;
|
||||
}
|
||||
div.divTable{
|
||||
display: table;
|
||||
overflow: auto;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
div.divTableBody {
|
||||
display: table-row-group;
|
||||
}
|
||||
div.divTableRow {
|
||||
display: table-row;
|
||||
}
|
||||
.divTableCell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
div {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
min-width: 100%;
|
||||
}
|
||||
@keyframes blink{
|
||||
0%{opacity:0;}
|
||||
|
@ -3711,13 +3694,128 @@ const styles = css`
|
|||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.rotating {
|
||||
[rotating] {
|
||||
-webkit-animation: rotating 2s linear infinite;
|
||||
-moz-animation: rotating 2s linear infinite;
|
||||
-ms-animation: rotating 2s linear infinite;
|
||||
-o-animation: rotating 2s linear infinite;
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
max-height: 100%;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
.img-cell {
|
||||
grid-area: i;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
object-fit: scale;
|
||||
overflow: hidden;
|
||||
}
|
||||
.name {
|
||||
grid-area: n;
|
||||
max-width: 100%;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
/* margin: auto; */
|
||||
}
|
||||
.state {
|
||||
grid-area: s;
|
||||
max-width: 100%;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
/* margin: auto; */
|
||||
}
|
||||
|
||||
.container.vertical {
|
||||
grid-template-areas: "i" "n" "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr min-content min-content;
|
||||
}
|
||||
.container.vertical.no-icon {
|
||||
grid-template-areas: "n" "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.vertical.no-icon .state {
|
||||
align-self: start;
|
||||
}
|
||||
.container.vertical.no-icon .name {
|
||||
align-self: end;
|
||||
}
|
||||
.container.vertical.no-icon.no-name {
|
||||
grid-template-areas: "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.container.vertical.no-icon.no-name .state {
|
||||
align-self: center;
|
||||
}
|
||||
.container.vertical.no-icon.no-state {
|
||||
grid-template-areas: "n";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.container.vertical.no-icon.no-state .name {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.container.icon_name_state {
|
||||
grid-template-areas: "i n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.container.icon_name {
|
||||
grid-template-areas: "i n" "s s";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.icon_state {
|
||||
grid-template-areas: "i s" "n n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.name_state {
|
||||
grid-template-areas: "i" "n";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.icon_name_state2nd {
|
||||
grid-template-areas: "i n" "i s";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.icon_name_state2nd .name {
|
||||
align-self: end;
|
||||
}
|
||||
.container.icon_name_state2nd .state {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.container.icon_state_name2nd {
|
||||
grid-template-areas: "i s" "i n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.icon_state_name2nd .state {
|
||||
align-self: end;
|
||||
}
|
||||
.container.icon_state_name2nd .name {
|
||||
align-self: start;
|
||||
}
|
||||
`;
|
||||
|
||||
let ButtonCard = class ButtonCard extends LitElement {
|
||||
|
@ -3728,23 +3826,12 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
if (!this.config || !this.hass) {
|
||||
return html``;
|
||||
}
|
||||
const state = this.config.entity ? this.hass.states[this.config.entity] : undefined;
|
||||
const configState = this.testConfigState(state);
|
||||
switch (this.config.color_type) {
|
||||
case 'blank-card':
|
||||
return this.blankCardColoredHtml(state);
|
||||
case 'label-card':
|
||||
case 'card':
|
||||
return this.cardColoredHtml(state, configState);
|
||||
case 'icon':
|
||||
default:
|
||||
return this.iconColoredHtml(state, configState);
|
||||
}
|
||||
return this._cardHtml();
|
||||
}
|
||||
shouldUpdate(changedProps) {
|
||||
return hasConfigOrEntityChanged(this, changedProps);
|
||||
}
|
||||
testConfigState(state) {
|
||||
_getMatchingConfigState(state) {
|
||||
if (!state || !this.config.state) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -3786,7 +3873,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return retval;
|
||||
}
|
||||
getDefaultColorForState(state) {
|
||||
_getDefaultColorForState(state) {
|
||||
switch (state.state) {
|
||||
case 'on':
|
||||
return this.config.color_on;
|
||||
|
@ -3796,7 +3883,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
return this.config.default_color;
|
||||
}
|
||||
}
|
||||
buildCssColorAttribute(state, configState) {
|
||||
_buildCssColorAttribute(state, configState) {
|
||||
let colorValue = '';
|
||||
let color;
|
||||
if (configState && configState.color) {
|
||||
|
@ -3814,9 +3901,9 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
color = applyBrightnessToColor(color, (state.attributes.brightness + 245) / 5);
|
||||
}
|
||||
} else if (state.attributes.brightness) {
|
||||
color = applyBrightnessToColor(this.getDefaultColorForState(state), (state.attributes.brightness + 245) / 5);
|
||||
color = applyBrightnessToColor(this._getDefaultColorForState(state), (state.attributes.brightness + 245) / 5);
|
||||
} else {
|
||||
color = this.getDefaultColorForState(state);
|
||||
color = this._getDefaultColorForState(state);
|
||||
}
|
||||
} else {
|
||||
color = this.config.default_color;
|
||||
|
@ -3824,13 +3911,13 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
} else if (colorValue) {
|
||||
color = colorValue;
|
||||
} else if (state) {
|
||||
color = this.getDefaultColorForState(state);
|
||||
color = this._getDefaultColorForState(state);
|
||||
} else {
|
||||
color = this.config.default_color;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
buildIcon(state, configState) {
|
||||
_buildIcon(state, configState) {
|
||||
if (!this.config.show_icon) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -3844,7 +3931,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return icon;
|
||||
}
|
||||
buildEntityPicture(state, configState) {
|
||||
_buildEntityPicture(state, configState) {
|
||||
if (!this.config.show_entity_picture || !state && !configState && !this.config.entity_picture) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -3858,7 +3945,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return entityPicture;
|
||||
}
|
||||
buildStyle(state, configState) {
|
||||
_buildStyle(state, configState) {
|
||||
let cardStyle = {};
|
||||
let styleArray;
|
||||
if (state) {
|
||||
|
@ -3875,7 +3962,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return cardStyle;
|
||||
}
|
||||
buildEntityPictureStyle(state, configState) {
|
||||
_buildEntityPictureStyle(state, configState) {
|
||||
let entityPictureStyle = {};
|
||||
let styleArray;
|
||||
if (state) {
|
||||
|
@ -3892,7 +3979,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return entityPictureStyle;
|
||||
}
|
||||
buildName(state, configState) {
|
||||
_buildName(state, configState) {
|
||||
if (this.config.show_name === false) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -3906,10 +3993,10 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return name;
|
||||
}
|
||||
buildStateString(state) {
|
||||
_buildStateString(state) {
|
||||
let stateString;
|
||||
if (this.config.show_state && state && state.state) {
|
||||
const units = this.buildUnits(state);
|
||||
const units = this._buildUnits(state);
|
||||
if (units) {
|
||||
stateString = `${state.state} ${units}`;
|
||||
} else {
|
||||
|
@ -3918,7 +4005,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return stateString;
|
||||
}
|
||||
buildUnits(state) {
|
||||
_buildUnits(state) {
|
||||
let units;
|
||||
if (state) {
|
||||
if (this.config.show_units) {
|
||||
|
@ -3931,7 +4018,7 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return units;
|
||||
}
|
||||
isClickable(state) {
|
||||
_isClickable(state) {
|
||||
let clickable = true;
|
||||
if (this.config.tap_action.action === 'toggle' && this.config.hold_action.action === 'none' || this.config.hold_action.action === 'toggle' && this.config.tap_action.action === 'none') {
|
||||
if (state) {
|
||||
|
@ -3955,134 +4042,11 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
}
|
||||
return clickable;
|
||||
}
|
||||
rotate(configState) {
|
||||
return configState && configState.spin ? 'rotating' : '';
|
||||
_rotate(configState) {
|
||||
return configState && configState.spin ? true : false;
|
||||
}
|
||||
buttonContent(state, configState, color) {
|
||||
const icon = this.buildIcon(state, configState);
|
||||
const name = this.buildName(state, configState);
|
||||
const stateString = this.buildStateString(state);
|
||||
const nameStateString = buildNameStateConcat(name, stateString);
|
||||
const entityPicture = this.buildEntityPicture(state, configState);
|
||||
const entityPictureStyle = this.buildEntityPictureStyle(state, configState);
|
||||
const divTableCellStyles = { width: this.config.size, height: 'auto' };
|
||||
const haIconInlineStyle = {
|
||||
color,
|
||||
width: this.config.size,
|
||||
height: 'auto'
|
||||
};
|
||||
const haIconTableStyle = Object.assign({}, haIconInlineStyle, { width: 'auto', 'max-width': this.config.size });
|
||||
const entityPictureInlineStyle = Object.assign({}, haIconInlineStyle, entityPictureStyle);
|
||||
const entityPictureTableStyle = Object.assign({}, haIconTableStyle, entityPictureStyle);
|
||||
switch (this.config.layout) {
|
||||
case 'icon_name_state':
|
||||
return html`
|
||||
<div class='divTable'>
|
||||
<div class='divTableBody'>
|
||||
<div class='divTableRow'>
|
||||
<div class='divTableCell' style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${nameStateString ? html`<div class="divTableCell">${nameStateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'icon_name':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${stateString !== undefined ? html`<div>${stateString}</div>` : ''}
|
||||
`;
|
||||
case 'icon_state':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${name ? html`<div>${name}</div>` : ''}
|
||||
`;
|
||||
case 'icon_state_name2nd':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined && name ? html`<div class="divTableCell">${stateString}<br />${name}</div>` : ''}
|
||||
${!stateString && name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
${stateString && !name ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'icon_name_state2nd':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined && name ? html`<div class="divTableCell">${name}<br />${stateString}</div>` : ''}
|
||||
${!stateString && name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
${stateString && !name ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'name_state':
|
||||
return html`
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconInlineStyle)}
|
||||
icon=${icon} class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureInlineStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
${nameStateString ? html`<div>${nameStateString}</div>` : ''}
|
||||
`;
|
||||
case 'vertical':
|
||||
default:
|
||||
return html`
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconInlineStyle)}
|
||||
icon=${icon} class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureInlineStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
${name ? html`<div>${name}</div>` : ''}
|
||||
${stateString ? html`<div>${stateString}</div>` : ''}
|
||||
`;
|
||||
}
|
||||
}
|
||||
blankCardColoredHtml(state) {
|
||||
const color = this.buildCssColorAttribute(state, undefined);
|
||||
_blankCardColoredHtml(state) {
|
||||
const color = this._buildCssColorAttribute(state, undefined);
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
return html`
|
||||
<ha-card class="disabled">
|
||||
|
@ -4090,32 +4054,95 @@ let ButtonCard = class ButtonCard extends LitElement {
|
|||
</ha-card>
|
||||
`;
|
||||
}
|
||||
cardColoredHtml(state, configState) {
|
||||
const color = this.buildCssColorAttribute(state, configState);
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
const style = Object.assign({ color: fontColor, 'background-color': color }, this.buildStyle(state, configState));
|
||||
_cardHtml() {
|
||||
const state = this.config.entity ? this.hass.states[this.config.entity] : undefined;
|
||||
const configState = this._getMatchingConfigState(state);
|
||||
const color = this._buildCssColorAttribute(state, configState);
|
||||
let buttonColor = color;
|
||||
let cardStyle = {};
|
||||
const configCardStyle = this._buildStyle(state, configState);
|
||||
switch (this.config.color_type) {
|
||||
case 'blank-card':
|
||||
return this._blankCardColoredHtml(state);
|
||||
case 'card':
|
||||
case 'label-card':
|
||||
{
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
cardStyle.color = fontColor;
|
||||
cardStyle['background-color'] = color;
|
||||
cardStyle = Object.assign({}, cardStyle, configCardStyle);
|
||||
buttonColor = 'inherit';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cardStyle = configCardStyle;
|
||||
break;
|
||||
}
|
||||
if (configCardStyle.width) {
|
||||
this.style.setProperty('flex', '0 0 auto');
|
||||
this.style.setProperty('max-width', 'fit-content');
|
||||
}
|
||||
return html`
|
||||
<ha-card class="button-card-main ${this.isClickable(state) ? '' : 'disabled'}" style=${styleMap(style)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this.buttonContent(state, configState, 'inherit')}
|
||||
<ha-card class="button-card-main ${this._isClickable(state) ? '' : 'disabled'}" style=${styleMap(cardStyle)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this._buttonContent(state, configState, buttonColor)}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
iconColoredHtml(state, configState) {
|
||||
const color = this.buildCssColorAttribute(state, configState);
|
||||
const style = this.buildStyle(state, configState);
|
||||
_buttonContent(state, configState, color) {
|
||||
const name = this._buildName(state, configState);
|
||||
const stateString = this._buildStateString(state);
|
||||
const nameStateString = buildNameStateConcat(name, stateString);
|
||||
switch (this.config.layout) {
|
||||
case 'icon_name_state':
|
||||
case 'name_state':
|
||||
return this._gridHtml(state, configState, this.config.layout, color, nameStateString, undefined);
|
||||
default:
|
||||
return this._gridHtml(state, configState, this.config.layout, color, name, stateString);
|
||||
}
|
||||
}
|
||||
_gridHtml(state, configState, containerClass, color, name, stateString) {
|
||||
const iconTemplate = this._getIconHtml(state, configState, color);
|
||||
const itemClass = ['container', containerClass];
|
||||
if (!iconTemplate) itemClass.push('no-icon');
|
||||
if (!name) itemClass.push('no-name');
|
||||
if (!stateString) itemClass.push('no-state');
|
||||
return html`
|
||||
<ha-card class="button-card-main ${this.isClickable(state) ? '' : 'disabled'}" style=${styleMap(style)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this.buttonContent(state, configState, color)}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
<div class=${itemClass.join(' ')}>
|
||||
${iconTemplate ? iconTemplate : ''}
|
||||
${name ? html`<div class="name">${name}</div>` : ''}
|
||||
${stateString ? html`<div class="state">${stateString}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
_getIconHtml(state, configState, color) {
|
||||
const icon = this._buildIcon(state, configState);
|
||||
const entityPicture = this._buildEntityPicture(state, configState);
|
||||
const entityPictureStyleFromConfig = this._buildEntityPictureStyle(state, configState);
|
||||
const haIconStyle = {
|
||||
color,
|
||||
width: this.config.size,
|
||||
'min-width': this.config.size
|
||||
};
|
||||
const entityPictureStyle = Object.assign({}, haIconStyle, entityPictureStyleFromConfig);
|
||||
if (icon || entityPicture) {
|
||||
return html`
|
||||
<div class="img-cell">
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconStyle)}
|
||||
.icon="${icon}" class="icon" ?rotating=${this._rotate(configState)}></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureStyle)}
|
||||
class="icon" ?rotating=${this._rotate(configState)} />` : ''}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
setConfig(config) {
|
||||
if (!config) {
|
||||
throw new Error('Invalid configuration');
|
||||
}
|
||||
this.config = Object.assign({ tap_action: { action: 'toggle' }, hold_action: { action: 'none' }, size: '40%', color_type: 'icon', show_name: true, show_state: false, show_icon: true, show_units: true, show_entity_picture: false }, config);
|
||||
this.config = Object.assign({ tap_action: { action: 'toggle' }, hold_action: { action: 'none' }, layout: 'vertical', size: '40%', color_type: 'icon', show_name: true, show_state: false, show_icon: true, show_units: true, show_entity_picture: false }, config);
|
||||
this.config.default_color = 'var(--primary-text-color)';
|
||||
if (this.config.color_type !== 'icon') {
|
||||
this.config.color_off = 'var(--paper-card-background-color)';
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -44,25 +44,14 @@ class ButtonCard extends LitElement {
|
|||
if (!this.config || !this.hass) {
|
||||
return html``;
|
||||
}
|
||||
const state = this.config.entity ? this.hass.states[this.config.entity] : undefined;
|
||||
const configState = this.testConfigState(state);
|
||||
switch (this.config.color_type) {
|
||||
case 'blank-card':
|
||||
return this.blankCardColoredHtml(state);
|
||||
case 'label-card':
|
||||
case 'card':
|
||||
return this.cardColoredHtml(state, configState);
|
||||
case 'icon':
|
||||
default:
|
||||
return this.iconColoredHtml(state, configState);
|
||||
}
|
||||
return this._cardHtml();
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
return hasConfigOrEntityChanged(this, changedProps);
|
||||
}
|
||||
|
||||
private testConfigState(state: HassEntity | undefined): StateConfig | undefined {
|
||||
private _getMatchingConfigState(state: HassEntity | undefined): StateConfig | undefined {
|
||||
if (!state || !this.config!.state) {
|
||||
return undefined;
|
||||
}
|
||||
|
@ -104,7 +93,7 @@ class ButtonCard extends LitElement {
|
|||
return retval;
|
||||
}
|
||||
|
||||
private getDefaultColorForState(state: HassEntity): string {
|
||||
private _getDefaultColorForState(state: HassEntity): string {
|
||||
switch (state.state) {
|
||||
case 'on':
|
||||
return this.config!.color_on;
|
||||
|
@ -115,7 +104,7 @@ class ButtonCard extends LitElement {
|
|||
}
|
||||
}
|
||||
|
||||
private buildCssColorAttribute(
|
||||
private _buildCssColorAttribute(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): string {
|
||||
let colorValue: string = '';
|
||||
|
@ -136,10 +125,10 @@ class ButtonCard extends LitElement {
|
|||
}
|
||||
} else if (state.attributes.brightness) {
|
||||
color = applyBrightnessToColor(
|
||||
this.getDefaultColorForState(state), (state.attributes.brightness + 245) / 5,
|
||||
this._getDefaultColorForState(state), (state.attributes.brightness + 245) / 5,
|
||||
);
|
||||
} else {
|
||||
color = this.getDefaultColorForState(state);
|
||||
color = this._getDefaultColorForState(state);
|
||||
}
|
||||
} else {
|
||||
color = this.config!.default_color;
|
||||
|
@ -147,14 +136,14 @@ class ButtonCard extends LitElement {
|
|||
} else if (colorValue) {
|
||||
color = colorValue;
|
||||
} else if (state) {
|
||||
color = this.getDefaultColorForState(state);
|
||||
color = this._getDefaultColorForState(state);
|
||||
} else {
|
||||
color = this.config!.default_color;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
private buildIcon(
|
||||
private _buildIcon(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): string | undefined {
|
||||
if (!this.config!.show_icon) {
|
||||
|
@ -173,7 +162,7 @@ class ButtonCard extends LitElement {
|
|||
return icon;
|
||||
}
|
||||
|
||||
private buildEntityPicture(
|
||||
private _buildEntityPicture(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): string | undefined {
|
||||
if (!this.config!.show_entity_picture
|
||||
|
@ -192,7 +181,7 @@ class ButtonCard extends LitElement {
|
|||
return entityPicture;
|
||||
}
|
||||
|
||||
private buildStyle(
|
||||
private _buildStyle(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): StyleInfo {
|
||||
let cardStyle: StyleInfo = {};
|
||||
|
@ -212,7 +201,7 @@ class ButtonCard extends LitElement {
|
|||
return cardStyle;
|
||||
}
|
||||
|
||||
private buildEntityPictureStyle(
|
||||
private _buildEntityPictureStyle(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): StyleInfo {
|
||||
let entityPictureStyle: StyleInfo = {};
|
||||
|
@ -232,7 +221,7 @@ class ButtonCard extends LitElement {
|
|||
return entityPictureStyle;
|
||||
}
|
||||
|
||||
private buildName(
|
||||
private _buildName(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): string | undefined {
|
||||
if (this.config!.show_name === false) {
|
||||
|
@ -250,10 +239,10 @@ class ButtonCard extends LitElement {
|
|||
return name;
|
||||
}
|
||||
|
||||
private buildStateString(state: HassEntity | undefined): string | undefined {
|
||||
private _buildStateString(state: HassEntity | undefined): string | undefined {
|
||||
let stateString: string | undefined;
|
||||
if (this.config!.show_state && state && state.state) {
|
||||
const units = this.buildUnits(state);
|
||||
const units = this._buildUnits(state);
|
||||
if (units) {
|
||||
stateString = `${state.state} ${units}`;
|
||||
} else {
|
||||
|
@ -263,7 +252,7 @@ class ButtonCard extends LitElement {
|
|||
return stateString;
|
||||
}
|
||||
|
||||
private buildUnits(state: HassEntity | undefined): string | undefined {
|
||||
private _buildUnits(state: HassEntity | undefined): string | undefined {
|
||||
let units: string | undefined;
|
||||
if (state) {
|
||||
if (this.config!.show_units) {
|
||||
|
@ -277,7 +266,7 @@ class ButtonCard extends LitElement {
|
|||
return units;
|
||||
}
|
||||
|
||||
private isClickable(state: HassEntity | undefined): boolean {
|
||||
private _isClickable(state: HassEntity | undefined): boolean {
|
||||
let clickable = true;
|
||||
if (this.config!.tap_action!.action === 'toggle' && this.config!.hold_action!.action === 'none'
|
||||
|| this.config!.hold_action!.action === 'toggle' && this.config!.tap_action!.action === 'none') {
|
||||
|
@ -304,151 +293,12 @@ class ButtonCard extends LitElement {
|
|||
return clickable;
|
||||
}
|
||||
|
||||
private rotate(configState: StateConfig | undefined): string {
|
||||
return configState && configState.spin ? 'rotating' : '';
|
||||
private _rotate(configState: StateConfig | undefined): Boolean {
|
||||
return configState && configState.spin ? true : false;
|
||||
}
|
||||
|
||||
private buttonContent(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined, color: string,
|
||||
): TemplateResult {
|
||||
const icon = this.buildIcon(state, configState);
|
||||
const name = this.buildName(state, configState);
|
||||
const stateString = this.buildStateString(state);
|
||||
const nameStateString = buildNameStateConcat(name, stateString);
|
||||
const entityPicture = this.buildEntityPicture(state, configState);
|
||||
const entityPictureStyle = this.buildEntityPictureStyle(state, configState);
|
||||
|
||||
const divTableCellStyles = { width: this.config!.size, height: 'auto' };
|
||||
const haIconInlineStyle = {
|
||||
color,
|
||||
width: this.config!.size,
|
||||
height: 'auto',
|
||||
};
|
||||
const haIconTableStyle = {
|
||||
...haIconInlineStyle,
|
||||
width: 'auto',
|
||||
'max-width': this.config!.size,
|
||||
};
|
||||
|
||||
const entityPictureInlineStyle = {
|
||||
...haIconInlineStyle,
|
||||
...entityPictureStyle,
|
||||
};
|
||||
const entityPictureTableStyle = {
|
||||
...haIconTableStyle,
|
||||
...entityPictureStyle,
|
||||
};
|
||||
|
||||
switch (this.config!.layout) {
|
||||
case 'icon_name_state':
|
||||
return html`
|
||||
<div class='divTable'>
|
||||
<div class='divTableBody'>
|
||||
<div class='divTableRow'>
|
||||
<div class='divTableCell' style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${nameStateString ? html`<div class="divTableCell">${nameStateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'icon_name':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${stateString !== undefined ? html`<div>${stateString}</div>` : ''}
|
||||
`;
|
||||
case 'icon_state':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${name ? html`<div>${name}</div>` : ''}
|
||||
`;
|
||||
case 'icon_state_name2nd':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined && name ? html`<div class="divTableCell">${stateString}<br />${name}</div>` : ''}
|
||||
${!stateString && name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
${stateString && !name ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'icon_name_state2nd':
|
||||
return html`
|
||||
<div class="divTable">
|
||||
<div class="divTableBody">
|
||||
<div class="divTableRow">
|
||||
<div class="divTableCell" style=${styleMap(divTableCellStyles)}>
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconTableStyle)}
|
||||
icon="${icon}" class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureTableStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
</div>
|
||||
${stateString !== undefined && name ? html`<div class="divTableCell">${name}<br />${stateString}</div>` : ''}
|
||||
${!stateString && name ? html`<div class="divTableCell">${name}</div>` : ''}
|
||||
${stateString && !name ? html`<div class="divTableCell">${stateString}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
case 'name_state':
|
||||
return html`
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconInlineStyle)}
|
||||
icon=${icon} class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureInlineStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
${nameStateString ? html`<div>${nameStateString}</div>` : ''}
|
||||
`;
|
||||
case 'vertical':
|
||||
default:
|
||||
return html`
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconInlineStyle)}
|
||||
icon=${icon} class="${this.rotate(configState)}"></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureInlineStyle)}
|
||||
class="${this.rotate(configState)}" />` : ''}
|
||||
${name ? html`<div>${name}</div>` : ''}
|
||||
${stateString ? html`<div>${stateString}</div>` : ''}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
private blankCardColoredHtml(state: HassEntity | undefined): TemplateResult {
|
||||
const color = this.buildCssColorAttribute(state, undefined);
|
||||
private _blankCardColoredHtml(state: HassEntity | undefined): TemplateResult {
|
||||
const color = this._buildCssColorAttribute(state, undefined);
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
return html`
|
||||
<ha-card class="disabled">
|
||||
|
@ -457,35 +307,117 @@ class ButtonCard extends LitElement {
|
|||
`;
|
||||
}
|
||||
|
||||
private cardColoredHtml(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
): TemplateResult {
|
||||
const color = this.buildCssColorAttribute(state, configState);
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
const style = {
|
||||
color: fontColor,
|
||||
'background-color': color,
|
||||
...this.buildStyle(state, configState),
|
||||
};
|
||||
private _cardHtml(): TemplateResult {
|
||||
const state = this.config!.entity ? this.hass!.states[this.config!.entity] : undefined;
|
||||
const configState = this._getMatchingConfigState(state);
|
||||
const color = this._buildCssColorAttribute(state, configState);
|
||||
let buttonColor = color;
|
||||
let cardStyle: StyleInfo = {};
|
||||
const configCardStyle = this._buildStyle(state, configState);
|
||||
|
||||
switch (this.config!.color_type) {
|
||||
case 'blank-card':
|
||||
return this._blankCardColoredHtml(state);
|
||||
case 'card':
|
||||
case 'label-card': {
|
||||
const fontColor = getFontColorBasedOnBackgroundColor(color);
|
||||
cardStyle.color = fontColor;
|
||||
cardStyle['background-color'] = color;
|
||||
cardStyle = { ...cardStyle, ...configCardStyle };
|
||||
buttonColor = 'inherit';
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cardStyle = configCardStyle;
|
||||
break;
|
||||
}
|
||||
if (configCardStyle.width) {
|
||||
this.style.setProperty('flex', '0 0 auto');
|
||||
this.style.setProperty('max-width', 'fit-content');
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-card class="button-card-main ${this.isClickable(state) ? '' : 'disabled'}" style=${styleMap(style)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this.buttonContent(state, configState, 'inherit')}
|
||||
<ha-card class="button-card-main ${this._isClickable(state) ? '' : 'disabled'}" style=${styleMap(cardStyle)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this._buttonContent(state, configState, buttonColor)}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
private iconColoredHtml(
|
||||
state: HassEntity | undefined, configState: StateConfig | undefined,
|
||||
private _buttonContent(
|
||||
state: HassEntity | undefined,
|
||||
configState: StateConfig | undefined,
|
||||
color: string,
|
||||
): TemplateResult {
|
||||
const color = this.buildCssColorAttribute(state, configState);
|
||||
const style = this.buildStyle(state, configState);
|
||||
const name = this._buildName(state, configState);
|
||||
const stateString = this._buildStateString(state);
|
||||
const nameStateString = buildNameStateConcat(name, stateString);
|
||||
|
||||
switch (this.config!.layout) {
|
||||
case 'icon_name_state':
|
||||
case 'name_state':
|
||||
return this._gridHtml(state, configState, this.config!.layout, color,
|
||||
nameStateString, undefined);
|
||||
default:
|
||||
return this._gridHtml(state, configState, this.config!.layout, color,
|
||||
name, stateString);
|
||||
}
|
||||
}
|
||||
|
||||
private _gridHtml(
|
||||
state: HassEntity | undefined,
|
||||
configState: StateConfig | undefined,
|
||||
containerClass: string,
|
||||
color: string,
|
||||
name: string | undefined,
|
||||
stateString: string | undefined,
|
||||
): TemplateResult {
|
||||
const iconTemplate = this._getIconHtml(state, configState, color);
|
||||
const itemClass: string[] = ['container', containerClass];
|
||||
if (!iconTemplate) itemClass.push('no-icon');
|
||||
if (!name) itemClass.push('no-name');
|
||||
if (!stateString) itemClass.push('no-state');
|
||||
|
||||
return html`
|
||||
<ha-card class="button-card-main ${this.isClickable(state) ? '' : 'disabled'}" style=${styleMap(style)} @ha-click="${this._handleTap}" @ha-hold="${this._handleHold}" .longpress="${longPress()}" .config="${this.config}">
|
||||
${this.buttonContent(state, configState, color)}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
<div class=${itemClass.join(' ')}>
|
||||
${iconTemplate ? iconTemplate : ''}
|
||||
${name ? html`<div class="name">${name}</div>` : ''}
|
||||
${stateString ? html`<div class="state">${stateString}</div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _getIconHtml(
|
||||
state: HassEntity | undefined,
|
||||
configState: StateConfig | undefined,
|
||||
color: string,
|
||||
): TemplateResult | undefined {
|
||||
const icon = this._buildIcon(state, configState);
|
||||
const entityPicture = this._buildEntityPicture(state, configState);
|
||||
const entityPictureStyleFromConfig = this._buildEntityPictureStyle(state, configState);
|
||||
|
||||
const haIconStyle = {
|
||||
color,
|
||||
width: this.config!.size,
|
||||
'min-width': this.config!.size,
|
||||
};
|
||||
const entityPictureStyle = {
|
||||
...haIconStyle,
|
||||
...entityPictureStyleFromConfig,
|
||||
};
|
||||
|
||||
if (icon || entityPicture) {
|
||||
return html`
|
||||
<div class="img-cell">
|
||||
${icon && !entityPicture ? html`<ha-icon style=${styleMap(haIconStyle)}
|
||||
.icon="${icon}" class="icon" ?rotating=${this._rotate(configState)}></ha-icon>` : ''}
|
||||
${entityPicture ? html`<img src="${entityPicture}" style=${styleMap(entityPictureStyle)}
|
||||
class="icon" ?rotating=${this._rotate(configState)} />` : ''}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public setConfig(config: ButtonCardConfig): void {
|
||||
|
@ -496,6 +428,7 @@ class ButtonCard extends LitElement {
|
|||
this.config = {
|
||||
tap_action: { action: 'toggle' },
|
||||
hold_action: { action: 'none' },
|
||||
layout: 'vertical',
|
||||
size: '40%',
|
||||
color_type: 'icon',
|
||||
show_name: true,
|
||||
|
|
134
src/styles.ts
134
src/styles.ts
|
@ -24,27 +24,10 @@ export const styles = css`
|
|||
letter-spacing: normal;
|
||||
width: 100%;
|
||||
}
|
||||
div.divTable{
|
||||
display: table;
|
||||
overflow: auto;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
div.divTableBody {
|
||||
display: table-row-group;
|
||||
}
|
||||
div.divTableRow {
|
||||
display: table-row;
|
||||
}
|
||||
.divTableCell {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
div {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
min-width: 100%;
|
||||
}
|
||||
@keyframes blink{
|
||||
0%{opacity:0;}
|
||||
|
@ -79,13 +62,128 @@ export const styles = css`
|
|||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
.rotating {
|
||||
[rotating] {
|
||||
-webkit-animation: rotating 2s linear infinite;
|
||||
-moz-animation: rotating 2s linear infinite;
|
||||
-ms-animation: rotating 2s linear infinite;
|
||||
-o-animation: rotating 2s linear infinite;
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
max-height: 100%;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
.img-cell {
|
||||
grid-area: i;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
object-fit: scale;
|
||||
overflow: hidden;
|
||||
}
|
||||
.name {
|
||||
grid-area: n;
|
||||
max-width: 100%;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
/* margin: auto; */
|
||||
}
|
||||
.state {
|
||||
grid-area: s;
|
||||
max-width: 100%;
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
/* margin: auto; */
|
||||
}
|
||||
|
||||
.container.vertical {
|
||||
grid-template-areas: "i" "n" "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr min-content min-content;
|
||||
}
|
||||
.container.vertical.no-icon {
|
||||
grid-template-areas: "n" "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.vertical.no-icon .state {
|
||||
align-self: start;
|
||||
}
|
||||
.container.vertical.no-icon .name {
|
||||
align-self: end;
|
||||
}
|
||||
.container.vertical.no-icon.no-name {
|
||||
grid-template-areas: "s";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.container.vertical.no-icon.no-name .state {
|
||||
align-self: center;
|
||||
}
|
||||
.container.vertical.no-icon.no-state {
|
||||
grid-template-areas: "n";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.container.vertical.no-icon.no-state .name {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.container.icon_name_state {
|
||||
grid-template-areas: "i n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
|
||||
.container.icon_name {
|
||||
grid-template-areas: "i n" "s s";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.icon_state {
|
||||
grid-template-areas: "i s" "n n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.name_state {
|
||||
grid-template-areas: "i" "n";
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr min-content;
|
||||
}
|
||||
|
||||
.container.icon_name_state2nd {
|
||||
grid-template-areas: "i n" "i s";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.icon_name_state2nd .name {
|
||||
align-self: end;
|
||||
}
|
||||
.container.icon_name_state2nd .state {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.container.icon_state_name2nd {
|
||||
grid-template-areas: "i s" "i n";
|
||||
grid-template-columns: 40% 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
.container.icon_state_name2nd .state {
|
||||
align-self: end;
|
||||
}
|
||||
.container.icon_state_name2nd .name {
|
||||
align-self: start;
|
||||
}
|
||||
`;
|
||||
|
||||
export default styles;
|
||||
|
|
|
@ -28,7 +28,7 @@ export interface ButtonCardConfig {
|
|||
style?: CssStyleConfig[];
|
||||
state?: StateConfig[];
|
||||
confirmation?: string;
|
||||
layout?: 'vertical' | 'icon_name_state' | 'name_state' | 'icon_name' | 'icon_state' | 'icon_name_state2nd' | 'icon_state_name2nd';
|
||||
layout: 'vertical' | 'icon_name_state' | 'name_state' | 'icon_name' | 'icon_state' | 'icon_name_state2nd' | 'icon_state_name2nd';
|
||||
entity_picture_style?: CssStyleConfig[];
|
||||
|
||||
default_color: string;
|
||||
|
|
Loading…
Reference in New Issue