Use chips for button rows (#10770)

This commit is contained in:
Bram Kragten 2021-12-02 23:29:52 +01:00 committed by GitHub
parent 48d12ceafe
commit a580904c52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 129 additions and 50 deletions

View File

@ -14,11 +14,17 @@ import { customElement, property } from "lit/decorators";
export class HaChip extends LitElement { export class HaChip extends LitElement {
@property({ type: Boolean }) public hasIcon = false; @property({ type: Boolean }) public hasIcon = false;
@property({ type: Boolean }) public noText = false;
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
<div class="mdc-chip"> <div class="mdc-chip">
${this.hasIcon ${this.hasIcon
? html`<div class="mdc-chip__icon mdc-chip__icon--leading"> ? html`<div
class="mdc-chip__icon mdc-chip__icon--leading ${this.noText
? "no-text"
: ""}"
>
<slot name="icon"></slot> <slot name="icon"></slot>
</div>` </div>`
: null} : null}
@ -51,6 +57,10 @@ export class HaChip extends LitElement {
--mdc-icon-size: 20px; --mdc-icon-size: 20px;
color: var(--ha-chip-icon-color, var(--ha-chip-text-color)); color: var(--ha-chip-icon-color, var(--ha-chip-text-color));
} }
.mdc-chip
.mdc-chip__icon--leading:not(.mdc-chip__icon--leading-hidden).no-text {
margin-right: -4px;
}
`; `;
} }
} }

View File

@ -134,7 +134,10 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
} }
if (this._config.header) { if (this._config.header) {
this._headerElement = createHeaderFooterElement(this._config.header); this._headerElement = createHeaderFooterElement(
this._config.header
) as LovelaceHeaderFooter;
this._headerElement.type = "header";
if (this._hass) { if (this._hass) {
this._headerElement.hass = this._hass; this._headerElement.hass = this._hass;
} }
@ -143,7 +146,10 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
} }
if (this._config.footer) { if (this._config.footer) {
this._footerElement = createHeaderFooterElement(this._config.footer); this._footerElement = createHeaderFooterElement(
this._config.footer
) as LovelaceHeaderFooter;
this._footerElement.type = "footer";
if (this._hass) { if (this._hass) {
this._footerElement.hass = this._hass; this._footerElement.hass = this._hass;
} }

View File

@ -9,6 +9,8 @@ import { computeTooltip } from "../common/compute-tooltip";
import { actionHandler } from "../common/directives/action-handler-directive"; import { actionHandler } from "../common/directives/action-handler-directive";
import { handleAction } from "../common/handle-action"; import { handleAction } from "../common/handle-action";
import { hasAction } from "../common/has-action"; import { hasAction } from "../common/has-action";
import "../../../components/ha-chip";
import { haStyleScrollbar } from "../../../resources/styles";
@customElement("hui-buttons-base") @customElement("hui-buttons-base")
export class HuiButtonsBase extends LitElement { export class HuiButtonsBase extends LitElement {
@ -18,40 +20,46 @@ export class HuiButtonsBase extends LitElement {
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
${(this.configEntities || []).map((entityConf) => { <div class="ha-scrollbar">
const stateObj = this.hass.states[entityConf.entity]; ${(this.configEntities || []).map((entityConf) => {
const stateObj = this.hass.states[entityConf.entity];
return html` const name =
<div (entityConf.show_name && stateObj) ||
@action=${this._handleAction} (entityConf.name && entityConf.show_name !== false)
.actionHandler=${actionHandler({ ? entityConf.name || computeStateName(stateObj)
hasHold: hasAction(entityConf.hold_action), : "";
hasDoubleClick: hasAction(entityConf.double_tap_action),
})} return html`
.config=${entityConf} <ha-chip
tabindex="0" @action=${this._handleAction}
> .actionHandler=${actionHandler({
${entityConf.show_icon !== false hasHold: hasAction(entityConf.hold_action),
? html` hasDoubleClick: hasAction(entityConf.double_tap_action),
<state-badge })}
title=${computeTooltip(this.hass, entityConf)} .config=${entityConf}
.hass=${this.hass} tabindex="0"
.stateObj=${stateObj} .hasIcon=${entityConf.show_icon !== false}
.overrideIcon=${entityConf.icon} .noText=${!name}
.overrideImage=${entityConf.image} >
stateColor ${entityConf.show_icon !== false
></state-badge> ? html`
` <state-badge
: ""} title=${computeTooltip(this.hass, entityConf)}
<span> .hass=${this.hass}
${(entityConf.show_name && stateObj) || .stateObj=${stateObj}
(entityConf.name && entityConf.show_name !== false) .overrideIcon=${entityConf.icon}
? entityConf.name || computeStateName(stateObj) .overrideImage=${entityConf.image}
stateColor
slot="icon"
></state-badge>
`
: ""} : ""}
</span> ${name}
</div> </ha-chip>
`; `;
})} })}
</div>
`; `;
} }
@ -61,20 +69,36 @@ export class HuiButtonsBase extends LitElement {
} }
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return [
:host { haStyleScrollbar,
display: flex; css`
justify-content: space-evenly; .ha-scrollbar {
flex-wrap: wrap; padding: 8px;
padding: 0 8px; padding-top: var(--padding-top, 8px);
} padding-bottom: var(--padding-bottom, 8px);
div { width: 100%;
cursor: pointer; overflow-x: auto;
align-items: center; overflow-y: hidden;
display: inline-flex; white-space: nowrap;
outline: none; box-sizing: border-box;
} display: flex;
`; flex-wrap: wrap;
}
state-badge {
line-height: inherit;
text-align: start;
color: var(--secondary-text-color);
}
ha-chip {
padding: 4px;
}
@media all and (max-width: 450px), all and (max-height: 500px) {
.ha-scrollbar {
flex-wrap: nowrap;
}
}
`,
];
} }
} }

View File

@ -1,4 +1,5 @@
import { html, LitElement, TemplateResult } from "lit"; import { css, html, LitElement, TemplateResult } from "lit";
import { classMap } from "lit/directives/class-map";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { computeDomain } from "../../../common/entity/compute_domain"; import { computeDomain } from "../../../common/entity/compute_domain";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
@ -19,6 +20,8 @@ export class HuiButtonsHeaderFooter
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass?: HomeAssistant;
@property() public type!: "header" | "footer";
@state() private _configEntities?: EntityConfig[]; @state() private _configEntities?: EntityConfig[];
public getCardSize(): number { public getCardSize(): number {
@ -47,12 +50,43 @@ export class HuiButtonsHeaderFooter
protected render(): TemplateResult | void { protected render(): TemplateResult | void {
return html` return html`
${this.type === "footer"
? html`<li class="divider footer" role="separator"></li>`
: ""}
<hui-buttons-base <hui-buttons-base
.hass=${this.hass} .hass=${this.hass}
.configEntities=${this._configEntities} .configEntities=${this._configEntities}
class=${classMap({
footer: this.type === "footer",
header: this.type === "header",
})}
></hui-buttons-base> ></hui-buttons-base>
${this.type === "header"
? html`<li class="divider header" role="separator"></li>`
: ""}
`; `;
} }
static styles = css`
.divider {
height: 0;
margin: 16px 0;
list-style-type: none;
border: none;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: var(--divider-color);
}
.divider.header {
margin-top: 0;
}
hui-buttons-base.footer {
--padding-bottom: 16px;
}
hui-buttons-base.header {
--padding-top: 16px;
}
`;
} }
declare global { declare global {

View File

@ -60,6 +60,8 @@ export class HuiGraphHeaderFooter
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass?: HomeAssistant;
@property() public type!: "header" | "footer";
@property() protected _config?: GraphHeaderFooterConfig; @property() protected _config?: GraphHeaderFooterConfig;
@state() private _coordinates?: number[][]; @state() private _coordinates?: number[][];

View File

@ -34,6 +34,8 @@ export class HuiPictureHeaderFooter
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass?: HomeAssistant;
@property() public type!: "header" | "footer";
@property() protected _config?: PictureHeaderFooterConfig; @property() protected _config?: PictureHeaderFooterConfig;
public getCardSize(): number { public getCardSize(): number {

View File

@ -68,6 +68,7 @@ export interface LovelaceRowConstructor extends Constructor<LovelaceRow> {
export interface LovelaceHeaderFooter extends HTMLElement { export interface LovelaceHeaderFooter extends HTMLElement {
hass?: HomeAssistant; hass?: HomeAssistant;
type: "header" | "footer";
getCardSize(): number | Promise<number>; getCardSize(): number | Promise<number>;
setConfig(config: LovelaceHeaderFooterConfig): void; setConfig(config: LovelaceHeaderFooterConfig): void;
} }