Replace clickable list item (#25165)

This commit is contained in:
Bram Kragten 2025-04-25 09:01:19 +02:00 committed by GitHub
parent 3a0c367f76
commit 0229f67751
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 58 additions and 144 deletions

View File

@ -1,61 +0,0 @@
import type { CSSResultGroup } from "lit";
import { css, html } from "lit";
import { customElement, property, query } from "lit/decorators";
import { HaListItem } from "./ha-list-item";
@customElement("ha-clickable-list-item")
export class HaClickableListItem extends HaListItem {
@property() public href?: string;
@property({ attribute: "disable-href", type: Boolean })
public disableHref = false;
@property({ attribute: "open-new-tab", type: Boolean, reflect: true })
public openNewTab = false;
@query("a") private _anchor!: HTMLAnchorElement;
public render() {
const r = super.render();
const href = this.href || "";
return html`${this.disableHref
? html`<a href="#" class="disabled">${r}</a>`
: html`<a target=${this.openNewTab ? "_blank" : ""} href=${href}
>${r}</a
>`}`;
}
firstUpdated() {
super.firstUpdated();
this.addEventListener("keydown", (ev) => {
if (ev.key === "Enter" || ev.key === " ") {
this._anchor.click();
}
});
}
static get styles(): CSSResultGroup {
return [
super.styles,
css`
a {
width: 100%;
height: 100%;
display: flex;
align-items: center;
overflow: hidden;
}
.disabled {
pointer-events: none;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-clickable-list-item": HaClickableListItem;
}
}

View File

@ -12,8 +12,7 @@ import "../../../components/buttons/ha-progress-button";
import "../../../components/chart/ha-chart-base";
import "../../../components/ha-alert";
import "../../../components/ha-card";
import "../../../components/ha-list";
import "../../../components/ha-clickable-list-item";
import "../../../components/ha-md-list-item";
import "../../../components/ha-icon-button";
import "../../../components/ha-icon-next";
import "../../../components/ha-settings-row";
@ -287,26 +286,24 @@ class HaConfigHardware extends SubscribeMixin(LitElement) {
</div>
${documentationURL
? html`
<ha-list>
<ha-clickable-list-item
.href=${documentationURL}
open-new-tab
twoline
hasMeta
<ha-md-list-item
.href=${documentationURL}
type="link"
target="_blank"
rel="noopener noreferrer"
>
<span
>${this.hass.localize(
"ui.panel.config.hardware.documentation"
)}</span
>
<span
>${this.hass.localize(
"ui.panel.config.hardware.documentation"
)}</span
>
<span slot="secondary"
>${this.hass.localize(
"ui.panel.config.hardware.documentation_description"
)}</span
>
<ha-icon-next slot="meta"></ha-icon-next>
</ha-clickable-list-item>
</ha-list>
<span slot="supporting-text"
>${this.hass.localize(
"ui.panel.config.hardware.documentation_description"
)}</span
>
<ha-icon-next slot="end"></ha-icon-next>
</ha-md-list-item>
`
: ""}
${boardConfigEntries.length ||

View File

@ -13,11 +13,12 @@ import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import "../../../components/ha-card";
import "../../../components/ha-clickable-list-item";
import "../../../components/ha-icon-next";
import "../../../components/ha-list";
import "../../../components/ha-list-item";
import "../../../components/ha-logo-svg";
import "../../../components/ha-md-list";
import "../../../components/ha-md-list-item";
import type { HassioHassOSInfo } from "../../../data/hassio/host";
import { fetchHassioHassOsInfo } from "../../../data/hassio/host";
import type { HassioInfo } from "../../../data/hassio/supervisor";
@ -174,10 +175,10 @@ class HaConfigInfo extends LitElement {
</ha-card>
<ha-card outlined class="pages">
<ha-list>
<ha-list-item graphic="avatar" @click=${this._showShortcuts}>
<ha-md-list>
<ha-md-list-item type="button" @click=${this._showShortcuts}>
<div
slot="graphic"
slot="start"
class="icon-background"
style="background-color: #9e4dd1;"
>
@ -186,18 +187,18 @@ class HaConfigInfo extends LitElement {
<span
>${this.hass.localize("ui.panel.config.info.shortcuts")}</span
>
</ha-list-item>
</ha-md-list-item>
${PAGES.map(
(page) => html`
<ha-clickable-list-item
graphic="avatar"
open-new-tab
href=${documentationUrl(this.hass, page.path)}
hasMeta
<ha-md-list-item
type="link"
.href=${documentationUrl(this.hass, page.path)}
target="_blank"
rel="noopener noreferrer"
>
<div
slot="graphic"
slot="start"
class="icon-background"
.style="background-color: ${page.iconColor}"
>
@ -208,14 +209,11 @@ class HaConfigInfo extends LitElement {
`ui.panel.config.info.items.${page.name}`
)}
</span>
<ha-svg-icon
slot="meta"
.path=${mdiOpenInNew}
></ha-svg-icon>
</ha-clickable-list-item>
<ha-svg-icon slot="end" .path=${mdiOpenInNew}></ha-svg-icon>
</ha-md-list-item>
`
)}
</ha-list>
</ha-md-list>
${customUiList.length
? html`
<div class="custom-ui">
@ -354,16 +352,6 @@ class HaConfigInfo extends LitElement {
padding: 4px 0;
}
ha-list {
--mdc-list-side-padding: 16px;
--mdc-list-vertical-padding: 0;
}
ha-clickable-list-item,
ha-list-item {
height: 64px;
}
.icon-background ha-svg-icon {
height: 24px;
width: 24px;

View File

@ -1,10 +1,10 @@
import { mdiDotsVertical } from "@mdi/js";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-button-menu";
import "../../../components/ha-clickable-list-item";
import "../../../components/ha-icon-button";
import type { HomeAssistant } from "../../../types";
import "../../../components/ha-md-list-item";
import "../../../components/ha-md-button-menu";
@customElement("ha-integration-overflow-menu")
export class HaIntegrationOverflowMenu extends LitElement {
@ -12,18 +12,18 @@ export class HaIntegrationOverflowMenu extends LitElement {
protected render() {
return html`
<ha-button-menu activatable>
<ha-md-button-menu>
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-clickable-list-item href="/config/application_credentials">
<ha-md-list-item type="link" href="/config/application_credentials">
${this.hass.localize(
"ui.panel.config.application_credentials.caption"
)}
</ha-clickable-list-item>
</ha-button-menu>
</ha-md-list-item>
</ha-md-button-menu>
`;
}
}

View File

@ -11,17 +11,20 @@ import { customElement, property, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import memoize from "memoize-one";
import { isComponentLoaded } from "../../../../common/config/is_component_loaded";
import { storage } from "../../../../common/decorators/storage";
import { navigate } from "../../../../common/navigate";
import { stringCompare } from "../../../../common/string/compare";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import type {
DataTableColumnContainer,
RowClickedEvent,
SortingChangedEvent,
} from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-clickable-list-item";
import "../../../../components/ha-fab";
import "../../../../components/ha-icon";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-md-button-menu";
import "../../../../components/ha-md-list-item";
import "../../../../components/ha-svg-icon";
import "../../../../components/ha-tooltip";
import type { LovelacePanelConfig } from "../../../../data/lovelace";
@ -44,13 +47,11 @@ import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-
import "../../../../layouts/hass-loading-screen";
import "../../../../layouts/hass-tabs-subpage-data-table";
import type { HomeAssistant, Route } from "../../../../types";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import { getLovelaceStrategy } from "../../../lovelace/strategies/get-strategy";
import { showNewDashboardDialog } from "../../dashboard/show-dialog-new-dashboard";
import { lovelaceTabs } from "../ha-config-lovelace";
import { showDashboardConfigureStrategyDialog } from "./show-dialog-lovelace-dashboard-configure-strategy";
import { showDashboardDetailDialog } from "./show-dialog-lovelace-dashboard-detail";
import { storage } from "../../../../common/decorators/storage";
type DataTableItem = Pick<
LovelaceDashboard,
@ -327,16 +328,16 @@ export class HaConfigLovelaceDashboards extends LitElement {
has-fab
clickable
>
<ha-button-menu slot="toolbar-icon" activatable>
<ha-md-button-menu slot="toolbar-icon">
<ha-icon-button
slot="trigger"
.label=${this.hass.localize("ui.common.menu")}
.path=${mdiDotsVertical}
></ha-icon-button>
<ha-clickable-list-item href="/config/lovelace/resources">
<ha-md-list-item type="link" href="/config/lovelace/resources">
${this.hass.localize("ui.panel.config.lovelace.resources.caption")}
</ha-clickable-list-item>
</ha-button-menu>
</ha-md-list-item>
</ha-md-button-menu>
<ha-fab
slot="fab"
.label=${this.hass.localize(

View File

@ -2,8 +2,9 @@ import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import "../../../components/ha-card";
import "../../../components/ha-clickable-list-item";
import "../../../components/ha-list";
import "../../../components/ha-md-list";
import "../../../components/ha-md-list-item";
import type {
IntegrationManifest,
IntegrationSetup,
@ -39,7 +40,7 @@ class IntegrationsStartupTime extends LitElement {
}
return html`
<ha-list>
<ha-md-list>
${this._setups?.map((setup) => {
const manifest = this._manifests && this._manifests[setup.domain];
const docLink = manifest
@ -50,13 +51,7 @@ class IntegrationsStartupTime extends LitElement {
const setupSeconds = setup.seconds?.toFixed(2);
return html`
<ha-clickable-list-item
graphic="avatar"
twoline
hasMeta
open-new-tab
href=${docLink}
>
<ha-md-list-item .href=${docLink} type="link" target="_blank">
<img
alt=""
loading="lazy"
@ -68,19 +63,19 @@ class IntegrationsStartupTime extends LitElement {
})}
crossorigin="anonymous"
referrerpolicy="no-referrer"
slot="graphic"
slot="start"
/>
<span>
${domainToName(this.hass.localize, setup.domain, manifest)}
</span>
<span slot="secondary">${setup.domain}</span>
<div slot="meta">
<span slot="supporting-text">${setup.domain}</span>
<div slot="end">
${setupSeconds ? html`${setupSeconds} s` : ""}
</div>
</ha-clickable-list-item>
</ha-md-list-item>
`;
})}
</ha-list>
</ha-md-list>
`;
}
@ -109,20 +104,14 @@ class IntegrationsStartupTime extends LitElement {
}
static styles = css`
ha-clickable-list-item {
--mdc-list-item-meta-size: 64px;
--mdc-typography-caption-font-size: 12px;
}
img {
display: block;
max-height: 40px;
max-width: 40px;
border-radius: 0;
}
div[slot="meta"] {
display: flex;
justify-content: center;
align-items: center;
div[slot="end"] {
font-size: 12px;
}
`;
}