/*! * All material copyright ESRI, All Rights Reserved, unless otherwise specified. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details. * v1.0.0-beta.97 */ import { h, Host } from "@stencil/core"; import { guid } from "../../utils/guid"; export class Loader { constructor() { //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- /** When `true`, the component is active. */ this.active = false; /** When `true`, displays smaller and appears to the left of the text. */ this.inline = false; /** Specifies the size of the component. */ this.scale = "m"; /** The component's value. Valid only for `"determinate"` indicators. Percent complete of 100. */ this.value = 0; /** Text that displays under the component's indicator. */ this.text = ""; /** * Disables spacing around the component. * * @deprecated Use `--calcite-loader-padding` CSS variable instead. */ this.noPadding = false; } //-------------------------------------------------------------------------- // // Lifecycle // //-------------------------------------------------------------------------- render() { const { el, inline, label, scale, text, type, value } = this; const id = el.id || guid(); const radiusRatio = 0.45; const size = inline ? this.getInlineSize(scale) : this.getSize(scale); const radius = size * radiusRatio; const viewbox = `0 0 ${size} ${size}`; const isDeterminate = type === "determinate"; const circumference = 2 * radius * Math.PI; const progress = (value / 100) * circumference; const remaining = circumference - progress; const valueNow = Math.floor(value); const hostAttributes = { "aria-valuenow": valueNow, "aria-valuemin": 0, "aria-valuemax": 100, complete: valueNow === 100 }; const svgAttributes = { r: radius, cx: size / 2, cy: size / 2 }; const determinateStyle = { "stroke-dasharray": `${progress} ${remaining}` }; return (h(Host, { "aria-label": label, id: id, role: "progressbar", ...(isDeterminate ? hostAttributes : {}) }, h("div", { class: "loader__svgs" }, h("svg", { class: "loader__svg loader__svg--1", viewBox: viewbox }, h("circle", { ...svgAttributes })), h("svg", { class: "loader__svg loader__svg--2", viewBox: viewbox }, h("circle", { ...svgAttributes })), h("svg", { class: "loader__svg loader__svg--3", viewBox: viewbox, ...(isDeterminate ? { style: determinateStyle } : {}) }, h("circle", { ...svgAttributes }))), text && h("div", { class: "loader__text" }, text), isDeterminate && h("div", { class: "loader__percentage" }, value))); } //-------------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------------- /** * Return the proper sizes based on the scale property * * @param scale */ getSize(scale) { return { s: 32, m: 56, l: 80 }[scale]; } getInlineSize(scale) { return { s: 12, m: 16, l: 20 }[scale]; } static get is() { return "calcite-loader"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["loader.scss"] }; } static get styleUrls() { return { "$": ["loader.css"] }; } static get properties() { return { "active": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "When `true`, the component is active." }, "attribute": "active", "reflect": true, "defaultValue": "false" }, "inline": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "When `true`, displays smaller and appears to the left of the text." }, "attribute": "inline", "reflect": true, "defaultValue": "false" }, "label": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": true, "optional": false, "docs": { "tags": [], "text": "Accessible name for the component." }, "attribute": "label", "reflect": false }, "scale": { "type": "string", "mutable": false, "complexType": { "original": "Scale", "resolved": "\"l\" | \"m\" | \"s\"", "references": { "Scale": { "location": "import", "path": "../interfaces" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies the size of the component." }, "attribute": "scale", "reflect": true, "defaultValue": "\"m\"" }, "type": { "type": "string", "mutable": false, "complexType": { "original": "\"indeterminate\" | \"determinate\"", "resolved": "\"determinate\" | \"indeterminate\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies the component type.\n\nUse `\"indeterminate\"` if finding actual progress value is impossible." }, "attribute": "type", "reflect": true }, "value": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The component's value. Valid only for `\"determinate\"` indicators. Percent complete of 100." }, "attribute": "value", "reflect": false, "defaultValue": "0" }, "text": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Text that displays under the component's indicator." }, "attribute": "text", "reflect": false, "defaultValue": "\"\"" }, "noPadding": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [{ "name": "deprecated", "text": "Use `--calcite-loader-padding` CSS variable instead." }], "text": "Disables spacing around the component." }, "attribute": "no-padding", "reflect": true, "defaultValue": "false" } }; } static get elementRef() { return "el"; } }