mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 09:56:36 +00:00
Improve search and filters on mobile + fix close button in search field (#11662)
Co-authored-by: Zack <zackbarett@hey.com>
This commit is contained in:
parent
35cc291118
commit
a9bfea233c
@ -14,6 +14,9 @@ class SearchInput extends LitElement {
|
|||||||
|
|
||||||
@property() public filter?: string;
|
@property() public filter?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
public suffix = false;
|
||||||
|
|
||||||
@property({ type: Boolean })
|
@property({ type: Boolean })
|
||||||
public autofocus = false;
|
public autofocus = false;
|
||||||
|
|
||||||
@ -33,7 +36,7 @@ class SearchInput extends LitElement {
|
|||||||
.label=${this.label || "Search"}
|
.label=${this.label || "Search"}
|
||||||
.value=${this.filter || ""}
|
.value=${this.filter || ""}
|
||||||
.icon=${true}
|
.icon=${true}
|
||||||
.iconTrailing=${this.filter}
|
.iconTrailing=${this.filter || this.suffix}
|
||||||
@input=${this._filterInputChanged}
|
@input=${this._filterInputChanged}
|
||||||
>
|
>
|
||||||
<slot name="prefix" slot="leadingIcon">
|
<slot name="prefix" slot="leadingIcon">
|
||||||
@ -43,16 +46,18 @@ class SearchInput extends LitElement {
|
|||||||
.path=${mdiMagnify}
|
.path=${mdiMagnify}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
</slot>
|
</slot>
|
||||||
|
<div class="trailing" slot="trailingIcon">
|
||||||
${this.filter &&
|
${this.filter &&
|
||||||
html`
|
html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
slot="trailingIcon"
|
|
||||||
@click=${this._clearSearch}
|
@click=${this._clearSearch}
|
||||||
.label=${this.hass.localize("ui.common.clear")}
|
.label=${this.hass.localize("ui.common.clear")}
|
||||||
.path=${mdiClose}
|
.path=${mdiClose}
|
||||||
class="clear-button"
|
class="clear-button"
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`}
|
`}
|
||||||
|
<slot name="suffix"></slot>
|
||||||
|
</div>
|
||||||
</ha-textfield>
|
</ha-textfield>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -81,15 +86,16 @@ class SearchInput extends LitElement {
|
|||||||
ha-svg-icon {
|
ha-svg-icon {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
ha-icon-button {
|
|
||||||
--mdc-icon-button-size: 24px;
|
|
||||||
}
|
|
||||||
.clear-button {
|
.clear-button {
|
||||||
--mdc-icon-size: 20px;
|
--mdc-icon-size: 20px;
|
||||||
}
|
}
|
||||||
ha-textfield {
|
ha-textfield {
|
||||||
display: inherit;
|
display: inherit;
|
||||||
}
|
}
|
||||||
|
.trailing {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ export class HaRelatedFilterButtonMenu extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this.value?.area}
|
.value=${this.value?.area}
|
||||||
no-add
|
no-add
|
||||||
|
.excludeDomains=${this.excludeDomains}
|
||||||
@value-changed=${this._areaPicked}
|
@value-changed=${this._areaPicked}
|
||||||
></ha-area-picker>
|
></ha-area-picker>
|
||||||
<ha-device-picker
|
<ha-device-picker
|
||||||
@ -81,6 +82,7 @@ export class HaRelatedFilterButtonMenu extends LitElement {
|
|||||||
)}
|
)}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this.value?.device}
|
.value=${this.value?.device}
|
||||||
|
.excludeDomains=${this.excludeDomains}
|
||||||
@value-changed=${this._devicePicked}
|
@value-changed=${this._devicePicked}
|
||||||
></ha-device-picker>
|
></ha-device-picker>
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
@ -103,7 +105,8 @@ export class HaRelatedFilterButtonMenu extends LitElement {
|
|||||||
this._open = true;
|
this._open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onClosed(): void {
|
private _onClosed(ev): void {
|
||||||
|
ev.stopPropagation();
|
||||||
this._open = false;
|
this._open = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,9 +176,7 @@ export class HaRelatedFilterButtonMenu extends LitElement {
|
|||||||
:host {
|
:host {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
--mdc-menu-min-width: 200px;
|
||||||
:host([narrow]) {
|
|
||||||
position: static;
|
|
||||||
}
|
}
|
||||||
ha-area-picker,
|
ha-area-picker,
|
||||||
ha-device-picker,
|
ha-device-picker,
|
||||||
@ -186,7 +187,8 @@ export class HaRelatedFilterButtonMenu extends LitElement {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
:host([narrow]) ha-area-picker,
|
:host([narrow]) ha-area-picker,
|
||||||
:host([narrow]) ha-device-picker {
|
:host([narrow]) ha-device-picker,
|
||||||
|
:host([narrow]) ha-entity-picker {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -68,6 +68,14 @@ export class HaTextField extends TextFieldBase {
|
|||||||
:host([no-spinner]) input[type="number"] {
|
:host([no-spinner]) input[type="number"] {
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mdc-text-field__ripple {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdc-text-field {
|
||||||
|
overflow: var(--text-field-overflow);
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import "@material/mwc-button/mwc-button";
|
import "@material/mwc-button/mwc-button";
|
||||||
import { mdiFilterVariant } from "@mdi/js";
|
|
||||||
import "@polymer/paper-tooltip/paper-tooltip";
|
import "@polymer/paper-tooltip/paper-tooltip";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, query } from "lit/decorators";
|
import { customElement, property, query } from "lit/decorators";
|
||||||
@ -159,28 +158,25 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
const headerToolbar = html`<search-input
|
const headerToolbar = html`<search-input
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.filter=${this.filter}
|
.filter=${this.filter}
|
||||||
|
.suffix=${!this.narrow}
|
||||||
@value-changed=${this._handleSearchChange}
|
@value-changed=${this._handleSearchChange}
|
||||||
.label=${this.searchLabel ||
|
.label=${this.searchLabel ||
|
||||||
this.hass.localize("ui.components.data-table.search")}
|
this.hass.localize("ui.components.data-table.search")}
|
||||||
>
|
>
|
||||||
</search-input>
|
${!this.narrow
|
||||||
<div class="filters">
|
? html`<div class="filters" slot="suffix">
|
||||||
${filterInfo
|
${filterInfo
|
||||||
? html`<div class="active-filters">
|
? html`<div class="active-filters">
|
||||||
${this.narrow
|
|
||||||
? html`<div>
|
|
||||||
<ha-svg-icon .path=${mdiFilterVariant}></ha-svg-icon>
|
|
||||||
<paper-tooltip animation-delay="0" position="left">
|
|
||||||
${filterInfo}
|
${filterInfo}
|
||||||
</paper-tooltip>
|
|
||||||
</div>`
|
|
||||||
: filterInfo}
|
|
||||||
<mwc-button @click=${this._clearFilter}>
|
<mwc-button @click=${this._clearFilter}>
|
||||||
${this.hass.localize("ui.components.data-table.clear")}
|
${this.hass.localize("ui.components.data-table.clear")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
</div>`
|
</div>`
|
||||||
: ""}<slot name="filter-menu"></slot>
|
: ""}
|
||||||
</div>`;
|
<slot name="filter-menu"></slot>
|
||||||
|
</div>`
|
||||||
|
: ""}
|
||||||
|
</search-input>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
@ -195,7 +191,16 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
.mainPage=${this.mainPage}
|
.mainPage=${this.mainPage}
|
||||||
.supervisor=${this.supervisor}
|
.supervisor=${this.supervisor}
|
||||||
>
|
>
|
||||||
<div slot="toolbar-icon"><slot name="toolbar-icon"></slot></div>
|
<div slot="toolbar-icon">
|
||||||
|
${this.narrow
|
||||||
|
? html`<div class="filter-menu">
|
||||||
|
<slot name="filter-menu"></slot>${this.numHidden ||
|
||||||
|
this.activeFilters
|
||||||
|
? html`<span class="badge">${this.numHidden || "!"}</span>`
|
||||||
|
: ""}
|
||||||
|
</div>`
|
||||||
|
: ""}<slot name="toolbar-icon"></slot>
|
||||||
|
</div>
|
||||||
${this.narrow
|
${this.narrow
|
||||||
? html`
|
? html`
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
@ -267,6 +272,12 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
}
|
}
|
||||||
|
search-input {
|
||||||
|
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||||
|
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||||
|
--text-field-overflow: visible;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
.table-header search-input {
|
.table-header search-input {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -276,15 +287,16 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
}
|
}
|
||||||
.search-toolbar search-input {
|
.search-toolbar search-input {
|
||||||
display: block;
|
display: block;
|
||||||
|
width: 100%;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
--mdc-text-field-fill-color: transparant;
|
|
||||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
|
||||||
--mdc-ripple-color: transparant;
|
--mdc-ripple-color: transparant;
|
||||||
}
|
}
|
||||||
.filters {
|
.filters {
|
||||||
|
--mdc-text-field-fill-color: initial;
|
||||||
|
--mdc-text-field-idle-line-color: initial;
|
||||||
|
--text-field-overflow: initial;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
width: 100%;
|
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
.active-filters {
|
.active-filters {
|
||||||
@ -295,6 +307,7 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
padding: 2px 2px 2px 8px;
|
padding: 2px 2px 2px 8px;
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
width: max-content;
|
||||||
}
|
}
|
||||||
.active-filters ha-svg-icon {
|
.active-filters ha-svg-icon {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
@ -313,6 +326,24 @@ export class HaTabsSubpageDataTable extends LitElement {
|
|||||||
left: 0;
|
left: 0;
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
|
.badge {
|
||||||
|
min-width: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-weight: 400;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0px 4px;
|
||||||
|
color: var(--text-primary-color);
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 4px;
|
||||||
|
font-size: 0.65em;
|
||||||
|
}
|
||||||
|
.filter-menu {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,7 @@ class HassTabsSubpage extends LitElement {
|
|||||||
ha-menu-button,
|
ha-menu-button,
|
||||||
ha-icon-button-arrow-prev,
|
ha-icon-button-arrow-prev,
|
||||||
::slotted([slot="toolbar-icon"]) {
|
::slotted([slot="toolbar-icon"]) {
|
||||||
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
color: var(--sidebar-icon-color);
|
color: var(--sidebar-icon-color);
|
||||||
|
@ -297,10 +297,12 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
this._filter
|
this._filter
|
||||||
);
|
);
|
||||||
|
|
||||||
const filterMenu = html`<ha-button-menu
|
const filterMenu = html`<div
|
||||||
|
slot=${ifDefined(this.narrow ? "toolbar-icon" : "suffix")}
|
||||||
|
>
|
||||||
|
<ha-button-menu
|
||||||
corner="BOTTOM_START"
|
corner="BOTTOM_START"
|
||||||
multi
|
multi
|
||||||
slot=${ifDefined(this.narrow ? "toolbar-icon" : undefined)}
|
|
||||||
@action=${this._handleMenuAction}
|
@action=${this._handleMenuAction}
|
||||||
>
|
>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
@ -319,7 +321,11 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
"ui.panel.config.integrations.disable.show_disabled"
|
"ui.panel.config.integrations.disable.show_disabled"
|
||||||
)}
|
)}
|
||||||
</ha-check-list-item>
|
</ha-check-list-item>
|
||||||
</ha-button-menu>`;
|
</ha-button-menu>
|
||||||
|
${!this._showDisabled && this.narrow && disabledCount
|
||||||
|
? html`<span class="badge">${disabledCount}</span>`
|
||||||
|
: ""}
|
||||||
|
</div>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage
|
<hass-tabs-subpage
|
||||||
@ -336,8 +342,6 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
class="header"
|
class="header"
|
||||||
no-label-float
|
|
||||||
no-underline
|
|
||||||
@value-changed=${this._handleSearchChange}
|
@value-changed=${this._handleSearchChange}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.integrations.search"
|
"ui.panel.config.integrations.search"
|
||||||
@ -350,16 +354,15 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
<div class="search">
|
<div class="search">
|
||||||
<search-input
|
<search-input
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
no-label-float
|
suffix
|
||||||
no-underline
|
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
@value-changed=${this._handleSearchChange}
|
@value-changed=${this._handleSearchChange}
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.integrations.search"
|
"ui.panel.config.integrations.search"
|
||||||
)}
|
)}
|
||||||
></search-input>
|
>
|
||||||
${!this._showDisabled && disabledCount
|
${!this._showDisabled && disabledCount
|
||||||
? html`<div class="active-filters">
|
? html`<div class="active-filters" slot="suffix">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.integrations.disable.disabled_integrations",
|
"ui.panel.config.integrations.disable.disabled_integrations",
|
||||||
{ number: disabledCount }
|
{ number: disabledCount }
|
||||||
@ -373,6 +376,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
</div>`
|
</div>`
|
||||||
: ""}
|
: ""}
|
||||||
${filterMenu}
|
${filterMenu}
|
||||||
|
</search-input>
|
||||||
</div>
|
</div>
|
||||||
`}
|
`}
|
||||||
|
|
||||||
@ -683,13 +687,15 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
.empty-message h1 {
|
.empty-message h1 {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
search-input {
|
||||||
|
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||||
|
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||||
|
--text-field-overflow: visible;
|
||||||
|
}
|
||||||
search-input.header {
|
search-input.header {
|
||||||
display: block;
|
display: block;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
--mdc-text-field-fill-color: transparant;
|
|
||||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
|
||||||
--mdc-ripple-color: transparant;
|
--mdc-ripple-color: transparant;
|
||||||
}
|
}
|
||||||
.search {
|
.search {
|
||||||
@ -717,6 +723,7 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2px 2px 2px 8px;
|
padding: 2px 2px 2px 8px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
width: max-content;
|
||||||
}
|
}
|
||||||
.active-filters mwc-button {
|
.active-filters mwc-button {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
@ -732,6 +739,21 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
left: 0;
|
left: 0;
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
|
.badge {
|
||||||
|
min-width: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-weight: 400;
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0px 4px;
|
||||||
|
color: var(--text-primary-color);
|
||||||
|
position: absolute;
|
||||||
|
right: 14px;
|
||||||
|
top: 8px;
|
||||||
|
font-size: 0.65em;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -105,10 +105,10 @@ export class HaConfigLogs extends LitElement {
|
|||||||
}
|
}
|
||||||
search-input {
|
search-input {
|
||||||
display: block;
|
display: block;
|
||||||
|
--mdc-text-field-fill-color: var(--sidebar-background-color);
|
||||||
|
--mdc-text-field-idle-line-color: var(--divider-color);
|
||||||
}
|
}
|
||||||
search-input.header {
|
search-input.header {
|
||||||
--mdc-text-field-fill-color: transparant;
|
|
||||||
--mdc-text-field-idle-line-color: var(--divider-color);
|
|
||||||
--mdc-ripple-color: transparant;
|
--mdc-ripple-color: transparant;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user