import { LightningElement, api } from "lwc"; import cx from "classnames"; import { ButtonTextColor, ButtonTarget, ButtonVariant, ButtonSize, IconSprite, IconSize, IconSymbol } from "typings/custom"; export default class Button extends LightningElement { private _didSetFormAttribute = false; @api ariaLabel: string = ""; @api disabled: boolean | null = null; @api iconColor?: string; @api iconSize?: IconSize = "small"; @api iconSprite?: IconSprite = "utility"; @api iconSymbol?: IconSymbol; @api iconPosition?: "right" | "left" = "right"; @api loading: boolean = false; @api size: ButtonSize = "small"; @api variant: ButtonVariant = "primary"; @api inlineTextColor: ButtonTextColor = "dark"; @api font: "display" | "sans" = "display"; @api form: string | undefined; @api name?: string; @api value?: any; // button props @api type: "submit" | "reset" | "button" = "button"; // link props @api href: string | null = null; @api download: string | null = null; @api target: ButtonTarget = null; @api rel: string | null = null; @api focus() { const button = this.template.querySelector(".button"); if (button) { button.focus(); } } private isSlotEmpty: boolean = true; private get showIcon(): boolean { return !!this.iconSymbol && !this.loading; } private get className(): string { const isIconOnly = this.variant === "icon-only"; const iconPositionClassName = `icon-${this.iconPosition || "left"}`; const inlineTextColorClassName = `${this.inlineTextColor}-text`; return cx( "button", `font-${this.font}`, `size-${this.size}`, `variant_${this.variant}`, { "slot-empty": !isIconOnly && !this.loading && this.isSlotEmpty, "state-disabled": this.disabled, "state-loading": this.loading, "style-icon": !!this.iconSymbol, [iconPositionClassName]: !isIconOnly, [inlineTextColorClassName]: this.variant === "inline" } ); } renderedCallback() { if ( !this.href && typeof this.form !== "undefined" && !this._didSetFormAttribute ) { this._didSetFormAttribute = true; this.template .querySelector("button") ?.setAttribute("form", this.form); } } private onSlotChange(e: Event) { const slot = e.target as HTMLSlotElement; this.isSlotEmpty = slot.assignedNodes().length === 0; } }