import { customElement, property, query, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { html, literal } from 'lit/static-html.js'; import { WaBlurEvent } from '../../events/blur.js'; import { WaFocusEvent } from '../../events/focus.js'; import { WaInvalidEvent } from '../../events/invalid.js'; import { MirrorValidator } from '../../internal/validators/mirror-validator.js'; import { watch } from '../../internal/watch.js'; import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-element.js'; import nativeStyles from '../../styles/native/button.css'; import sizeStyles from '../../styles/shadow/size.css'; import appearanceStyles from '../../styles/utilities/appearance.css'; import variantStyles from '../../styles/utilities/variants.css'; import { LocalizeController } from '../../utilities/localize.js'; import '../icon/icon.js'; import '../spinner/spinner.js'; import styles from './button.css'; /** * @summary Buttons represent actions that are available to the user. * @documentation https://backers.webawesome.com/docs/components/button * @status stable * @since 2.0 * * @dependency wa-icon * @dependency wa-spinner * * @event wa-blur - Emitted when the button loses focus. * @event wa-focus - Emitted when the button gains focus. * @event wa-invalid - Emitted when the form control has been checked for validity and its constraints aren't satisfied. * * @slot - The button's label. * @slot prefix - A presentational prefix icon or similar element. * @slot suffix - A presentational suffix icon or similar element. * * @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, a `` element. * @csspart spinner - The spinner that shows when the button is in the loading state. * * @cssproperty --background-color - The button's background color when the button is not being interacted with. * @cssproperty --background-color-active - The button's background color when active. * @cssproperty --background-color-hover - The button's background color on hover. * @cssproperty --border-color - The color of the button's border when the button is not being interacted with. * @cssproperty --border-color-active - The color of the button's border when active. * @cssproperty --border-color-hover - The color of the button's border on hover. * @cssproperty --text-color - The color of the button's label when the button is not being interacted with. * @cssproperty --text-color-active - The color of the button's label when active. * @cssproperty --text-color-hover - The color of the button's label on hover. */ @customElement('wa-button') export default class WaButton extends WebAwesomeFormAssociatedElement { static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles]; static get validators() { return [...super.validators, MirrorValidator()]; } assumeInteractionOn = ['click']; private readonly localize = new LocalizeController(this); @query('.wa-button') button: HTMLButtonElement | HTMLLinkElement; @state() private hasFocus = false; @state() visuallyHiddenLabel = false; @state() invalid = false; @property() title = ''; // make reactive to pass through /** The button's theme variant. */ @property({ reflect: true }) variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' = 'neutral'; /** The button's visual appearance. */ @property({ reflect: true }) appearance: 'filled' | 'tinted' | 'outlined' | 'text' = 'filled'; /** The button's size. */ @property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium'; /** Draws the button with a caret. Used to indicate that the button triggers a dropdown menu or similar behavior. */ @property({ type: Boolean, reflect: true }) caret = false; /** Disables the button. Does not apply to link buttons. */ @property({ type: Boolean }) disabled = false; /** Draws the button in a loading state. */ @property({ type: Boolean, reflect: true }) loading = false; /** Draws a pill-style button with rounded edges. */ @property({ type: Boolean, reflect: true }) pill = false; /** * The type of button. Note that the default value is `button` instead of `submit`, which is opposite of how native * `