UNPKG

@limetech/lime-elements

Version:
375 lines (374 loc) • 11.7 kB
import { MDCList } from '@material/list'; import { strings as listStrings } from '@material/list/constants'; import { h, Host, } from '@stencil/core'; import { ListRenderer } from './list-renderer'; const { ACTION_EVENT } = listStrings; /** * @exampleComponent limel-example-list * @exampleComponent limel-example-list-secondary * @exampleComponent limel-example-list-separator * @exampleComponent limel-example-list-icons * @exampleComponent limel-example-list-badge-icons * @exampleComponent limel-example-list-pictures * @exampleComponent limel-example-list-selectable * @exampleComponent limel-example-list-checkbox-icons * @exampleComponent limel-example-list-radio-button-icons * @exampleComponent limel-example-list-action * @exampleComponent limel-example-list-striped * @exampleComponent limel-example-list-badge-icons-with-multiple-lines * @exampleComponent limel-example-list-grid * @exampleComponent limel-example-list-primary-component */ export class List { constructor() { this.listRenderer = new ListRenderer(); this.setup = () => { this.setupList(); this.setupListeners(); }; this.setupList = () => { if (this.mdcList) { this.teardown(); this.mdcList = null; } const element = this.element.shadowRoot.querySelector('.mdc-deprecated-list'); if (!element) { return; } this.mdcList = new MDCList(element); this.mdcList.hasTypeahead = true; }; this.setupListeners = () => { if (!this.mdcList) { return; } this.mdcList.unlisten(ACTION_EVENT, this.handleAction); this.selectable = ['selectable', 'radio', 'checkbox'].includes(this.type); this.multiple = this.type === 'checkbox'; if (!this.selectable) { return; } this.mdcList.listen(ACTION_EVENT, this.handleAction); this.mdcList.singleSelection = !this.multiple; }; this.teardown = () => { var _a, _b; (_a = this.mdcList) === null || _a === void 0 ? void 0 : _a.unlisten(ACTION_EVENT, this.handleAction); (_b = this.mdcList) === null || _b === void 0 ? void 0 : _b.destroy(); }; this.handleAction = (event) => { if (!this.multiple) { this.handleSingleSelect(event.detail.index); return; } this.handleMultiSelect(event.detail.index); }; this.handleSingleSelect = (index) => { const listItems = this.items.filter(this.isListItem); if (listItems[index].disabled) { return; } const selectedItem = listItems.find((item) => { return !!item.selected; }); let interactedItem; if (selectedItem) { if (this.type !== 'radio') { this.mdcList.selectedIndex = -1; } interactedItem = Object.assign(Object.assign({}, selectedItem), { selected: false }); this.change.emit(interactedItem); } if (listItems[index] !== selectedItem) { interactedItem = Object.assign(Object.assign({}, listItems[index]), { selected: true }); this.change.emit(interactedItem); } this.interact.emit(interactedItem); }; this.handleMultiSelect = (index) => { const listItems = this.items.filter(this.isListItem); if (listItems[index].disabled) { return; } const selectedItems = listItems .filter((item, listIndex) => { if (listIndex === index) { // This is the item that was selected or deselected, // so we negate its previous selection status. return !item.selected; } // This is an item that didn't change, so we keep its selection status. return item.selected; }) .map((item) => { return Object.assign(Object.assign({}, item), { selected: true }); }); this.change.emit(selectedItems); this.interact.emit(Object.assign({}, selectedItems[index])); }; this.isListItem = (item) => { return !('separator' in item); }; this.items = undefined; this.badgeIcons = undefined; this.iconSize = 'small'; this.type = undefined; this.maxLinesSecondaryText = 3; } connectedCallback() { this.setup(); } disconnectedCallback() { this.teardown(); } componentDidLoad() { this.setup(); this.triggerIconColorWarning(); } render() { var _a; this.config = { badgeIcons: this.badgeIcons, type: this.type, iconSize: this.iconSize, }; let maxLinesSecondaryText = +((_a = this.maxLinesSecondaryText) === null || _a === void 0 ? void 0 : _a.toFixed()); if (this.maxLinesSecondaryText < 1) { maxLinesSecondaryText = 1; } const html = this.listRenderer.render(this.items, this.config); return (h(Host, { style: { '--maxLinesSecondaryText': `${maxLinesSecondaryText}`, } }, html)); } handleType() { this.setupListeners(); } itemsChanged() { if (!this.mdcList) { return; } setTimeout(() => { this.setup(); const listItems = this.items.filter(this.isListItem); if (this.multiple) { this.mdcList.selectedIndex = listItems .filter((item) => item.selected) .map((item) => listItems.indexOf(item)); } else { const selectedIndex = listItems.findIndex((item) => item.selected); if (selectedIndex === -1) { this.mdcList.initializeListType(); } else { this.mdcList.selectedIndex = selectedIndex; } } }, 0); } triggerIconColorWarning() { var _a; if ((_a = this.items) === null || _a === void 0 ? void 0 : _a.some((item) => 'iconColor' in item)) { console.warn("The `iconColor` prop is deprecated now! Use the new `Icon` interface and instead of `iconColor: 'color-name'` write `icon {name: 'icon-name', color: 'color-name'}`."); } } static get is() { return "limel-list"; } static get encapsulation() { return "shadow"; } static get delegatesFocus() { return true; } static get originalStyleUrls() { return { "$": ["list.scss"] }; } static get styleUrls() { return { "$": ["list.css"] }; } static get properties() { return { "items": { "type": "unknown", "mutable": false, "complexType": { "original": "Array<ListItem | ListSeparator>", "resolved": "(ListSeparator | ListItem<any>)[]", "references": { "Array": { "location": "global" }, "ListItem": { "location": "import", "path": "./list-item.types" }, "ListSeparator": { "location": "import", "path": "./list-item.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "List of items to display" } }, "badgeIcons": { "type": "boolean", "mutable": false, "complexType": { "original": "boolean", "resolved": "boolean", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Set to `true` if the list should display larger icons with a background" }, "attribute": "badge-icons", "reflect": false }, "iconSize": { "type": "string", "mutable": false, "complexType": { "original": "IconSize", "resolved": "\"large\" | \"medium\" | \"small\" | \"x-small\"", "references": { "IconSize": { "location": "import", "path": "../icon/icon.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "Size of the icons in the list" }, "attribute": "icon-size", "reflect": false, "defaultValue": "'small'" }, "type": { "type": "string", "mutable": false, "complexType": { "original": "ListType", "resolved": "\"checkbox\" | \"radio\" | \"selectable\"", "references": { "ListType": { "location": "import", "path": "./list.types" } } }, "required": false, "optional": false, "docs": { "tags": [], "text": "The type of the list, omit to get a regular list. Available types are:\n`selectable`: regular list with single selection.\n`radio`: radio button list with single selection.\n`checkbox`: checkbox list with multiple selection." }, "attribute": "type", "reflect": false }, "maxLinesSecondaryText": { "type": "number", "mutable": false, "complexType": { "original": "number", "resolved": "number", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "By default, lists will display 3 lines of text, and then truncate the rest.\nConsumers can increase or decrease this number by specifying\n`maxLinesSecondaryText`. If consumer enters zero or negative\nnumbers we default to 1; and if they type decimals we round up." }, "attribute": "max-lines-secondary-text", "reflect": false, "defaultValue": "3" } }; } static get events() { return [{ "method": "change", "name": "change", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Fired when a new value has been selected from the list.\nOnly fired if `type` is set to `selectable`, `radio` or `checkbox`." }, "complexType": { "original": "ListItem | ListItem[]", "resolved": "ListItem<any> | ListItem<any>[]", "references": { "ListItem": { "location": "import", "path": "./list-item.types" } } } }, { "method": "select", "name": "select", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Fired when an action has been selected from the action menu of a list item" }, "complexType": { "original": "ListItem | ListItem[]", "resolved": "ListItem<any> | ListItem<any>[]", "references": { "ListItem": { "location": "import", "path": "./list-item.types" } } } }, { "method": "interact", "name": "interact", "bubbles": true, "cancelable": true, "composed": true, "docs": { "tags": [], "text": "Fires when a user interacts with an item in the list (e.g., click,\nkeyboard select)." }, "complexType": { "original": "ListItem", "resolved": "ListItem<any>", "references": { "ListItem": { "location": "import", "path": "./list-item.types" } } } }]; } static get elementRef() { return "element"; } static get watchers() { return [{ "propName": "type", "methodName": "handleType" }, { "propName": "items", "methodName": "itemsChanged" }]; } } //# sourceMappingURL=list.js.map