UNPKG

soft-components

Version:

Simple soft flexible set of web components

295 lines (294 loc) 7.76 kB
import { Component, Host, h, Prop, State, Element, Method, Event, } from '@stencil/core'; import { hasSlot } from '../../../utils/component'; export class ScAccordionItem { constructor() { /** * Heading text. * This will be overwritten by `heading` slot */ this.heading = null; /** * The HTML tag to be applied to the heading text. * This will be overwritten by `heading` slot */ this.headingTag = 'h3'; /** * If expanded height should be automatically calculated. If set, the `--sc-accordion-item-body-max-height` CSS variable will be set automatically to the content height */ this.autoHeight = true; /** * If the accordion item should be opened by default */ this.active = false; this.hasHeadingSlot = true; this.hasArrowSlot = true; } componentWillLoad() { this.hasHeadingSlot = hasSlot(this.el, 'heading'); this.hasArrowSlot = hasSlot(this.el, 'arrow'); } componentDidLoad() { if (this.autoHeight) { this.bodyEl.style.setProperty('--sc-accordion-item-body-max-height', this.bodyEl.scrollHeight + 2 + 'px'); } this.onTransitionEnd(); this.bodyEl.addEventListener('transitionstart', () => { this.onTransitionStart(); }); this.bodyEl.addEventListener('transitionend', () => { this.onTransitionEnd(); }); } onTransitionEnd() { if (this.active) { this.bodyEl.style.overflow = 'auto'; this.opened.emit(); } else { this.bodyEl.style.overflow = 'hidden'; this.bodyEl.style.visibility = 'hidden'; this.closed.emit(); } } onTransitionStart() { if (this.active) { this.bodyEl.style.visibility = 'visible'; this.opening.emit(); } else { this.closing.emit(); } } /** * Toggle open state of accordion item */ async toggle() { if (this.active) { this.close(); } else { this.open(); } } /** * Closes the accordion item */ async close() { this.active = false; } /** * Opens the accordion item. */ async open() { this.active = true; } render() { const { active, autoHeight, headingTag: HeadingTag } = this; return (h(Host, { class: { active, autoHeight } }, h("button", { class: "heading", role: "button", onClick: () => this.toggle() }, this.hasHeadingSlot ? (h("slot", { name: "heading" })) : (h(HeadingTag, { class: "heading-text" }, this.heading)), h("span", { class: "arrow" }, this.hasArrowSlot ? (h("slot", { name: "arrow" })) : (h("svg", { focusable: "false", viewBox: "0 0 24 24", "aria-hidden": "true" }, h("path", { d: "M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" }))))), h("div", { class: "body-container", ref: el => (this.bodyEl = el) }, h("div", { class: "body" }, h("slot", null))))); } static get is() { return "sc-accordion-item"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["sc-accordion-item.scss"] }; } static get styleUrls() { return { "$": ["sc-accordion-item.css"] }; } static get properties() { return { "heading": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "Heading text.\nThis will be overwritten by `heading` slot" }, "attribute": "heading", "reflect": false, "defaultValue": "null" }, "headingTag": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "The HTML tag to be applied to the heading text.\nThis will be overwritten by `heading` slot" }, "attribute": "heading-tag", "reflect": false, "defaultValue": "'h3'" }, "autoHeight": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "If expanded height should be automatically calculated. If set, the `--sc-accordion-item-body-max-height` CSS variable will be set automatically to the content height" }, "attribute": "auto-height", "reflect": false, "defaultValue": "true" }, "active": { "type": "boolean", "mutable": true, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": true, "docs": { "tags": [], "text": "If the accordion item should be opened by default" }, "attribute": "active", "reflect": true, "defaultValue": "false" } }; } static get states() { return { "hasHeadingSlot": {}, "hasArrowSlot": {} }; } static get events() { return [{ "method": "opened", "name": "opened", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when accordion item has opened" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "opening", "name": "opening", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when accordion item started opening" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "closed", "name": "closed", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when accordion item has closed" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }, { "method": "closing", "name": "closing", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Emitted when accordion item started closing" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get methods() { return { "toggle": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "Toggle open state of accordion item", "tags": [] } }, "close": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "Closes the accordion item", "tags": [] } }, "open": { "complexType": { "signature": "() => Promise<void>", "parameters": [], "references": { "Promise": { "location": "global" } }, "return": "Promise<void>" }, "docs": { "text": "Opens the accordion item.", "tags": [] } } }; } static get elementRef() { return "el"; } }