Skip to content

Commit

Permalink
Add categories, filtering, grouping to automation panel (#20197)
Browse files Browse the repository at this point in the history
* Add categories and filtering to automation panel

* Update search-input-outlined.ts

* Update ha-config-entities.ts

* fix resetting area filter

* fixes

* Update ha-category-picker.ts

* Update ha-filter-blueprints.ts

* fix updating badge

* fix overflow issue
  • Loading branch information
bramkragten authored Mar 27, 2024
1 parent 141c8c5 commit 68935d4
Show file tree
Hide file tree
Showing 37 changed files with 3,843 additions and 732 deletions.
2 changes: 2 additions & 0 deletions demo/src/ha-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class HaDemo extends HomeAssistantAppEl {
name: null,
icon: null,
labels: [],
categories: {},
platform: "co2signal",
hidden_by: null,
entity_category: null,
Expand All @@ -90,6 +91,7 @@ export class HaDemo extends HomeAssistantAppEl {
name: null,
icon: null,
labels: [],
categories: {},
platform: "co2signal",
hidden_by: null,
entity_category: null,
Expand Down
1 change: 1 addition & 0 deletions gallery/src/pages/misc/integration-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ const createEntityRegistryEntries = (
unique_id: "updater",
options: null,
labels: [],
categories: {},
},
];

Expand Down
49 changes: 47 additions & 2 deletions src/components/chips/ha-assist-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@ import { css, html } from "lit";
import { customElement, property } from "lit/decorators";

@customElement("ha-assist-chip")
// @ts-ignore
export class HaAssistChip extends MdAssistChip {
@property({ type: Boolean, reflect: true }) filled = false;

@property({ type: Boolean }) active = false;

static override styles = [
...super.styles,
css`
:host {
--md-sys-color-primary: var(--primary-text-color);
--md-sys-color-on-surface: var(--primary-text-color);
--md-assist-chip-container-shape: 16px;
--md-assist-chip-container-shape: var(
--ha-assist-chip-container-shape,
16px
);
--md-assist-chip-outline-color: var(--outline-color);
--md-assist-chip-label-text-weight: 400;
--ha-assist-chip-filled-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
--ha-assist-chip-active-container-color: rgba(
var(--rgb-primary-color),
0.15
);
}
/** Material 3 doesn't have a filled chip, so we have to make our own **/
.filled {
Expand All @@ -31,10 +41,21 @@ export class HaAssistChip extends MdAssistChip {
background-color: var(--ha-assist-chip-filled-container-color);
}
/** Set the size of mdc icons **/
::slotted([slot="icon"]) {
::slotted([slot="icon"]),
::slotted([slot="trailingIcon"]) {
display: flex;
--mdc-icon-size: var(--md-input-chip-icon-size, 18px);
}
.trailing.icon ::slotted(*),
.trailing.icon svg {
margin-inline-end: unset;
margin-inline-start: var(--_icon-label-space);
}
:where(.active)::before {
background: var(--ha-assist-chip-active-container-color);
opacity: var(--ha-assist-chip-active-container-opacity);
}
`,
];

Expand All @@ -45,6 +66,30 @@ export class HaAssistChip extends MdAssistChip {

return super.renderOutline();
}

protected override getContainerClasses() {
return {
...super.getContainerClasses(),
active: this.active,
};
}

protected override renderPrimaryContent() {
return html`
<span class="leading icon" aria-hidden="true">
${this.renderLeadingIcon()}
</span>
<span class="label">${this.label}</span>
<span class="touch"></span>
<span class="trailing leading icon" aria-hidden="true">
${this.renderTrailingIcon()}
</span>
`;
}

protected renderTrailingIcon() {
return html`<slot name="trailing-icon"></slot>`;
}
}

declare global {
Expand Down
118 changes: 118 additions & 0 deletions src/components/data-table/ha-data-table-labels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { css, html, LitElement, nothing, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../chips/ha-assist-chip";
import { repeat } from "lit/directives/repeat";
import { LabelRegistryEntry } from "../../data/label_registry";
import { computeCssColor } from "../../common/color/compute-color";
import { fireEvent } from "../../common/dom/fire_event";

@customElement("ha-data-table-labels")
class HaDataTableLabels extends LitElement {
@property({ attribute: false }) public labels!: LabelRegistryEntry[];

protected render(): TemplateResult {
return html`
<ha-chip-set>
${repeat(
this.labels.slice(0, 2),
(label) => label.label_id,
(label) => this._renderLabel(label, true)
)}
${this.labels.length > 2
? html`<ha-button-menu
absolute
@click=${this._handleIconOverflowMenuOpened}
@closed=${this._handleIconOverflowMenuClosed}
>
<ha-assist-chip
slot="trigger"
.label=${`+${this.labels.length - 2}`}
></ha-assist-chip>
${repeat(
this.labels.slice(2),
(label) => label.label_id,
(label) =>
html`<ha-list-item
@click=${this._labelClicked}
.item=${label}
>
${this._renderLabel(label, false)}
</ha-list-item>`
)}
</ha-button-menu>`
: nothing}
</ha-chip-set>
`;
}

private _renderLabel(label: LabelRegistryEntry, clickAction: boolean) {
const color = label?.color ? computeCssColor(label.color) : undefined;
return html`<ha-assist-chip
.item=${label}
@click=${clickAction ? this._labelClicked : undefined}
.label=${label?.name}
active
style=${color ? `--color: ${color}` : ""}
>
${label?.icon
? html`<ha-icon slot="icon" .icon=${label.icon}></ha-icon>`
: nothing}
</ha-assist-chip>`;
}

private _labelClicked(ev: Event) {
const label = (ev.currentTarget as any).item as LabelRegistryEntry;
fireEvent(this, "label-clicked", { label });
}

protected _handleIconOverflowMenuOpened(e) {
e.stopPropagation();
// If this component is used inside a data table, the z-index of the row
// needs to be increased. Otherwise the ha-button-menu would be displayed
// underneath the next row in the table.
const row = this.closest(".mdc-data-table__row") as HTMLDivElement | null;
if (row) {
row.style.zIndex = "1";
}
}

protected _handleIconOverflowMenuClosed() {
const row = this.closest(".mdc-data-table__row") as HTMLDivElement | null;
if (row) {
row.style.zIndex = "";
}
}

static get styles() {
return css`
:host {
display: block;
flex-grow: 1;
margin-top: 4px;
height: 22px;
}
ha-chip-set {
position: fixed;
flex-wrap: nowrap;
}
ha-assist-chip {
border: 1px solid var(--color);
--md-assist-chip-icon-size: 16px;
--md-assist-chip-container-height: 20px;
--md-assist-chip-leading-space: 12px;
--md-assist-chip-trailing-space: 12px;
--ha-assist-chip-active-container-color: var(--color);
--ha-assist-chip-active-container-opacity: 0.3;
}
`;
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-data-table-labels": HaDataTableLabels;
}
interface HASSDomEvents {
"label-clicked": { label: LabelRegistryEntry };
}
}
Loading

0 comments on commit 68935d4

Please sign in to comment.