UNPKG

@limetech/lime-elements

Version:
313 lines (312 loc) 11 kB
import { h, Host } from "@stencil/core"; import { makeEnterClickable, removeEnterClickable, } from "../../util/make-enter-clickable"; import { getIconName, getIconTitle } from "../icon/get-icon-props"; /** * @exampleComponent limel-example-button-basic * @exampleComponent limel-example-button-primary * @exampleComponent limel-example-button-outlined * @exampleComponent limel-example-button-disabled * @exampleComponent limel-example-button-icon * @exampleComponent limel-example-button-loading * @exampleComponent limel-example-button-click-success * @exampleComponent limel-example-button-click-fail * @exampleComponent limel-example-button-reduce-presence * @exampleComponent limel-example-button-colors * @exampleComponent limel-example-button-composite */ export class Button { constructor() { /** * Set to `true` to make the button primary. */ this.primary = false; /** * Set to `true` to make the button outlined. */ this.outlined = false; /** * Set to `true` to disable the button. */ this.disabled = false; /** * Set to `true` to put the button in the `loading` state. * This also disables the button. */ this.loading = false; /** * Set to `true` to indicate failure instead of success when the button is * no longer in the `loading` state. */ this.loadingFailed = false; this.justLoaded = false; this.filterClickWhenDisabled = (e) => { if (this.disabled) { e.preventDefault(); } }; } componentWillLoad() { makeEnterClickable(this.host); } disconnectedCallback() { removeEnterClickable(this.host); } render() { return (h(Host, { key: '426168cd8aca55bd6dbefb8e00a0890bbb292477', onClick: this.filterClickWhenDisabled }, h("button", { key: '30981d02852f9f6495e5fa36e3590ce04dcd957d', class: { loading: this.loading, 'just-loaded': this.justLoaded && !this.loadingFailed, 'just-failed': this.justLoaded && this.loadingFailed, outlined: this.outlined, }, disabled: this.disabled || this.loading, "aria-busy": this.loading ? 'true' : 'false', "aria-live": "polite" }, this.renderIcon(this.icon), this.renderLabel(), this.renderSpinner(), h("svg", { key: '0fc71b8f9aae8569b0112c3c92da2c2da8d79738', viewBox: "0 0 30 30" }, this.renderLoadingIcons())))); } loadingWatcher(newValue, oldValue) { const hasFinishedLoading = this.hasFinishedLoading(newValue, oldValue); if (hasFinishedLoading) { this.handleLoadingFinished(); } else if (newValue) { this.handleLoadingStarted(); } } hasFinishedLoading(newValue, oldValue) { return oldValue && !newValue; } handleLoadingFinished() { this.justLoaded = true; const TIMEOUT = 2000; this.justLoadedTimeout = window.setTimeout(() => { this.justLoaded = false; }, TIMEOUT); } handleLoadingStarted() { this.justLoaded = false; window.clearTimeout(this.justLoadedTimeout); } renderLoadingIcons() { if (this.loadingFailed) { return [ h("line", { x1: "9", y1: "9", x2: "21", y2: "21" }), h("line", { x1: "21", y1: "9", x2: "9", y2: "21" }), ]; } return [ h("line", { x1: "8", y1: "14", x2: "15", y2: "20" }), h("line", { x1: "23", y1: "9", x2: "14", y2: "20" }), ]; } renderIcon(icon) { const iconName = getIconName(icon); if (!iconName) { return; } const title = getIconTitle(icon); if (!this.label && !title) { const WARNING_MESSAGE = '⚠️ Accessibility warning: `limel-button` has no `label` and its `icon` has no `title`. ' + 'This creates an inaccessible button for screen reader users. ' + 'Please add either a `label`, a `title` to the `icon`, or use a `limel-tooltip`. ' + 'See https://lundalogik.github.io/lime-elements/versions/latest/#/component/limel-button/ ' + 'for more information.'; console.warn(WARNING_MESSAGE); } let iconColor; if (typeof icon === 'object') { iconColor = icon.color; } const iconProps = { role: 'presentation', name: iconName, 'aria-label': title, 'aria-hidden': title ? null : 'true', // Use null instead of 'false' to remove attribute style: { color: iconColor, }, }; return h("limel-icon", Object.assign({}, iconProps)); } renderLabel() { if (!this.label) { return; } return h("span", { class: "label" }, this.label); } renderSpinner() { if (!this.loading) { return; } return h("limel-spinner", { limeBranded: false }); } static get is() { return "limel-button"; } static get encapsulation() { return "shadow"; } static get delegatesFocus() { return true; } static get originalStyleUrls() { return { "$": ["button.scss"] }; } static get styleUrls() { return { "$": ["button.css"] }; } static get properties() { return { "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The text to show on the button." }, "getter": false, "setter": false, "reflect": true, "attribute": "label" }, "primary": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to make the button primary." }, "getter": false, "setter": false, "reflect": true, "attribute": "primary", "defaultValue": "false" }, "outlined": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to make the button outlined." }, "getter": false, "setter": false, "reflect": true, "attribute": "outlined", "defaultValue": "false" }, "icon": { "type": "string", "mutable": false, "complexType": { "original": "string | Icon", "resolved": "Icon | string", "references": { "Icon": { "location": "import", "path": "../../global/shared-types/icon.types", "id": "src/global/shared-types/icon.types.ts::Icon", "referenceLocation": "Icon" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set icon for the button" }, "getter": false, "setter": false, "reflect": true, "attribute": "icon" }, "disabled": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to disable the button." }, "getter": false, "setter": false, "reflect": true, "attribute": "disabled", "defaultValue": "false" }, "loading": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to put the button in the `loading` state.\nThis also disables the button." }, "getter": false, "setter": false, "reflect": true, "attribute": "loading", "defaultValue": "false" }, "loadingFailed": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` to indicate failure instead of success when the button is\nno longer in the `loading` state." }, "getter": false, "setter": false, "reflect": true, "attribute": "loading-failed", "defaultValue": "false" } }; } static get states() { return { "justLoaded": {} }; } static get elementRef() { return "host"; } static get watchers() { return [{ "propName": "loading", "methodName": "loadingWatcher" }]; } }