@limetech/lime-elements
Version:
313 lines (312 loc) • 11 kB
JavaScript
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"
}];
}
}