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/paper-tabs": "3.1.0",
"@polymer/polymer": "3.5.2", "@polymer/polymer": "3.5.2",
"@replit/codemirror-indentation-markers": "6.5.3", "@replit/codemirror-indentation-markers": "6.5.3",
"@shoelace-style/shoelace": "2.20.0",
"@thomasloven/round-slider": "0.6.0", "@thomasloven/round-slider": "0.6.0",
"@vaadin/combo-box": "24.6.5", "@vaadin/combo-box": "24.6.5",
"@vaadin/vaadin-themable-mixin": "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 type { CSSResultGroup, TemplateResult } from "lit";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
@ -8,6 +7,7 @@ import type { Analytics, AnalyticsPreferences } from "../data/analytics";
import { haStyle } from "../resources/styles"; import { haStyle } from "../resources/styles";
import "./ha-settings-row"; import "./ha-settings-row";
import "./ha-switch"; import "./ha-switch";
import "./ha-tooltip";
import type { HaSwitch } from "./ha-switch"; import type { HaSwitch } from "./ha-switch";
const ADDITIONAL_PREFERENCES = ["usage", "statistics"] as const; const ADDITIONAL_PREFERENCES = ["usage", "statistics"] as const;
@ -67,22 +67,21 @@ export class HaAnalytics extends LitElement {
)} )}
</span> </span>
<span> <span>
<ha-switch <ha-tooltip
@change=${this._handleRowClick} content=${this.localize(
.checked=${this.analytics?.preferences[preference]} `ui.panel.${this.translationKeyPanel}.analytics.need_base_enabled`
.preference=${preference} )}
name=${preference} placement="right"
?disabled=${baseEnabled}
> >
</ha-switch> <ha-switch
${!baseEnabled @change=${this._handleRowClick}
? html` .checked=${this.analytics?.preferences[preference]}
<simple-tooltip animation-delay="0" position="right"> .preference=${preference}
${this.localize( name=${preference}
`ui.panel.${this.translationKeyPanel}.analytics.need_base_enabled` >
)} </ha-switch>
</simple-tooltip> </ha-tooltip>
`
: ""}
</span> </span>
</ha-settings-row> </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 { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { formatDateTime } from "../../common/datetime/format_date_time"; import { formatDateTime } from "../../common/datetime/format_date_time";
import "../../components/ha-markdown"; import "../../components/ha-markdown";
import "../../components/ha-relative-time"; import "../../components/ha-relative-time";
import "../../components/ha-tooltip";
import "../../components/ha-button";
import type { PersistentNotification } from "../../data/persistent_notification"; import type { PersistentNotification } from "../../data/persistent_notification";
import type { HomeAssistant } from "../../types"; import type { HomeAssistant } from "../../types";
import "./notification-item-template"; import "./notification-item-template";
@ -28,21 +28,23 @@ export class HuiPersistentNotificationItem extends LitElement {
<div class="time"> <div class="time">
<span> <span>
<ha-relative-time <ha-tooltip
.hass=${this.hass} .content=${this._computeTooltip(this.hass, this.notification)}
.datetime=${this.notification.created_at} placement="bottom"
capitalize >
></ha-relative-time> <ha-relative-time
<simple-tooltip animation-delay="0"> .hass=${this.hass}
${this._computeTooltip(this.hass, this.notification)} .datetime=${this.notification.created_at}
</simple-tooltip> capitalize
></ha-relative-time>
</ha-tooltip>
</span> </span>
</div> </div>
<mwc-button slot="actions" @click=${this._handleDismiss} <ha-button slot="actions" @click=${this._handleDismiss}
>${this.hass.localize( >${this.hass.localize(
"ui.card.persistent_notification.dismiss" "ui.card.persistent_notification.dismiss"
)}</mwc-button )}</ha-button
> >
</notification-item-template> </notification-item-template>
`; `;

884
yarn.lock

File diff suppressed because it is too large Load Diff