@openremote/or-mwc-components 1.8.0-snapshot.20250725074716 → 1.8.0-snapshot.20250725120001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -32
- package/build.gradle +19 -19
- package/custom-elements.json +4 -4
- package/lib/or-mwc-dialog.js +329 -76
- package/lib/or-mwc-drawer.js +114 -10
- package/lib/or-mwc-input.js +1760 -439
- package/lib/or-mwc-list.js +283 -71
- package/lib/or-mwc-menu.js +237 -45
- package/lib/or-mwc-snackbar.js +141 -17
- package/lib/or-mwc-table.js +685 -245
- package/lib/or-mwc-tabs.js +173 -53
- package/lib/style.js +125 -121
- package/package.json +5 -5
- package/rspack.config.js +7 -7
- package/src/or-mwc-dialog.ts +374 -374
- package/src/or-mwc-drawer.ts +100 -100
- package/src/or-mwc-input.ts +1876 -1876
- package/src/or-mwc-list.ts +335 -335
- package/src/or-mwc-menu.ts +279 -279
- package/src/or-mwc-snackbar.ts +157 -157
- package/src/or-mwc-table.ts +712 -712
- package/src/or-mwc-tabs.ts +175 -175
- package/src/style.ts +125 -125
- package/tsconfig.json +15 -15
- package/tsconfig.tsbuildinfo +1 -1
package/src/or-mwc-menu.ts
CHANGED
|
@@ -1,279 +1,279 @@
|
|
|
1
|
-
import {
|
|
2
|
-
css,
|
|
3
|
-
html,
|
|
4
|
-
LitElement,
|
|
5
|
-
PropertyValues,
|
|
6
|
-
TemplateResult,
|
|
7
|
-
unsafeCSS
|
|
8
|
-
} from "lit";
|
|
9
|
-
import {customElement, property, query} from "lit/decorators.js";
|
|
10
|
-
import {classMap} from 'lit/directives/class-map.js';
|
|
11
|
-
import {MDCMenu} from "@material/menu";
|
|
12
|
-
import {DefaultColor4, DefaultColor8} from "@openremote/core";
|
|
13
|
-
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
import listStyle from "@material/list/dist/mdc.list.css";
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
import menuSurfaceStyle from "@material/menu-surface/dist/mdc.menu-surface.css";
|
|
18
|
-
import {getItemTemplate, getListTemplate, ListItem, ListType, MDCListActionEvent} from "./or-mwc-list";
|
|
19
|
-
import { ref } from 'lit/directives/ref.js';
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
const menuStyle = require("@material/menu/dist/mdc.menu.css");
|
|
22
|
-
|
|
23
|
-
export class OrMwcMenuChangedEvent extends CustomEvent<any[] | any> {
|
|
24
|
-
|
|
25
|
-
public static readonly NAME = "or-mwc-menu-changed";
|
|
26
|
-
|
|
27
|
-
constructor(values: any[] | any) {
|
|
28
|
-
super(OrMwcMenuChangedEvent.NAME, {
|
|
29
|
-
detail: values,
|
|
30
|
-
bubbles: true,
|
|
31
|
-
composed: true
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export class OrMwcMenuClosedEvent extends CustomEvent<void> {
|
|
37
|
-
|
|
38
|
-
public static readonly NAME = "or-mwc-menu-closed";
|
|
39
|
-
|
|
40
|
-
constructor() {
|
|
41
|
-
super(OrMwcMenuClosedEvent.NAME, {
|
|
42
|
-
bubbles: true,
|
|
43
|
-
composed: true
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
declare global {
|
|
49
|
-
export interface HTMLElementEventMap {
|
|
50
|
-
[OrMwcMenuChangedEvent.NAME]: OrMwcMenuChangedEvent;
|
|
51
|
-
[OrMwcMenuClosedEvent.NAME]: OrMwcMenuClosedEvent;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function positionMenuAtElement<T extends OrMwcMenu>(
|
|
56
|
-
menu: T,
|
|
57
|
-
hostElement?: HTMLElement
|
|
58
|
-
): T {
|
|
59
|
-
if (!hostElement) {
|
|
60
|
-
hostElement = document.body;
|
|
61
|
-
}
|
|
62
|
-
const rect = hostElement.getBoundingClientRect();
|
|
63
|
-
|
|
64
|
-
// Applying a style that is calculated from the runtime coordinates of
|
|
65
|
-
// the host element.
|
|
66
|
-
Object.assign(menu.style, {
|
|
67
|
-
position: 'fixed',
|
|
68
|
-
top: `${rect.bottom}px`,
|
|
69
|
-
left: `${rect.left}px`,
|
|
70
|
-
zIndex: '1000',
|
|
71
|
-
display: 'block'
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return menu;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function getContentWithMenuTemplate(content: TemplateResult, menuItems: (ListItem | ListItem[] | null)[], selectedValues: string[] | string | undefined, valueChangedCallback: (values: string[] | string) => void, closedCallback?: () => void, multiSelect = false, translateValues = true, midHeight = false, fullWidth = false, menuId = "menu", fixedToHost = false): TemplateResult {
|
|
78
|
-
let menuRef: OrMwcMenu | null = null; // Reference to the menu
|
|
79
|
-
|
|
80
|
-
const openMenu = (evt: Event) => {
|
|
81
|
-
if (!menuItems) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (fixedToHost && menuRef) {
|
|
86
|
-
const hostElement = evt.currentTarget as HTMLElement;
|
|
87
|
-
|
|
88
|
-
// Using run time coordinates to assign a fixed position to the menu
|
|
89
|
-
positionMenuAtElement(
|
|
90
|
-
menuRef,
|
|
91
|
-
hostElement
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
((evt.currentTarget as Element).parentElement!.lastElementChild as OrMwcMenu).open();
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
return html`
|
|
98
|
-
<span>
|
|
99
|
-
<span @click="${openMenu}">${content}</span>
|
|
100
|
-
${menuItems ? html`<or-mwc-menu ?multiselect="${multiSelect}" @or-mwc-menu-closed="${() => {if (closedCallback) { closedCallback(); }} }" @or-mwc-menu-changed="${(evt: OrMwcMenuChangedEvent) => {if (valueChangedCallback) { valueChangedCallback(evt.detail); }} }" .translateValues="${translateValues}" .values="${selectedValues}" .menuItems="${menuItems}" .midHeight="${midHeight}" .fullWidth="${fullWidth}" id="${menuId}" ${ref(el => (menuRef = el as OrMwcMenu))}></or-mwc-menu>` : ``}
|
|
101
|
-
</span>
|
|
102
|
-
`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// language=CSS
|
|
106
|
-
const style = css`
|
|
107
|
-
:host {
|
|
108
|
-
white-space: nowrap;
|
|
109
|
-
--internal-or-mwc-input-color: var(--or-mwc-input-color, var(--or-app-color4, ${unsafeCSS(DefaultColor4)}));
|
|
110
|
-
--internal-or-mwc-input-text-color: var(--or-mwc-input-text-color, var(--or-app-color8, ${unsafeCSS(DefaultColor8)}));
|
|
111
|
-
|
|
112
|
-
--mdc-theme-primary: var(--internal-or-mwc-input-color);
|
|
113
|
-
--mdc-theme-on-primary: var(--internal-or-mwc-input-text-color);
|
|
114
|
-
--mdc-theme-secondary: var(--internal-or-mwc-input-color);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.mdc-list-item__graphic {
|
|
118
|
-
margin-right: 16px;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
a {
|
|
122
|
-
text-decoration: none;
|
|
123
|
-
color: rgba(0, 0, 0, 0.87);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.mdc-menu-surface-mid-height {
|
|
127
|
-
max-height: calc(45vh - 32px) !important;
|
|
128
|
-
}
|
|
129
|
-
.mdc-menu-surface-full-width {
|
|
130
|
-
width: 100%;
|
|
131
|
-
}
|
|
132
|
-
`;
|
|
133
|
-
|
|
134
|
-
@customElement("or-mwc-menu")
|
|
135
|
-
export class OrMwcMenu extends LitElement {
|
|
136
|
-
|
|
137
|
-
static get styles() {
|
|
138
|
-
return [
|
|
139
|
-
css`${unsafeCSS(listStyle)}`,
|
|
140
|
-
css`${unsafeCSS(menuStyle)}`,
|
|
141
|
-
css`${unsafeCSS(menuSurfaceStyle)}`,
|
|
142
|
-
style
|
|
143
|
-
];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
@property({type: Array})
|
|
147
|
-
public menuItems?: (ListItem | ListItem[] | null)[];
|
|
148
|
-
|
|
149
|
-
@property({type: Array})
|
|
150
|
-
public values?: any[] | any;
|
|
151
|
-
|
|
152
|
-
@property({type: Boolean, attribute: true})
|
|
153
|
-
public multiSelect?: boolean;
|
|
154
|
-
|
|
155
|
-
@property({type: Boolean, attribute: true})
|
|
156
|
-
public visible?: boolean;
|
|
157
|
-
|
|
158
|
-
@property({type: Boolean, attribute: true})
|
|
159
|
-
public translateValues?: boolean;
|
|
160
|
-
|
|
161
|
-
@property({type: Boolean, attribute: false})
|
|
162
|
-
public midHeight?: boolean;
|
|
163
|
-
|
|
164
|
-
@property({type: Boolean, attribute: false})
|
|
165
|
-
public fullWidth?: boolean;
|
|
166
|
-
|
|
167
|
-
@query("#wrapper")
|
|
168
|
-
protected _wrapperElem!: HTMLElement;
|
|
169
|
-
|
|
170
|
-
@query("#menu")
|
|
171
|
-
protected _mdcElem!: HTMLElement;
|
|
172
|
-
|
|
173
|
-
protected _mdcComponent?: MDCMenu;
|
|
174
|
-
|
|
175
|
-
public open() {
|
|
176
|
-
this._mdcComponent!.open = true;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
disconnectedCallback(): void {
|
|
180
|
-
super.disconnectedCallback();
|
|
181
|
-
if (this._mdcComponent) {
|
|
182
|
-
this._mdcComponent.destroy();
|
|
183
|
-
this._mdcComponent = undefined;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
protected render() {
|
|
188
|
-
|
|
189
|
-
if (!this.menuItems || this.menuItems.length === 0) {
|
|
190
|
-
return html``;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const content = this.getItemsTemplate(this.menuItems, this.translateValues);
|
|
194
|
-
const isTwoLine = this.menuItems && this.menuItems.some((item) => item && !Array.isArray(item) && !!item.secondaryText);
|
|
195
|
-
|
|
196
|
-
const classes = {
|
|
197
|
-
'mdc-menu-surface-mid-height': (this.midHeight ? 1 : 0),
|
|
198
|
-
'mdc-menu-surface-full-width': (this.fullWidth ? 1 : 0)
|
|
199
|
-
}
|
|
200
|
-
return html`
|
|
201
|
-
<div id="wrapper" class="mdc-menu-surface--anchor">
|
|
202
|
-
<div class="mdc-menu mdc-menu-surface ${classMap(classes)}" id="menu" @MDCMenuSurface:closed="${this._onMenuClosed}">
|
|
203
|
-
${getListTemplate(ListType.MULTI_TICK, content, isTwoLine, "menu")}
|
|
204
|
-
</div>
|
|
205
|
-
</div>
|
|
206
|
-
`;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
protected getItemsTemplate(items: (ListItem | ListItem[] | null)[], translate?: boolean): TemplateResult {
|
|
210
|
-
|
|
211
|
-
const type = this.multiSelect ? ListType.MULTI_TICK : ListType.PLAIN;
|
|
212
|
-
|
|
213
|
-
return html`
|
|
214
|
-
${items.map((item, index) => {
|
|
215
|
-
|
|
216
|
-
if (Array.isArray(item)) {
|
|
217
|
-
return html`
|
|
218
|
-
<li>
|
|
219
|
-
<ul class="mdc-menu__selection-group">
|
|
220
|
-
${this.getItemsTemplate(item, translate)}
|
|
221
|
-
</ul>
|
|
222
|
-
</li>
|
|
223
|
-
`;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return getItemTemplate(item, index, (Array.isArray(this.values) ? this.values : this.values ? [this.values] : []), type, translate, (e, item) => this._itemClicked(e, item));
|
|
227
|
-
})}`;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
protected firstUpdated(_changedProperties: PropertyValues): void {
|
|
231
|
-
super.firstUpdated(_changedProperties);
|
|
232
|
-
if (this._mdcElem) {
|
|
233
|
-
this._mdcComponent = new MDCMenu(this._mdcElem);
|
|
234
|
-
|
|
235
|
-
// This overrides the standard mdc menu body click capture handler as it doesn't work with webcomponents
|
|
236
|
-
(this._mdcComponent as any).menuSurface_.foundation.handleBodyClick = function (evt: MouseEvent) {
|
|
237
|
-
const el = evt.composedPath()[0]; // Use composed path not evt target to work with webcomponents
|
|
238
|
-
if (this.adapter.isElementInContainer(el)) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
this.close();
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
this._mdcComponent!.quickOpen = true;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
protected updated(_changedProperties: PropertyValues): void {
|
|
249
|
-
if (_changedProperties.has("visible")) {
|
|
250
|
-
this._mdcComponent!.open = this.visible || false;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
protected _onMenuClosed() {
|
|
255
|
-
this.dispatchEvent(new OrMwcMenuClosedEvent());
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
private _itemClicked(e: MouseEvent, item: ListItem) {
|
|
259
|
-
e.stopPropagation();
|
|
260
|
-
const value = item.value;
|
|
261
|
-
|
|
262
|
-
if (!this.multiSelect) {
|
|
263
|
-
this.values = value;
|
|
264
|
-
this._mdcComponent!.open = false;
|
|
265
|
-
} else {
|
|
266
|
-
if (!Array.isArray(this.values)) {
|
|
267
|
-
this.values = this.values ? [this.values] : [];
|
|
268
|
-
}
|
|
269
|
-
const index = this.values.findIndex((v: any) => v === value);
|
|
270
|
-
if (index >= 0) {
|
|
271
|
-
this.values.splice(index, 1);
|
|
272
|
-
} else {
|
|
273
|
-
this.values.push(value);
|
|
274
|
-
}
|
|
275
|
-
this.requestUpdate();
|
|
276
|
-
}
|
|
277
|
-
this.dispatchEvent(new OrMwcMenuChangedEvent(this.values!));
|
|
278
|
-
}
|
|
279
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
css,
|
|
3
|
+
html,
|
|
4
|
+
LitElement,
|
|
5
|
+
PropertyValues,
|
|
6
|
+
TemplateResult,
|
|
7
|
+
unsafeCSS
|
|
8
|
+
} from "lit";
|
|
9
|
+
import {customElement, property, query} from "lit/decorators.js";
|
|
10
|
+
import {classMap} from 'lit/directives/class-map.js';
|
|
11
|
+
import {MDCMenu} from "@material/menu";
|
|
12
|
+
import {DefaultColor4, DefaultColor8} from "@openremote/core";
|
|
13
|
+
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
import listStyle from "@material/list/dist/mdc.list.css";
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import menuSurfaceStyle from "@material/menu-surface/dist/mdc.menu-surface.css";
|
|
18
|
+
import {getItemTemplate, getListTemplate, ListItem, ListType, MDCListActionEvent} from "./or-mwc-list";
|
|
19
|
+
import { ref } from 'lit/directives/ref.js';
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
const menuStyle = require("@material/menu/dist/mdc.menu.css");
|
|
22
|
+
|
|
23
|
+
export class OrMwcMenuChangedEvent extends CustomEvent<any[] | any> {
|
|
24
|
+
|
|
25
|
+
public static readonly NAME = "or-mwc-menu-changed";
|
|
26
|
+
|
|
27
|
+
constructor(values: any[] | any) {
|
|
28
|
+
super(OrMwcMenuChangedEvent.NAME, {
|
|
29
|
+
detail: values,
|
|
30
|
+
bubbles: true,
|
|
31
|
+
composed: true
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class OrMwcMenuClosedEvent extends CustomEvent<void> {
|
|
37
|
+
|
|
38
|
+
public static readonly NAME = "or-mwc-menu-closed";
|
|
39
|
+
|
|
40
|
+
constructor() {
|
|
41
|
+
super(OrMwcMenuClosedEvent.NAME, {
|
|
42
|
+
bubbles: true,
|
|
43
|
+
composed: true
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
declare global {
|
|
49
|
+
export interface HTMLElementEventMap {
|
|
50
|
+
[OrMwcMenuChangedEvent.NAME]: OrMwcMenuChangedEvent;
|
|
51
|
+
[OrMwcMenuClosedEvent.NAME]: OrMwcMenuClosedEvent;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function positionMenuAtElement<T extends OrMwcMenu>(
|
|
56
|
+
menu: T,
|
|
57
|
+
hostElement?: HTMLElement
|
|
58
|
+
): T {
|
|
59
|
+
if (!hostElement) {
|
|
60
|
+
hostElement = document.body;
|
|
61
|
+
}
|
|
62
|
+
const rect = hostElement.getBoundingClientRect();
|
|
63
|
+
|
|
64
|
+
// Applying a style that is calculated from the runtime coordinates of
|
|
65
|
+
// the host element.
|
|
66
|
+
Object.assign(menu.style, {
|
|
67
|
+
position: 'fixed',
|
|
68
|
+
top: `${rect.bottom}px`,
|
|
69
|
+
left: `${rect.left}px`,
|
|
70
|
+
zIndex: '1000',
|
|
71
|
+
display: 'block'
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return menu;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function getContentWithMenuTemplate(content: TemplateResult, menuItems: (ListItem | ListItem[] | null)[], selectedValues: string[] | string | undefined, valueChangedCallback: (values: string[] | string) => void, closedCallback?: () => void, multiSelect = false, translateValues = true, midHeight = false, fullWidth = false, menuId = "menu", fixedToHost = false): TemplateResult {
|
|
78
|
+
let menuRef: OrMwcMenu | null = null; // Reference to the menu
|
|
79
|
+
|
|
80
|
+
const openMenu = (evt: Event) => {
|
|
81
|
+
if (!menuItems) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (fixedToHost && menuRef) {
|
|
86
|
+
const hostElement = evt.currentTarget as HTMLElement;
|
|
87
|
+
|
|
88
|
+
// Using run time coordinates to assign a fixed position to the menu
|
|
89
|
+
positionMenuAtElement(
|
|
90
|
+
menuRef,
|
|
91
|
+
hostElement
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
((evt.currentTarget as Element).parentElement!.lastElementChild as OrMwcMenu).open();
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return html`
|
|
98
|
+
<span>
|
|
99
|
+
<span @click="${openMenu}">${content}</span>
|
|
100
|
+
${menuItems ? html`<or-mwc-menu ?multiselect="${multiSelect}" @or-mwc-menu-closed="${() => {if (closedCallback) { closedCallback(); }} }" @or-mwc-menu-changed="${(evt: OrMwcMenuChangedEvent) => {if (valueChangedCallback) { valueChangedCallback(evt.detail); }} }" .translateValues="${translateValues}" .values="${selectedValues}" .menuItems="${menuItems}" .midHeight="${midHeight}" .fullWidth="${fullWidth}" id="${menuId}" ${ref(el => (menuRef = el as OrMwcMenu))}></or-mwc-menu>` : ``}
|
|
101
|
+
</span>
|
|
102
|
+
`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// language=CSS
|
|
106
|
+
const style = css`
|
|
107
|
+
:host {
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
--internal-or-mwc-input-color: var(--or-mwc-input-color, var(--or-app-color4, ${unsafeCSS(DefaultColor4)}));
|
|
110
|
+
--internal-or-mwc-input-text-color: var(--or-mwc-input-text-color, var(--or-app-color8, ${unsafeCSS(DefaultColor8)}));
|
|
111
|
+
|
|
112
|
+
--mdc-theme-primary: var(--internal-or-mwc-input-color);
|
|
113
|
+
--mdc-theme-on-primary: var(--internal-or-mwc-input-text-color);
|
|
114
|
+
--mdc-theme-secondary: var(--internal-or-mwc-input-color);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.mdc-list-item__graphic {
|
|
118
|
+
margin-right: 16px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
a {
|
|
122
|
+
text-decoration: none;
|
|
123
|
+
color: rgba(0, 0, 0, 0.87);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.mdc-menu-surface-mid-height {
|
|
127
|
+
max-height: calc(45vh - 32px) !important;
|
|
128
|
+
}
|
|
129
|
+
.mdc-menu-surface-full-width {
|
|
130
|
+
width: 100%;
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
|
|
134
|
+
@customElement("or-mwc-menu")
|
|
135
|
+
export class OrMwcMenu extends LitElement {
|
|
136
|
+
|
|
137
|
+
static get styles() {
|
|
138
|
+
return [
|
|
139
|
+
css`${unsafeCSS(listStyle)}`,
|
|
140
|
+
css`${unsafeCSS(menuStyle)}`,
|
|
141
|
+
css`${unsafeCSS(menuSurfaceStyle)}`,
|
|
142
|
+
style
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@property({type: Array})
|
|
147
|
+
public menuItems?: (ListItem | ListItem[] | null)[];
|
|
148
|
+
|
|
149
|
+
@property({type: Array})
|
|
150
|
+
public values?: any[] | any;
|
|
151
|
+
|
|
152
|
+
@property({type: Boolean, attribute: true})
|
|
153
|
+
public multiSelect?: boolean;
|
|
154
|
+
|
|
155
|
+
@property({type: Boolean, attribute: true})
|
|
156
|
+
public visible?: boolean;
|
|
157
|
+
|
|
158
|
+
@property({type: Boolean, attribute: true})
|
|
159
|
+
public translateValues?: boolean;
|
|
160
|
+
|
|
161
|
+
@property({type: Boolean, attribute: false})
|
|
162
|
+
public midHeight?: boolean;
|
|
163
|
+
|
|
164
|
+
@property({type: Boolean, attribute: false})
|
|
165
|
+
public fullWidth?: boolean;
|
|
166
|
+
|
|
167
|
+
@query("#wrapper")
|
|
168
|
+
protected _wrapperElem!: HTMLElement;
|
|
169
|
+
|
|
170
|
+
@query("#menu")
|
|
171
|
+
protected _mdcElem!: HTMLElement;
|
|
172
|
+
|
|
173
|
+
protected _mdcComponent?: MDCMenu;
|
|
174
|
+
|
|
175
|
+
public open() {
|
|
176
|
+
this._mdcComponent!.open = true;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
disconnectedCallback(): void {
|
|
180
|
+
super.disconnectedCallback();
|
|
181
|
+
if (this._mdcComponent) {
|
|
182
|
+
this._mdcComponent.destroy();
|
|
183
|
+
this._mdcComponent = undefined;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected render() {
|
|
188
|
+
|
|
189
|
+
if (!this.menuItems || this.menuItems.length === 0) {
|
|
190
|
+
return html``;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const content = this.getItemsTemplate(this.menuItems, this.translateValues);
|
|
194
|
+
const isTwoLine = this.menuItems && this.menuItems.some((item) => item && !Array.isArray(item) && !!item.secondaryText);
|
|
195
|
+
|
|
196
|
+
const classes = {
|
|
197
|
+
'mdc-menu-surface-mid-height': (this.midHeight ? 1 : 0),
|
|
198
|
+
'mdc-menu-surface-full-width': (this.fullWidth ? 1 : 0)
|
|
199
|
+
}
|
|
200
|
+
return html`
|
|
201
|
+
<div id="wrapper" class="mdc-menu-surface--anchor">
|
|
202
|
+
<div class="mdc-menu mdc-menu-surface ${classMap(classes)}" id="menu" @MDCMenuSurface:closed="${this._onMenuClosed}">
|
|
203
|
+
${getListTemplate(ListType.MULTI_TICK, content, isTwoLine, "menu")}
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
`;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
protected getItemsTemplate(items: (ListItem | ListItem[] | null)[], translate?: boolean): TemplateResult {
|
|
210
|
+
|
|
211
|
+
const type = this.multiSelect ? ListType.MULTI_TICK : ListType.PLAIN;
|
|
212
|
+
|
|
213
|
+
return html`
|
|
214
|
+
${items.map((item, index) => {
|
|
215
|
+
|
|
216
|
+
if (Array.isArray(item)) {
|
|
217
|
+
return html`
|
|
218
|
+
<li>
|
|
219
|
+
<ul class="mdc-menu__selection-group">
|
|
220
|
+
${this.getItemsTemplate(item, translate)}
|
|
221
|
+
</ul>
|
|
222
|
+
</li>
|
|
223
|
+
`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return getItemTemplate(item, index, (Array.isArray(this.values) ? this.values : this.values ? [this.values] : []), type, translate, (e, item) => this._itemClicked(e, item));
|
|
227
|
+
})}`;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
protected firstUpdated(_changedProperties: PropertyValues): void {
|
|
231
|
+
super.firstUpdated(_changedProperties);
|
|
232
|
+
if (this._mdcElem) {
|
|
233
|
+
this._mdcComponent = new MDCMenu(this._mdcElem);
|
|
234
|
+
|
|
235
|
+
// This overrides the standard mdc menu body click capture handler as it doesn't work with webcomponents
|
|
236
|
+
(this._mdcComponent as any).menuSurface_.foundation.handleBodyClick = function (evt: MouseEvent) {
|
|
237
|
+
const el = evt.composedPath()[0]; // Use composed path not evt target to work with webcomponents
|
|
238
|
+
if (this.adapter.isElementInContainer(el)) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
this.close();
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
this._mdcComponent!.quickOpen = true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
protected updated(_changedProperties: PropertyValues): void {
|
|
249
|
+
if (_changedProperties.has("visible")) {
|
|
250
|
+
this._mdcComponent!.open = this.visible || false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
protected _onMenuClosed() {
|
|
255
|
+
this.dispatchEvent(new OrMwcMenuClosedEvent());
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private _itemClicked(e: MouseEvent, item: ListItem) {
|
|
259
|
+
e.stopPropagation();
|
|
260
|
+
const value = item.value;
|
|
261
|
+
|
|
262
|
+
if (!this.multiSelect) {
|
|
263
|
+
this.values = value;
|
|
264
|
+
this._mdcComponent!.open = false;
|
|
265
|
+
} else {
|
|
266
|
+
if (!Array.isArray(this.values)) {
|
|
267
|
+
this.values = this.values ? [this.values] : [];
|
|
268
|
+
}
|
|
269
|
+
const index = this.values.findIndex((v: any) => v === value);
|
|
270
|
+
if (index >= 0) {
|
|
271
|
+
this.values.splice(index, 1);
|
|
272
|
+
} else {
|
|
273
|
+
this.values.push(value);
|
|
274
|
+
}
|
|
275
|
+
this.requestUpdate();
|
|
276
|
+
}
|
|
277
|
+
this.dispatchEvent(new OrMwcMenuChangedEvent(this.values!));
|
|
278
|
+
}
|
|
279
|
+
}
|