shoelace tooltip (#24337)

* Add shoelace based ha-tooltip

* Use shoelace component

* Improve styles

* Add docs

* Fix tooltip docs

* Revert new global styles
This commit is contained in:
Wendelin 2025-02-24 15:37:59 +01:00 committed by GitHub
parent 0cfe7f8d12
commit 9e1d64e728
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 558 additions and 457 deletions

View File

@ -0,0 +1,30 @@
---
title: Tooltip
---
A tooltip's target is its _first child element_, so you should only wrap one element inside of the tooltip. If you need the tooltip to show up for multiple elements, nest them inside a container first.
Tooltips use `display: contents` so they won't interfere with how elements are positioned in a flex or grid layout.
<ha-tooltip content="This is a tooltip">
<ha-button>Hover Me</ha-button>
</ha-tooltip>
```
<ha-tooltip content="This is a tooltip">
<ha-button>Hover Me</ha-button>
</ha-tooltip>
```
## Documentation
This element is based on sholace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation.
<a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a>
### HA style tokens
In your theme settings use this without the prefixed `--`.
- `--ha-tooltip-border-radius` (Default: 4px)
- `--ha-tooltip-arrow-size` (Default: 8px)

View File

@ -0,0 +1,2 @@
import "../../../../src/components/ha-tooltip";
import "../../../../src/components/ha-button";

View File

@ -90,6 +90,7 @@
"@polymer/paper-tabs": "3.1.0",
"@polymer/polymer": "3.5.2",
"@replit/codemirror-indentation-markers": "6.5.3",
"@shoelace-style/shoelace": "2.20.0",
"@thomasloven/round-slider": "0.6.0",
"@vaadin/combo-box": "24.6.5",
"@vaadin/vaadin-themable-mixin": "24.6.5",

View File

@ -1,4 +1,3 @@
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
@ -8,6 +7,7 @@ import type { Analytics, AnalyticsPreferences } from "../data/analytics";
import { haStyle } from "../resources/styles";
import "./ha-settings-row";
import "./ha-switch";
import "./ha-tooltip";
import type { HaSwitch } from "./ha-switch";
const ADDITIONAL_PREFERENCES = ["usage", "statistics"] as const;
@ -67,22 +67,21 @@ export class HaAnalytics extends LitElement {
)}
</span>
<span>
<ha-switch
@change=${this._handleRowClick}
.checked=${this.analytics?.preferences[preference]}
.preference=${preference}
name=${preference}
<ha-tooltip
content=${this.localize(
`ui.panel.${this.translationKeyPanel}.analytics.need_base_enabled`
)}
placement="right"
?disabled=${baseEnabled}
>
</ha-switch>
${!baseEnabled
? html`
<simple-tooltip animation-delay="0" position="right">
${this.localize(
`ui.panel.${this.translationKeyPanel}.analytics.need_base_enabled`
)}
</simple-tooltip>
`
: ""}
<ha-switch
@change=${this._handleRowClick}
.checked=${this.analytics?.preferences[preference]}
.preference=${preference}
name=${preference}
>
</ha-switch>
</ha-tooltip>
</span>
</ha-settings-row>
`

View File

@ -0,0 +1,41 @@
import SlTooltip from "@shoelace-style/shoelace/dist/components/tooltip/tooltip.component";
import styles from "@shoelace-style/shoelace/dist/components/tooltip/tooltip.styles";
import { css } from "lit";
import { customElement } from "lit/decorators";
import { setDefaultAnimation } from "@shoelace-style/shoelace/dist/utilities/animation-registry";
setDefaultAnimation("tooltip.show", {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
options: { duration: 150, easing: "ease" },
});
setDefaultAnimation("tooltip.hide", {
keyframes: [{ opacity: 1 }, { opacity: 0 }],
options: { duration: 400, easing: "ease" },
});
@customElement("ha-tooltip")
export class HaTooltip extends SlTooltip {
static override styles = [
styles,
css`
:host {
--sl-tooltip-background-color: var(--secondary-background-color);
--sl-tooltip-color: var(--primary-text-color);
--sl-tooltip-font-family: Roboto, sans-serif;
--sl-tooltip-font-size: 12px;
--sl-tooltip-font-weight: normal;
--sl-tooltip-line-height: 1;
--sl-tooltip-padding: 8px;
--sl-tooltip-border-radius: var(--ha-tooltip-border-radius, 4px);
--sl-tooltip-arrow-size: var(--ha-tooltip-arrow-size, 8px);
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
"ha-tooltip": HaTooltip;
}
}

View File

@ -1,10 +1,10 @@
import "@material/mwc-button";
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { formatDateTime } from "../../common/datetime/format_date_time";
import "../../components/ha-markdown";
import "../../components/ha-relative-time";
import "../../components/ha-tooltip";
import "../../components/ha-button";
import type { PersistentNotification } from "../../data/persistent_notification";
import type { HomeAssistant } from "../../types";
import "./notification-item-template";
@ -28,21 +28,23 @@ export class HuiPersistentNotificationItem extends LitElement {
<div class="time">
<span>
<ha-relative-time
.hass=${this.hass}
.datetime=${this.notification.created_at}
capitalize
></ha-relative-time>
<simple-tooltip animation-delay="0">
${this._computeTooltip(this.hass, this.notification)}
</simple-tooltip>
<ha-tooltip
.content=${this._computeTooltip(this.hass, this.notification)}
placement="bottom"
>
<ha-relative-time
.hass=${this.hass}
.datetime=${this.notification.created_at}
capitalize
></ha-relative-time>
</ha-tooltip>
</span>
</div>
<mwc-button slot="actions" @click=${this._handleDismiss}
<ha-button slot="actions" @click=${this._handleDismiss}
>${this.hass.localize(
"ui.card.persistent_notification.dismiss"
)}</mwc-button
)}</ha-button
>
</notification-item-template>
`;

884
yarn.lock

File diff suppressed because it is too large Load Diff