UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

297 lines (296 loc) • 9.09 kB
/*! * All material copyright ESRI, All Rights Reserved, unless otherwise specified. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details. */ import { Component, Element, Event, h, Listen, Prop } from "@stencil/core"; /** * @slot - A slot for adding `calcite-accordion-item`s. `calcite-accordion` cannot be nested, however calcite-accordion-item`s can. */ export class Accordion { constructor() { //-------------------------------------------------------------------------- // // Public Properties // //-------------------------------------------------------------------------- /** specify the appearance - default (containing border), or minimal (no containing border), defaults to default */ this.appearance = "default"; /** specify the placement of the icon in the header, defaults to end */ this.iconPosition = "end"; /** specify the type of the icon in the header, defaults to chevron */ this.iconType = "chevron"; /** specify the scale of accordion, defaults to m */ this.scale = "m"; /** specify the selection mode - multi (allow any number of open items), single (allow one open item), * or single-persist (allow and require one open item), defaults to multi */ this.selectionMode = "multi"; //-------------------------------------------------------------------------- // // Private State/Props // //-------------------------------------------------------------------------- /** created list of Accordion items */ this.items = []; /** keep track of whether the items have been sorted so we don't re-sort */ this.sorted = false; this.sortItems = (items) => items.sort((a, b) => a.position - b.position).map((a) => a.item); } //-------------------------------------------------------------------------- // // Lifecycle // //-------------------------------------------------------------------------- componentDidLoad() { if (!this.sorted) { this.items = this.sortItems(this.items); this.sorted = true; } } render() { return (h("div", { class: { "accordion--transparent": this.appearance === "transparent", "accordion--minimal": this.appearance === "minimal", accordion: this.appearance === "default" } }, h("slot", null))); } //-------------------------------------------------------------------------- // // Event Listeners // //-------------------------------------------------------------------------- calciteAccordionItemKeyEvent(e) { const item = e.detail.item; const parent = e.detail.parent; if (this.el === parent) { const key = item.key; const itemToFocus = e.target; const isFirstItem = this.itemIndex(itemToFocus) === 0; const isLastItem = this.itemIndex(itemToFocus) === this.items.length - 1; switch (key) { case "ArrowDown": if (isLastItem) { this.focusFirstItem(); } else { this.focusNextItem(itemToFocus); } break; case "ArrowUp": if (isFirstItem) { this.focusLastItem(); } else { this.focusPrevItem(itemToFocus); } break; case "Home": this.focusFirstItem(); break; case "End": this.focusLastItem(); break; } } } registerCalciteAccordionItem(e) { const item = { item: e.target, parent: e.detail.parent, position: e.detail.position }; if (this.el === item.parent) { this.items.push(item); } } updateActiveItemOnChange(event) { this.requestedAccordionItem = event.detail.requestedAccordionItem; this.calciteAccordionChange.emit({ requestedAccordionItem: this.requestedAccordionItem }); } //-------------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------------- focusFirstItem() { const firstItem = this.items[0]; this.focusElement(firstItem); } focusLastItem() { const lastItem = this.items[this.items.length - 1]; this.focusElement(lastItem); } focusNextItem(e) { const index = this.itemIndex(e); const nextItem = this.items[index + 1] || this.items[0]; this.focusElement(nextItem); } focusPrevItem(e) { const index = this.itemIndex(e); const prevItem = this.items[index - 1] || this.items[this.items.length - 1]; this.focusElement(prevItem); } itemIndex(e) { return this.items.indexOf(e); } focusElement(item) { const target = item; target.focus(); } static get is() { return "calcite-accordion"; } static get encapsulation() { return "shadow"; } static get originalStyleUrls() { return { "$": ["accordion.scss"] }; } static get styleUrls() { return { "$": ["accordion.css"] }; } static get properties() { return { "appearance": { "type": "string", "mutable": false, "complexType": { "original": "AccordionAppearance", "resolved": "\"default\" | \"minimal\" | \"transparent\"", "references": { "AccordionAppearance": { "location": "import", "path": "./interfaces" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "specify the appearance - default (containing border), or minimal (no containing border), defaults to default" }, "attribute": "appearance", "reflect": true, "defaultValue": "\"default\"" }, "iconPosition": { "type": "string", "mutable": false, "complexType": { "original": "Position", "resolved": "\"end\" | \"start\"", "references": { "Position": { "location": "import", "path": "../interfaces" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "specify the placement of the icon in the header, defaults to end" }, "attribute": "icon-position", "reflect": true, "defaultValue": "\"end\"" }, "iconType": { "type": "string", "mutable": false, "complexType": { "original": "\"chevron\" | \"caret\" | \"plus-minus\"", "resolved": "\"caret\" | \"chevron\" | \"plus-minus\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "specify the type of the icon in the header, defaults to chevron" }, "attribute": "icon-type", "reflect": true, "defaultValue": "\"chevron\"" }, "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": "specify the scale of accordion, defaults to m" }, "attribute": "scale", "reflect": true, "defaultValue": "\"m\"" }, "selectionMode": { "type": "string", "mutable": false, "complexType": { "original": "\"multi\" | \"single\" | \"single-persist\"", "resolved": "\"multi\" | \"single\" | \"single-persist\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "specify the selection mode - multi (allow any number of open items), single (allow one open item),\nor single-persist (allow and require one open item), defaults to multi" }, "attribute": "selection-mode", "reflect": true, "defaultValue": "\"multi\"" } }; } static get events() { return [{ "method": "calciteAccordionChange", "name": "calciteAccordionChange", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [{ "name": "internal", "text": undefined }], "text": "" }, "complexType": { "original": "any", "resolved": "any", "references": {} } }]; } static get elementRef() { return "el"; } static get listeners() { return [{ "name": "calciteAccordionItemKeyEvent", "method": "calciteAccordionItemKeyEvent", "target": undefined, "capture": false, "passive": false }, { "name": "calciteAccordionItemRegister", "method": "registerCalciteAccordionItem", "target": undefined, "capture": false, "passive": false }, { "name": "calciteAccordionItemSelect", "method": "updateActiveItemOnChange", "target": undefined, "capture": false, "passive": false }]; } }