mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-31 05:06:38 +00:00
Finish new button api
This commit is contained in:
parent
422f05dc3b
commit
bc3933d7d7
@ -3,141 +3,123 @@ import styles from "@shoelace-style/shoelace/dist/components/button/button.style
|
||||
import { css } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
|
||||
/**
|
||||
* Home Assistant button component
|
||||
*
|
||||
* @element ha-button
|
||||
* @extends {Button}
|
||||
*
|
||||
* @summary
|
||||
* A stylable button component supporting Home Assistant theming, variants, and appearances.
|
||||
*
|
||||
* @slot - Label of the button
|
||||
* @slot prefix - The prefix container (usually for icons).
|
||||
* @slot suffix - The suffix container (usually for icons).
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
* @csspart prefix - The container that wraps the prefix.
|
||||
* @csspart label - The button's label.
|
||||
* @csspart suffix - The container that wraps the suffix.
|
||||
* @csspart caret - The button's caret icon, an `<sl-icon>` element.
|
||||
* @csspart spinner - The spinner that shows when the button is in the loading state.
|
||||
*
|
||||
* @cssprop --ha-button-font-family - Font family for the button text.
|
||||
* @cssprop --ha-font-weight-medium - Medium font weight for button text.
|
||||
* @cssprop --ha-button-line-height - Line height for button text.
|
||||
* @cssprop --ha-button-border-width - Border width for the button.
|
||||
* @cssprop --ha-button-theme-color - Main color for the button.
|
||||
* @cssprop --ha-button-theme-darker-color - Darker variant of the main color.
|
||||
* @cssprop --ha-button-theme-lighter-color - Lighter variant of the main color.
|
||||
* @cssprop --ha-button-height - Height of the button.
|
||||
* @cssprop --ha-button-border-radius - Border radius for the button.
|
||||
* @cssprop --ha-button-text-color - Text color for the button.
|
||||
*
|
||||
* @attr {("small"|"medium")} size - Sets the button size.
|
||||
* @attr {("primary"|"danger"|"neutral")} variant - Sets the button color variant. "primary" is default.
|
||||
* @attr {("accent"|"filled"|"plain")} appearance - Sets the button appearance.
|
||||
*/
|
||||
@customElement("ha-button")
|
||||
export class HaButton extends Button {
|
||||
@property({ type: Boolean }) pill = true;
|
||||
@property() appearance?: "accent" | "filled" | "plain";
|
||||
|
||||
static override styles = [
|
||||
styles,
|
||||
css`
|
||||
:host {
|
||||
--sl-input-border-width: 0;
|
||||
--sl-input-font-family: var(
|
||||
--ha-button-font-family,
|
||||
var(--ha-font-family-body)
|
||||
);
|
||||
--sl-font-weight-semibold: var(--ha-font-weight-medium);
|
||||
--sl-transition-x-fast: 0.1s; /* ? */
|
||||
--sl-focus-ring: none; /* ? */
|
||||
--sl-focus-ring-offset: 0; /* ? */
|
||||
--sl-font-weight-semibold: var(
|
||||
--ha-button-font-weight,
|
||||
var(--ha-font-weight-medium)
|
||||
);
|
||||
--sl-transition-x-fast: 0.4s;
|
||||
--sl-focus-ring: solid 4px var(--accent-color);
|
||||
--sl-focus-ring-offset: 1px;
|
||||
|
||||
--sl-spacing-medium: 16px;
|
||||
--sl-spacing-small: 12px;
|
||||
--sl-spacing-x-small: 8px;
|
||||
|
||||
--ha-button-theme-color: var(--primary-color);
|
||||
--ha-button-theme-darker-color: var(--dark-primary-color);
|
||||
--ha-button-theme-lighter-color: var(--light-primary-color);
|
||||
|
||||
line-height: var(--ha-button-line-height, var(--ha-line-height-normal));
|
||||
--sl-input-border-width: var(--ha-button-border-width, 0);
|
||||
}
|
||||
|
||||
:host([destructive]), /* Deprecated */
|
||||
:host([variant="danger"]) {
|
||||
--ha-button-theme-color: var(--error-color);
|
||||
--ha-button-theme-darker-color: var(--error-color-darker);
|
||||
--ha-button-theme-lighter-color: var(--error-color-lighter);
|
||||
}
|
||||
|
||||
:host([variant="neutral"]) {
|
||||
--ha-button-theme-color: var(--primary-text-color);
|
||||
--ha-button-theme-darker-color: var(--dark-primary-color);
|
||||
--ha-button-theme-lighter-color: var(--light-primary-color);
|
||||
}
|
||||
|
||||
.button {
|
||||
height: 40px;
|
||||
height: var(--ha-button-height, var(--button-height, 40px));
|
||||
align-items: center;
|
||||
border-radius: var(--ha-button-border-radius, 48px);
|
||||
}
|
||||
.button.button--small {
|
||||
height: 32px;
|
||||
border-radius: var(--ha-button-border-radius, 32px);
|
||||
height: var(--ha-button-height, var(--button-height, 32px));
|
||||
}
|
||||
|
||||
/* Default */
|
||||
.button--standard.button--default,
|
||||
.button--standard.button--primary:active:not(.button--disabled) {
|
||||
background-color: var(
|
||||
--ha-button-background-color,
|
||||
var(--primary-color)
|
||||
);
|
||||
.button,
|
||||
.button:active:not(.button--disabled) {
|
||||
background-color: var(--ha-button-theme-color);
|
||||
color: var(--ha-button-text-color, var(--white-color));
|
||||
}
|
||||
.button--standard.button--default:hover:not(.button--disabled) {
|
||||
background-color: var(
|
||||
--ha-button-background-color,
|
||||
var(--dark-primary-color)
|
||||
);
|
||||
color: var(--ha-button-text-color, var(--white-color));
|
||||
.button:hover:not(.button--disabled) {
|
||||
background-color: var(--ha-button-theme-darker-color);
|
||||
}
|
||||
|
||||
/* Danger */
|
||||
:host([destructive]) .button--standard,
|
||||
.button--standard.button--danger,
|
||||
.button--standard.button--danger:active:not(.button--disabled) {
|
||||
background-color: var(--ha-button-background-color, var(--error-color));
|
||||
color: var(--ha-button-text-color, var(--white-color));
|
||||
:host([appearance="filled"]) .button,
|
||||
:host([appearance="filled"]) .button:active:not(.button--disabled) {
|
||||
background-color: var(--ha-button-theme-lighter-color);
|
||||
color: var(--ha-button-text-color, var(--ha-button-theme-color));
|
||||
}
|
||||
:host([appearance="filled"]) .button:hover:not(.button--disabled) {
|
||||
background-color: var(--ha-button-theme-color);
|
||||
color: var(--white-color);
|
||||
}
|
||||
|
||||
:host([destructive]) .button--standard:hover:not(.button--disabled),
|
||||
.button--standard.button--danger:hover:not(.button--disabled) {
|
||||
background-color: var(--ha-button-background-color, var(--error-color));
|
||||
color: var(--ha-button-text-color, var(--white-color));
|
||||
}
|
||||
|
||||
/*
|
||||
* Text buttons
|
||||
*/
|
||||
|
||||
.button--text,
|
||||
.button--text:active:not(.button--disabled) {
|
||||
color: var(--ha-button-text-color, var(--primary-color));
|
||||
}
|
||||
|
||||
.button--text:hover:not(.button--disabled),
|
||||
.button--text:focus-visible:not(.button--disabled) {
|
||||
:host([appearance="plain"]) .button,
|
||||
:host([appearance="plain"]) .button:active:not(.button--disabled) {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
color: var(--ha-button-text-color, var(--dark-primary-color));
|
||||
color: var(--ha-button-text-color, var(--ha-button-theme-color));
|
||||
}
|
||||
|
||||
.button--pill.button--small {
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.button--pill.button--medium {
|
||||
border-radius: 48px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Button spacing
|
||||
*/
|
||||
|
||||
.button--has-label.button--small .button__label {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.button--has-label.button--medium .button__label {
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.button--has-prefix.button--small,
|
||||
.button--has-prefix.button--small .button__label {
|
||||
padding-inline-start: 8px;
|
||||
}
|
||||
|
||||
.button--has-prefix.button--medium,
|
||||
.button--has-prefix.button--medium .button__label {
|
||||
padding-inline-start: 12px;
|
||||
}
|
||||
|
||||
.button--has-suffix.button--small,
|
||||
.button--caret.button--small,
|
||||
.button--has-suffix.button--small .button__label,
|
||||
.button--caret.button--small .button__label {
|
||||
padding-inline-end: 8px;
|
||||
}
|
||||
|
||||
.button--has-suffix.button--medium,
|
||||
.button--caret.button--medium,
|
||||
.button--has-suffix.button--medium .button__label,
|
||||
.button--caret.button--medium .button__label {
|
||||
padding-inline-end: 12px;
|
||||
}
|
||||
|
||||
::slotted([slot="icon"]) {
|
||||
margin-inline-start: 0px;
|
||||
margin-inline-end: 8px;
|
||||
direction: var(--direction);
|
||||
display: block;
|
||||
}
|
||||
.mdc-button {
|
||||
height: var(--button-height, 36px);
|
||||
}
|
||||
.trailing-icon {
|
||||
display: flex;
|
||||
}
|
||||
.slot-container {
|
||||
overflow: var(--button-slot-container-overflow, visible);
|
||||
}
|
||||
:host([destructive]) {
|
||||
--mdc-theme-primary: var(--error-color);
|
||||
:host([appearance="plain"]) .button:hover:not(.button--disabled) {
|
||||
background-color: var(--ha-button-theme-lighter-color);
|
||||
color: var(--ha-button-text-color, var(--ha-button-theme-darker-color));
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -4,6 +4,9 @@ import { LitElement, css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-list-item";
|
||||
import {
|
||||
ATTENTION_SOURCES,
|
||||
DISCOVERY_SOURCES,
|
||||
@ -17,9 +20,6 @@ import type { HomeAssistant } from "../../../types";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import type { DataEntryFlowProgressExtended } from "./ha-config-integrations";
|
||||
import "./ha-integration-action-card";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-list-item";
|
||||
|
||||
@customElement("ha-config-flow-card")
|
||||
export class HaConfigFlowCard extends LitElement {
|
||||
@ -41,24 +41,25 @@ export class HaConfigFlowCard extends LitElement {
|
||||
.domain=${this.flow.handler}
|
||||
.label=${this.flow.localized_title}
|
||||
>
|
||||
${DISCOVERY_SOURCES.includes(this.flow.context.source) &&
|
||||
this.flow.context.unique_id
|
||||
? html`<ha-button appearance="plain" @click=${this._ignoreFlow}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.integrations.ignore.ignore"
|
||||
)}</ha-button
|
||||
>`
|
||||
: ""}
|
||||
<ha-button
|
||||
unelevated
|
||||
@click=${this._continueFlow}
|
||||
.label=${this.hass.localize(
|
||||
variant=${attention ? "danger" : "primary"}
|
||||
appearance="filled"
|
||||
>
|
||||
${this.hass.localize(
|
||||
attention
|
||||
? "ui.panel.config.integrations.reconfigure"
|
||||
: "ui.common.add"
|
||||
)}
|
||||
></ha-button>
|
||||
${DISCOVERY_SOURCES.includes(this.flow.context.source) &&
|
||||
this.flow.context.unique_id
|
||||
? html`<ha-button
|
||||
@click=${this._ignoreFlow}
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.integrations.ignore.ignore"
|
||||
)}
|
||||
></ha-button>`
|
||||
: ""}
|
||||
</ha-button>
|
||||
${this.flow.context.configuration_url || this.manifest
|
||||
? html`<ha-button-menu slot="header-button">
|
||||
<ha-icon-button
|
||||
|
@ -4,6 +4,7 @@ import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { PROTOCOL_INTEGRATIONS } from "../../../common/integrations/protocolIntegrationPicked";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-card";
|
||||
@ -23,7 +24,6 @@ import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { ConfigEntryExtended } from "./ha-config-integrations";
|
||||
import "./ha-integration-header";
|
||||
import { PROTOCOL_INTEGRATIONS } from "../../../common/integrations/protocolIntegrationPicked";
|
||||
|
||||
@customElement("ha-integration-card")
|
||||
export class HaIntegrationCard extends LitElement {
|
||||
@ -120,7 +120,7 @@ export class HaIntegrationCard extends LitElement {
|
||||
? `/config/devices/device/${devices[0].id}`
|
||||
: `/config/devices/dashboard?historyBack=1&domain=${this.domain}`}
|
||||
>
|
||||
<ha-button>
|
||||
<ha-button appearance="plain">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.integrations.config_entry.${
|
||||
services ? "services" : "devices"
|
||||
@ -133,7 +133,7 @@ export class HaIntegrationCard extends LitElement {
|
||||
? html`<a
|
||||
href=${`/config/entities?historyBack=1&domain=${this.domain}`}
|
||||
>
|
||||
<ha-button>
|
||||
<ha-button appearance="plain">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.integrations.config_entry.entities`,
|
||||
{ count: entitiesCount }
|
||||
@ -144,7 +144,7 @@ export class HaIntegrationCard extends LitElement {
|
||||
? html`<a
|
||||
href=${`/config/integrations/integration/${this.domain}`}
|
||||
>
|
||||
<ha-button>
|
||||
<ha-button appearance="plain">
|
||||
${this.hass.localize(
|
||||
`ui.panel.config.integrations.config_entry.entries`,
|
||||
{
|
||||
@ -309,6 +309,7 @@ export class HaIntegrationCard extends LitElement {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 4px 16px 4px 4px;
|
||||
}
|
||||
.debug-logging {
|
||||
--state-color: var(--warning-color);
|
||||
|
@ -34,6 +34,8 @@ export const colorStyles = css`
|
||||
--scrollbar-thumb-color: rgb(194, 194, 194);
|
||||
|
||||
--error-color: #db4437;
|
||||
--error-color-lighter: #ffdedc;
|
||||
--error-color-darker: #b30532;
|
||||
--warning-color: #ffa600;
|
||||
--success-color: #43a047;
|
||||
--info-color: #039be5;
|
||||
|
Loading…
x
Reference in New Issue
Block a user