soft-components
Version:
Simple soft flexible set of web components
295 lines (294 loc) • 7.76 kB
JavaScript
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"; }
}