@limetech/lime-elements
Version:
256 lines (255 loc) • 9.46 kB
JavaScript
import { MDCMenu } from "@material/menu";
import { MDCRipple } from "@material/ripple";
import { strings as menuStrings } from "@material/menu/constants";
import { h, } from "@stencil/core";
import { MenuListRenderer } from "./menu-list-renderer";
const { SELECTED_EVENT } = menuStrings;
/**
* @private
*/
export class MenuList {
constructor() {
/**
* Size of the icons in the list
*/
this.iconSize = 'small';
this.MenuListRenderer = new MenuListRenderer();
this.setup = () => {
this.setupMenu();
this.setupListeners();
};
this.setupMenu = () => {
if (this.mdcMenu) {
this.teardown();
this.mdcMenu = null;
}
const element = this.element.shadowRoot.querySelector('.mdc-menu');
if (!element) {
return;
}
this.mdcMenu = new MDCMenu(element);
this.mdcMenu.hasTypeahead = true;
this.mdcMenu.wrapFocus = true;
// eslint-disable-next-line sonarjs/constructor-for-side-effects
for (const item of this.mdcMenu.items)
new MDCRipple(item);
};
this.setupListeners = () => {
if (!this.mdcMenu) {
return;
}
this.mdcMenu.unlisten(SELECTED_EVENT, this.handleMenuSelect);
this.mdcMenu.listen(SELECTED_EVENT, this.handleMenuSelect);
};
this.teardown = () => {
var _a, _b;
(_a = this.mdcMenu) === null || _a === void 0 ? void 0 : _a.unlisten(SELECTED_EVENT, this.handleMenuSelect);
(_b = this.mdcMenu) === null || _b === void 0 ? void 0 : _b.destroy();
};
this.handleMenuSelect = (event) => {
this.handleSingleSelect(event.detail.index);
};
this.handleSingleSelect = (index) => {
const MenuItems = this.items.filter(this.isMenuItem);
if (MenuItems[index].disabled) {
return;
}
const selectedItem = MenuItems.find((item) => {
return !!item.selected;
});
let interactedItem;
if (selectedItem) {
interactedItem = Object.assign(Object.assign({}, selectedItem), { selected: false });
this.select.emit(interactedItem);
}
if (MenuItems[index] !== selectedItem) {
interactedItem = Object.assign(Object.assign({}, MenuItems[index]), { selected: false });
this.select.emit(interactedItem);
}
this.interact.emit(interactedItem);
};
this.isMenuItem = (item) => {
return !('separator' in item);
};
}
connectedCallback() {
this.setup();
}
disconnectedCallback() {
this.teardown();
}
componentDidLoad() {
this.setup();
this.triggerIconColorWarning();
}
render() {
this.config = {
badgeIcons: this.badgeIcons,
iconSize: this.iconSize,
};
const html = this.MenuListRenderer.render(this.items, this.config);
return h("div", { key: '1c044c711555d155c5559f8b787a3bbad09b7526', class: "mdc-menu mdc-menu-surface" }, html);
}
itemsChanged() {
setTimeout(() => {
this.setup();
}, 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, has no visual effect anymore, and will soon be removed! Use the new `Icon` interface, and instead of `iconColor: 'color-name'` write `icon: { name: 'icon-name', color: 'color-name' }`.");
}
}
static get is() { return "limel-menu-list"; }
static get encapsulation() { return "shadow"; }
static get delegatesFocus() { return true; }
static get originalStyleUrls() {
return {
"$": ["menu-list.scss"]
};
}
static get styleUrls() {
return {
"$": ["menu-list.css"]
};
}
static get properties() {
return {
"items": {
"type": "unknown",
"mutable": false,
"complexType": {
"original": "Array<MenuItem | ListSeparator>",
"resolved": "(ListSeparator | MenuItem<any>)[]",
"references": {
"Array": {
"location": "global",
"id": "global::Array"
},
"MenuItem": {
"location": "import",
"path": "../menu/menu.types",
"id": "src/components/menu/menu.types.ts::MenuItem",
"referenceLocation": "MenuItem"
},
"ListSeparator": {
"location": "import",
"path": "../list-item/list-item.types",
"id": "src/components/list-item/list-item.types.ts::ListSeparator",
"referenceLocation": "ListSeparator"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "List of items to display"
},
"getter": false,
"setter": false
},
"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"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "badge-icons"
},
"iconSize": {
"type": "string",
"mutable": false,
"complexType": {
"original": "IconSize",
"resolved": "\"large\" | \"medium\" | \"small\" | \"x-small\"",
"references": {
"IconSize": {
"location": "import",
"path": "../icon/icon.types",
"id": "src/components/icon/icon.types.ts::IconSize",
"referenceLocation": "IconSize"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Size of the icons in the list"
},
"getter": false,
"setter": false,
"reflect": false,
"attribute": "icon-size",
"defaultValue": "'small'"
}
};
}
static get events() {
return [{
"method": "select",
"name": "select",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Fired when a new value has been selected from the list."
},
"complexType": {
"original": "MenuItem",
"resolved": "MenuItem<any>",
"references": {
"MenuItem": {
"location": "import",
"path": "../menu/menu.types",
"id": "src/components/menu/menu.types.ts::MenuItem",
"referenceLocation": "MenuItem"
}
}
}
}, {
"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": "MenuItem",
"resolved": "MenuItem<any>",
"references": {
"MenuItem": {
"location": "import",
"path": "../menu/menu.types",
"id": "src/components/menu/menu.types.ts::MenuItem",
"referenceLocation": "MenuItem"
}
}
}
}];
}
static get elementRef() { return "element"; }
static get watchers() {
return [{
"propName": "items",
"methodName": "itemsChanged"
}];
}
}