UNPKG

@postnord/web-components

Version:

PostNord Web Components

752 lines (751 loc) 28.1 kB
/*! * Built with Stencil * By PostNord. */ import { Host, h } from "@stencil/core"; import { ripple } from "../../../index"; /** * The `pn-button` is built with a native `button` or `a` element, if you use the `href` attribute. * * @nativeClick Use the `click` event to listen when the button is clicked. */ export class PnButton { constructor() { this.tooltipOpen = false; this.tooltipUpwards = false; this.label = ''; this.appearance = ''; this.variant = ''; this.small = false; this.loading = false; this.icon = undefined; this.iconOnly = false; this.leftIcon = false; this.tooltip = undefined; this.tooltipUp = false; this.type = 'button'; this.form = undefined; this.href = undefined; this.rel = undefined; this.target = undefined; this.download = undefined; this.buttonId = null; this.arialabel = null; this.arialabelledby = null; this.ariacurrent = null; this.ariacontrols = null; this.ariapressed = null; this.ariahaspopup = null; this.ariaexpanded = null; this.noTab = false; } buttonEl; tooltipEl; tooltipDx; openEvents = ['mouseover', 'focus']; closeEvents = ['mouseleave', 'blur', 'touchcancel', 'touchleave']; eventListeners = [...this.openEvents, ...this.closeEvents]; hostElement; openHandler() { if (this.tooltipOpen) this.checkTooltipPosition(); } iconOnlyHandler() { this.checkTooltipPosition(); if (this.tooltip) this.initTooltip(); else this.removeTooltip(); } /** * This event is fired when the `button`/`a` element of the `pn-button` is clicked. * Setting an eventListener for `click` on the `pn-button` will trigger if you click outside of the button area * or if the button is `disabled` with the `loading` prop. **/ pnClick; componentWillLoad() { this.tooltipUpwards = this.tooltipUp; } componentDidLoad() { this.iconOnlyHandler(); } getRect(element) { return element.getBoundingClientRect(); } initTooltip() { this.eventListeners.forEach(e => this.buttonEl.addEventListener(e, this.toggleTooltip)); } removeTooltip() { this.eventListeners.forEach(e => this.buttonEl.removeEventListener(e, this.toggleTooltip)); } toggleTooltip = (event) => { this.tooltipOpen = this.openEvents.includes(event.type); }; setTooltipOffset() { this.tooltipEl.style.setProperty('--pn-dx', `${this.tooltipDx}px`); } checkTooltipPosition() { this.tooltipEl.style.transform = 'translateX(-50%)'; this.tooltipUpwards = this.tooltipUp; requestAnimationFrame(() => { const { top, x, y, right, height } = this.getRect(this.tooltipEl); const extraMargin = 16; this.tooltipDx = 0; this.tooltipUpwards = this.tooltipUp ? top > height : y + height > window.innerHeight; this.tooltipEl.style.transform = ''; if (x < 0) this.tooltipDx = x * -1 + extraMargin; if (right > window.innerWidth) this.tooltipDx = window.innerWidth - right - extraMargin - 8; requestAnimationFrame(() => this.setTooltipOffset()); }); } getAttributes() { const attrs = this.href ? { 'href': this.href, 'rel': !this.rel && this.target === '_blank' ? 'noopener' : this.rel, 'target': this.target ?? null, 'download': this.download ?? null, 'aria-current': this.ariacurrent, 'aria-disabled': this.loading ? 'true' : null, } : { 'type': this.type, 'form': this.form, 'disabled': this.loading, 'aria-pressed': this.ariapressed, 'aria-controls': this.ariacontrols, 'aria-haspopup': this.ariahaspopup, 'aria-expanded': this.ariaexpanded, }; const appearances = ['light', 'warning']; const variations = ['borderless', 'outlined']; return { 'tabindex': this.noTab || (this.href && this.loading) ? '-1' : null, 'data-small': this.small, 'data-loading': this.loading, 'data-tooltip-open': this.tooltipOpen, 'data-tooltip-upwards': this.tooltipUpwards, 'data-icon-only': this.showIconOnly(), 'data-left-icon': this.leftIcon, 'data-appearance': appearances.includes(this.appearance) ? this.appearance : null, 'data-variant': variations.includes(this.variant) ? this.variant : null, ...attrs, }; } getTagName() { return this.href ? 'a' : 'button'; } showIconOnly() { return !!this.icon && this.iconOnly && !!(this.tooltip || this.arialabel || this.arialabelledby); } handleClick(event) { ripple(event, this.hostElement, '.pn-button-bg'); this.pnClick.emit(event); } render() { const TagName = this.getTagName(); return (h(Host, { key: '180829edde0e9471638f6a432a23470b4a024201' }, h(TagName, { key: 'a379079e76aa1a3fdea4a5c17e0de204fbb546d0', class: "pn-button", id: this.buttonId, "aria-label": this.arialabel, "aria-labelledby": this.arialabelledby, onClick: e => this.handleClick(e), ...this.getAttributes(), ref: (el) => (this.buttonEl = el) }, h("div", { key: '836e8be4f23275acc3e2918f99529ab198802d1a', class: "pn-button-bg" }), h("div", { key: 'ae1b5955bbff42463cb4076fc069daddff7c45f2', class: "pn-button-content" }, h("div", { key: '32e7974f93b3f674ed587419e2cd15e1a7f163d4', class: "pn-button-text", hidden: this.showIconOnly() }, this.label, h("slot", { key: '67672d69b3b7c4192c3533c3d77701c7e75e390a' })), !!this.icon && h("pn-icon", { key: 'b884299835c2844f5e49bb10273490d058f6098d', icon: this.icon })), h("pn-spinner", { key: '5d514b4e8b1a0f434e8b44e9c3ae50ed9d80971c', light: true }), h("div", { key: '2b1a2cc98d6d9e6732b2f479cbc29f88868f498b', class: "pn-button-tooltip", hidden: !this.tooltip, ref: el => (this.tooltipEl = el) }, h("span", { key: '8dd356c33fced3deddea322b48b8fd74c43b902f', class: "pn-button-tooltip-text" }, this.tooltip))))); } static get is() { return "pn-button"; } static get originalStyleUrls() { return { "$": ["pn-button.scss"] }; } static get styleUrls() { return { "$": ["pn-button.css"] }; } static get properties() { return { "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The label of the button, this is the same as using the default slot." }, "attribute": "label", "reflect": false, "defaultValue": "''" }, "appearance": { "type": "string", "mutable": false, "complexType": { "original": "PnButtonAppearance", "resolved": "\"\" | \"light\" | \"warning\"", "references": { "PnButtonAppearance": { "location": "import", "path": "@/index", "id": "src/index.ts::PnButtonAppearance" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Visual" }], "text": "Select the button appearance: default (blue), `light` (white) and `warning` (red)." }, "attribute": "appearance", "reflect": false, "defaultValue": "''" }, "variant": { "type": "string", "mutable": false, "complexType": { "original": "PnButtonVariant", "resolved": "\"\" | \"borderless\" | \"outlined\"", "references": { "PnButtonVariant": { "location": "import", "path": "@/index", "id": "src/index.ts::PnButtonVariant" } } }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Visual" }], "text": "Select the button variant: default (colored background), `outlined` (bordered, no background) and `borderless` (borderless, no background)." }, "attribute": "variant", "reflect": false, "defaultValue": "''" }, "small": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Visual" }], "text": "Use the small button." }, "attribute": "small", "reflect": false, "defaultValue": "false" }, "loading": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Visual" }], "text": "Display the loading indicator." }, "attribute": "loading", "reflect": true, "defaultValue": "false" }, "icon": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "see", "text": "{@link https://portal.postnord.com/web-components/?path=/docs/docs-assets--docs pn-design-assets}" }, { "name": "category", "text": "Icon" }], "text": "The SVG content of the icon you want." }, "attribute": "icon", "reflect": false }, "iconOnly": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "summary", "text": "__You need an `icon` selected, as well as either `tooltip`, `arialabel` or `arialabelledby` for this to work__." }, { "name": "see", "text": "{@link icon }" }, { "name": "category", "text": "Icon" }], "text": "Turn the button into an icon only. Requires `icon` and one of the following props to work: `tooltip`, `arialabel` or `arialabelledby`." }, "attribute": "icon-only", "reflect": false, "defaultValue": "false" }, "leftIcon": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "summary", "text": "__You need an `icon` selected for this to work__." }, { "name": "see", "text": "{@link icon }" }, { "name": "category", "text": "Icon" }], "text": "Place the `icon` to the left of the button." }, "attribute": "left-icon", "reflect": false, "defaultValue": "false" }, "tooltip": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Tooltip" }], "text": "When the user focus/hover the button, the `tooltip` text will show up." }, "attribute": "tooltip", "reflect": false }, "tooltipUp": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "category", "text": "Tooltip" }], "text": "Prefer the tooltip to open upwards. Will still go downwards if there is no space." }, "attribute": "tooltip-up", "reflect": false, "defaultValue": "false" }, "type": { "type": "string", "mutable": false, "complexType": { "original": "'button' | 'reset' | 'submit' | ''", "resolved": "\"\" | \"button\" | \"reset\" | \"submit\"", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Button" }], "text": "Select HTML button type." }, "attribute": "type", "reflect": false, "defaultValue": "'button'" }, "form": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Button" }, { "name": "see", "text": "{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#form HTML button form}" }], "text": "Connect this button to a HTML form." }, "attribute": "form", "reflect": false }, "href": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Link" }], "text": "Pass an href to make the button into link (a-tag)." }, "attribute": "href", "reflect": false }, "rel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Link" }], "text": "The rel attribute of the link." }, "attribute": "rel", "reflect": false }, "target": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Link" }], "text": "The target attribute of the link." }, "attribute": "target", "reflect": false }, "download": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "Link" }], "text": "The download attribute of the link." }, "attribute": "download", "reflect": false }, "buttonId": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML ID." }, "attribute": "button-id", "reflect": false, "defaultValue": "null" }, "arialabel": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-label attribute." }, "attribute": "arialabel", "reflect": false, "defaultValue": "null" }, "arialabelledby": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-labelledby attribute." }, "attribute": "arialabelledby", "reflect": false, "defaultValue": "null" }, "ariacurrent": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-current attribute." }, "attribute": "ariacurrent", "reflect": false, "defaultValue": "null" }, "ariacontrols": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-controls attribute." }, "attribute": "ariacontrols", "reflect": false, "defaultValue": "null" }, "ariapressed": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-pressed attribute." }, "attribute": "ariapressed", "reflect": false, "defaultValue": "null" }, "ariahaspopup": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-haspopup attribute." }, "attribute": "ariahaspopup", "reflect": false, "defaultValue": "null" }, "ariaexpanded": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML aria-expanded attribute." }, "attribute": "ariaexpanded", "reflect": false, "defaultValue": "null" }, "noTab": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [{ "name": "category", "text": "HTML attributes" }], "text": "HTML tabindex." }, "attribute": "no-tab", "reflect": false, "defaultValue": "false" } }; } static get states() { return { "tooltipOpen": {}, "tooltipUpwards": {} }; } static get events() { return [{ "method": "pnClick", "name": "pnClick", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "This event is fired when the `button`/`a` element of the `pn-button` is clicked.\nSetting an eventListener for `click` on the `pn-button` will trigger if you click outside of the button area\nor if the button is `disabled` with the `loading` prop." }, "complexType": { "original": "MouseEvent", "resolved": "MouseEvent", "references": { "MouseEvent": { "location": "global", "id": "global::MouseEvent" } } } }]; } static get elementRef() { return "hostElement"; } static get watchers() { return [{ "propName": "tooltipOpen", "methodName": "openHandler" }, { "propName": "tooltip", "methodName": "iconOnlyHandler" }]; } } //# sourceMappingURL=pn-button.js.map