@limetech/lime-elements
Version:
375 lines (374 loc) • 11.7 kB
JavaScript
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