@schukai/monster 4.38.1 → 4.38.2
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/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/source/components/data/kpi-tile.mjs +55 -55
- package/source/components/datatable/style/filter-button.pcss +2 -0
- package/source/components/datatable/stylesheet/filter-button.mjs +1 -1
- package/source/components/tree-menu/tree-menu.mjs +446 -446
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.2","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.38.
|
1
|
+
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.2","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.38.2"}
|
@@ -14,8 +14,8 @@ import { instanceSymbol } from "../../constants.mjs";
|
|
14
14
|
import { ATTRIBUTE_ROLE } from "../../dom/constants.mjs";
|
15
15
|
import { CustomElement } from "../../dom/customelement.mjs";
|
16
16
|
import {
|
17
|
-
|
18
|
-
|
17
|
+
assembleMethodSymbol,
|
18
|
+
registerCustomElement,
|
19
19
|
} from "../../dom/customelement.mjs";
|
20
20
|
import { KpiTileStyleSheet } from "./stylesheet/kpi-tile.mjs";
|
21
21
|
|
@@ -34,62 +34,62 @@ export { KpiTile };
|
|
34
34
|
* @summary A KPI Tile Control that displays key performance indicators in a tile format.
|
35
35
|
*/
|
36
36
|
class KpiTile extends CustomElement {
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
static get [instanceSymbol]() {
|
38
|
+
return Symbol.for("@schukai/monster/components/data/kpi/tile@@instance");
|
39
|
+
}
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
41
|
+
/**
|
42
|
+
* @returns {symbol}
|
43
|
+
* @summary Returns the instance symbol for the KPI Tile control.
|
44
|
+
*/
|
45
|
+
[assembleMethodSymbol]() {
|
46
|
+
super[assembleMethodSymbol]();
|
47
|
+
return this;
|
48
|
+
}
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
50
|
+
/**
|
51
|
+
* To set the option via the HTML Tag use the attribute `data-monster-options-`
|
52
|
+
* with the name of the option.
|
53
|
+
*
|
54
|
+
* @property {Object} templates
|
55
|
+
* @property {string} templates.main The main template for the KPI Tile control.
|
56
|
+
* @property {Object} values
|
57
|
+
* @property {string} values.main The main value displayed in the tile.
|
58
|
+
* @property {string} values.small The small value displayed in the tile.
|
59
|
+
* @property {string} values.top The top value displayed in the tile.
|
60
|
+
* @property {string} values.bottom The bottom value displayed in the tile.
|
61
|
+
* @returns {Object}
|
62
|
+
* @summary Returns the default options for the KPI Tile control.
|
63
|
+
*/
|
64
|
+
get defaults() {
|
65
|
+
return Object.assign({}, super.defaults, {
|
66
|
+
templates: {
|
67
|
+
main: getTemplate(),
|
68
|
+
},
|
69
|
+
values: {
|
70
|
+
main: null,
|
71
|
+
small: null,
|
72
|
+
top: null,
|
73
|
+
bottom: null,
|
74
|
+
},
|
75
|
+
});
|
76
|
+
}
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
78
|
+
/**
|
79
|
+
* @returns {string}
|
80
|
+
* @summary Returns the role of the control.
|
81
|
+
*/
|
82
|
+
static getTag() {
|
83
|
+
return "monster-kpi-tile";
|
84
|
+
}
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
86
|
+
/**
|
87
|
+
* @returns {string}
|
88
|
+
* @summary Returns the role of the control.
|
89
|
+
*/
|
90
|
+
static getCSSStyleSheet() {
|
91
|
+
return [KpiTileStyleSheet];
|
92
|
+
}
|
93
93
|
}
|
94
94
|
|
95
95
|
/**
|
@@ -98,7 +98,7 @@ class KpiTile extends CustomElement {
|
|
98
98
|
* @summary Returns the template for the KPI Tile control.
|
99
99
|
*/
|
100
100
|
function getTemplate() {
|
101
|
-
|
101
|
+
return `
|
102
102
|
<div data-monster-role="control" part="control">
|
103
103
|
<div class="top" data-monster-role="top" part="top" data-monster-replace="path:values.top">—</div>
|
104
104
|
<div data-monster-role="main" part="main" data-monster-replace="path:values.main">—</div>
|
@@ -25,7 +25,7 @@ try {
|
|
25
25
|
FilterButtonStyleSheet.insertRule(
|
26
26
|
`
|
27
27
|
@layer filterbutton {
|
28
|
-
:host{display:flex}[data-monster-role=control] a{align-items:center;background:none;color:var(--monster-color-primary-1);display:flex}:is([data-monster-role=control] a):after{background-color:var(--monster-color-primary-1);content:\"\";display:inline-block;height:16px;margin:0 3px 0 5px;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-filter-square' viewBox='0 0 16 16'%3E%3Cpath d='M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z'/%3E%3Cpath d='M6 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-filter-square' viewBox='0 0 16 16'%3E%3Cpath d='M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z'/%3E%3Cpath d='M6 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5'/%3E%3C/svg%3E\");-webkit-mask-size:cover;mask-size:cover;width:16px}
|
28
|
+
:host{display:flex}[data-monster-role=control]{width:-moz-max-content;width:max-content}[data-monster-role=control] a{align-items:center;background:none;color:var(--monster-color-primary-1);display:flex}:is([data-monster-role=control] a):after{background-color:var(--monster-color-primary-1);content:\"\";display:inline-block;height:16px;margin:0 3px 0 5px;-webkit-mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-filter-square' viewBox='0 0 16 16'%3E%3Cpath d='M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z'/%3E%3Cpath d='M6 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5'/%3E%3C/svg%3E\");mask-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' class='bi bi-filter-square' viewBox='0 0 16 16'%3E%3Cpath d='M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z'/%3E%3Cpath d='M6 11.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5'/%3E%3C/svg%3E\");-webkit-mask-size:cover;mask-size:cover;width:16px}
|
29
29
|
}`,
|
30
30
|
0,
|
31
31
|
);
|
@@ -17,15 +17,15 @@ import { buildTree } from "../../data/buildtree.mjs";
|
|
17
17
|
import { Datasource } from "../datatable/datasource.mjs";
|
18
18
|
import { addAttributeToken } from "../../dom/attributes.mjs";
|
19
19
|
import {
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
ATTRIBUTE_ERRORMESSAGE,
|
21
|
+
ATTRIBUTE_ROLE,
|
22
|
+
ATTRIBUTE_UPDATER_INSERT_REFERENCE,
|
23
23
|
} from "../../dom/constants.mjs";
|
24
24
|
import {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
assembleMethodSymbol,
|
26
|
+
CustomElement,
|
27
|
+
getSlottedElements,
|
28
|
+
registerCustomElement,
|
29
29
|
} from "../../dom/customelement.mjs";
|
30
30
|
import { findTargetElementFromEvent, fireEvent } from "../../dom/events.mjs";
|
31
31
|
import { findElementWithSelectorUpwards } from "../../dom/util.mjs";
|
@@ -36,8 +36,8 @@ import { NodeRecursiveIterator } from "../../types/noderecursiveiterator.mjs";
|
|
36
36
|
import { Observer } from "../../types/observer.mjs";
|
37
37
|
import { validateInstance } from "../../types/validate.mjs";
|
38
38
|
import {
|
39
|
-
|
40
|
-
|
39
|
+
datasourceLinkedElementSymbol,
|
40
|
+
handleDataSourceChanges,
|
41
41
|
} from "../datatable/util.mjs";
|
42
42
|
import { ATTRIBUTE_INTEND } from "./../constants.mjs";
|
43
43
|
import { CommonStyleSheet } from "../stylesheet/common.mjs";
|
@@ -83,355 +83,355 @@ const firstRunDoneSymbol = Symbol("firstRunDone");
|
|
83
83
|
* @fires entries-imported
|
84
84
|
*/
|
85
85
|
class TreeMenu extends CustomElement {
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
86
|
+
/**
|
87
|
+
* This method is called by the `instanceof` operator.
|
88
|
+
* @return {symbol}
|
89
|
+
*/
|
90
|
+
static get [instanceSymbol]() {
|
91
|
+
return Symbol.for("@schukai/monster/components/tree-menu@@instance");
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
*/
|
96
|
+
constructor() {
|
97
|
+
super();
|
98
|
+
this[preventChangeSymbol] = false;
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* This method is called internal and should not be called directly.
|
103
|
+
*
|
104
|
+
* The defaults can be set either directly in the object or via an attribute in the HTML tag.
|
105
|
+
* The value of the attribute `data-monster-options` in the HTML tag must be a JSON string.
|
106
|
+
*
|
107
|
+
* ```
|
108
|
+
* <monster-treemenu data-monster-options="{}"></monster-treemenu>
|
109
|
+
* ```
|
110
|
+
*
|
111
|
+
* Since 1.18.0 the JSON can be specified as a DataURI.
|
112
|
+
*
|
113
|
+
* ```
|
114
|
+
* new Monster.Types.DataUrl(btoa(JSON.stringify({
|
115
|
+
* shadowMode: 'open',
|
116
|
+
* })),'application/json',true).toString()
|
117
|
+
* ```
|
118
|
+
* @property {Object} templates Template definitions
|
119
|
+
* @property {string} templates.main Main template
|
120
|
+
* @property {Datasource} datasource data source
|
121
|
+
* @property {Object} mapping
|
122
|
+
* @property {String} mapping.selector Path to select the appropriate entries
|
123
|
+
* @property {String} mapping.labelTemplate template with the label placeholders in the form ${name}, where name is the key
|
124
|
+
* @property {String} mapping.keyTemplate template with the key placeholders in the form ${name}, where name is the key
|
125
|
+
* @property {String} mapping.rootReferences the root references
|
126
|
+
* @property {String} mapping.idTemplate template with the id placeholders in the form ${name}, where name is the key
|
127
|
+
* @property {String} mapping.parentKey the parent key
|
128
|
+
* @property {String} mapping.selection the selection
|
129
|
+
* @property {Function} mapping.filter a filter function to filter the entries
|
130
|
+
* @property {Object} classes
|
131
|
+
* @property {String} classes.control the class for the control element
|
132
|
+
* @property {String} classes.label the class for the label element
|
133
|
+
* @property {Object} actions
|
134
|
+
* @property {Function} actions.open the action to open an entry (arguments, etnry, index, event)
|
135
|
+
* @property {Function} actions.close the action to close an entry (arguments, etnry, index, event)
|
136
|
+
* @property {Function} actions.select the action to select an entry (arguments, etnry, index, event)
|
137
|
+
*/
|
138
|
+
get defaults() {
|
139
|
+
return Object.assign({}, super.defaults, {
|
140
|
+
classes: {
|
141
|
+
control: "monster-theme-primary-1",
|
142
|
+
label: "monster-theme-primary-1",
|
143
|
+
},
|
144
|
+
|
145
|
+
mapping: {
|
146
|
+
rootReferences: ["0", undefined, null],
|
147
|
+
idTemplate: "id",
|
148
|
+
parentKey: "parent",
|
149
|
+
selector: "*",
|
150
|
+
labelTemplate: "",
|
151
|
+
valueTemplate: "",
|
152
|
+
iconTemplate: "",
|
153
|
+
filter: undefined,
|
154
|
+
},
|
155
|
+
|
156
|
+
templates: {
|
157
|
+
main: getTemplate(),
|
158
|
+
},
|
159
|
+
|
160
|
+
datasource: {
|
161
|
+
selector: null,
|
162
|
+
},
|
163
|
+
|
164
|
+
actions: {
|
165
|
+
open: null,
|
166
|
+
close: null,
|
167
|
+
select: (entry) => {
|
168
|
+
console.warn("select action is not defined", entry);
|
169
|
+
},
|
170
|
+
},
|
171
|
+
|
172
|
+
data: [],
|
173
|
+
entries: [],
|
174
|
+
});
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* @return {void}
|
179
|
+
*/
|
180
|
+
[assembleMethodSymbol]() {
|
181
|
+
super[assembleMethodSymbol]();
|
182
|
+
|
183
|
+
queueMicrotask(() => {
|
184
|
+
initControlReferences.call(this);
|
185
|
+
initEventHandler.call(this);
|
186
|
+
initObserver.call(this);
|
187
|
+
copyIconMap.call(this);
|
188
|
+
});
|
189
|
+
}
|
190
|
+
|
191
|
+
/**
|
192
|
+
* This method is called internal and should not be called directly.
|
193
|
+
*
|
194
|
+
* @return {CSSStyleSheet[]}
|
195
|
+
*/
|
196
|
+
static getCSSStyleSheet() {
|
197
|
+
return [CommonStyleSheet, TreeMenuStyleSheet];
|
198
|
+
}
|
199
|
+
|
200
|
+
/**
|
201
|
+
* This method is called internal and should not be called directly.
|
202
|
+
*
|
203
|
+
* @return {string}
|
204
|
+
*/
|
205
|
+
static getTag() {
|
206
|
+
return "monster-tree-menu";
|
207
|
+
}
|
208
|
+
|
209
|
+
/**
|
210
|
+
* @param {string} value
|
211
|
+
* @param value
|
212
|
+
*/
|
213
|
+
selectEntry(value) {
|
214
|
+
this.shadowRoot
|
215
|
+
.querySelectorAll("[data-monster-role=entry]")
|
216
|
+
.forEach((entry) => {
|
217
|
+
entry.classList.remove("selected");
|
218
|
+
});
|
219
|
+
|
220
|
+
value = String(value);
|
221
|
+
|
222
|
+
const entries = this.getOption("entries");
|
223
|
+
const index = entries.findIndex((entry) => entry.value === value);
|
224
|
+
|
225
|
+
if (index === -1) {
|
226
|
+
return;
|
227
|
+
}
|
228
|
+
|
229
|
+
const currentNode = this.shadowRoot.querySelector(
|
230
|
+
"[data-monster-insert-reference=entries-" + index + "]",
|
231
|
+
);
|
232
|
+
|
233
|
+
if (!currentNode) {
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
|
237
|
+
currentNode.click();
|
238
|
+
|
239
|
+
let intend = Number.parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
|
240
|
+
|
241
|
+
if (intend > 0) {
|
242
|
+
const refSet = new Set();
|
243
|
+
let ref = currentNode.previousElementSibling;
|
244
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
245
|
+
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
246
|
+
|
247
|
+
if (Number.isNaN(i)) {
|
248
|
+
break;
|
249
|
+
}
|
250
|
+
|
251
|
+
if (i < intend) {
|
252
|
+
if (ref.getAttribute("data-monster-state") !== "open") {
|
253
|
+
ref.click();
|
254
|
+
}
|
255
|
+
|
256
|
+
if (i === 0) {
|
257
|
+
break;
|
258
|
+
}
|
259
|
+
intend = i;
|
260
|
+
}
|
261
|
+
ref = ref.previousElementSibling;
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
265
|
}
|
266
266
|
|
267
267
|
/**
|
268
268
|
* @private
|
269
269
|
*/
|
270
270
|
function copyIconMap() {
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
271
|
+
const nodes = getSlottedElements.call(this, "svg", null);
|
272
|
+
if (nodes.size > 0) {
|
273
|
+
for (const node of nodes) {
|
274
|
+
this.shadowRoot.appendChild(node);
|
275
|
+
}
|
276
|
+
}
|
277
277
|
}
|
278
278
|
|
279
279
|
/**
|
280
280
|
* @private
|
281
281
|
*/
|
282
282
|
function initEventHandler() {
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
283
|
+
const selector = this.getOption("datasource.selector");
|
284
|
+
|
285
|
+
if (isString(selector)) {
|
286
|
+
const element = findElementWithSelectorUpwards(this, selector);
|
287
|
+
if (element === null) {
|
288
|
+
throw new Error("the selector must match exactly one element");
|
289
|
+
}
|
290
|
+
|
291
|
+
if (!(element instanceof HTMLElement)) {
|
292
|
+
throw new TypeError("the element must be an HTMLElement");
|
293
|
+
}
|
294
|
+
|
295
|
+
customElements.whenDefined(element.tagName.toLocaleLowerCase()).then(() => {
|
296
|
+
if (!(element instanceof Datasource)) {
|
297
|
+
throw new TypeError("the element must be a datasource");
|
298
|
+
}
|
299
|
+
|
300
|
+
this[datasourceLinkedElementSymbol] = element;
|
301
|
+
|
302
|
+
handleDataSourceChanges.call(this);
|
303
|
+
element.datasource.attachObserver(
|
304
|
+
new Observer(handleDataSourceChanges.bind(this)),
|
305
|
+
);
|
306
|
+
|
307
|
+
this.attachObserver(
|
308
|
+
new Observer(() => {
|
309
|
+
if (this[preventChangeSymbol] === true) {
|
310
|
+
return;
|
311
|
+
}
|
312
|
+
this[preventChangeSymbol] = true;
|
313
|
+
queueMicrotask(() => {
|
314
|
+
importEntries.call(this);
|
315
|
+
});
|
316
|
+
}),
|
317
|
+
);
|
318
|
+
});
|
319
|
+
}
|
320
|
+
|
321
|
+
this[openEntryEventHandlerSymbol] = (event) => {
|
322
|
+
const container = findTargetElementFromEvent(
|
323
|
+
event,
|
324
|
+
ATTRIBUTE_ROLE,
|
325
|
+
"entry",
|
326
|
+
);
|
327
|
+
|
328
|
+
if (!(container instanceof HTMLElement)) {
|
329
|
+
return;
|
330
|
+
}
|
331
|
+
|
332
|
+
const index = container
|
333
|
+
.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
|
334
|
+
.split("-")
|
335
|
+
.pop();
|
336
|
+
|
337
|
+
const currentEntry = this.getOption("entries." + index);
|
338
|
+
|
339
|
+
if (currentEntry["has-children"] === false) {
|
340
|
+
const doAction = this.getOption("actions.select");
|
341
|
+
|
342
|
+
this.shadowRoot
|
343
|
+
.querySelectorAll("[data-monster-role=entry].selected")
|
344
|
+
.forEach((entry) => {
|
345
|
+
entry.classList.remove("selected");
|
346
|
+
});
|
347
|
+
|
348
|
+
let intend = currentEntry.intend;
|
349
|
+
if (intend > 0) {
|
350
|
+
let ref = container.previousElementSibling;
|
351
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
352
|
+
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
353
|
+
|
354
|
+
if (Number.isNaN(i)) {
|
355
|
+
break;
|
356
|
+
}
|
357
|
+
|
358
|
+
if (i < intend) {
|
359
|
+
ref.classList.add("selected");
|
360
|
+
if (i === 0) {
|
361
|
+
break;
|
362
|
+
}
|
363
|
+
intend = i;
|
364
|
+
}
|
365
|
+
ref = ref.previousElementSibling;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
|
369
|
+
container.classList.add("selected");
|
370
|
+
|
371
|
+
if (isFunction(doAction)) {
|
372
|
+
doAction.call(this, currentEntry, index, event);
|
373
|
+
}
|
374
|
+
return;
|
375
|
+
}
|
376
|
+
|
377
|
+
const currentState = this.getOption("entries." + index + ".state");
|
378
|
+
|
379
|
+
const newState = currentState === "close" ? "open" : "close";
|
380
|
+
|
381
|
+
const doAction = this.getOption("actions." + newState);
|
382
|
+
if (isFunction(doAction)) {
|
383
|
+
doAction.call(this, this.getOption("entries." + index), index);
|
384
|
+
}
|
385
|
+
|
386
|
+
this.setOption("entries." + index + ".state", newState);
|
387
|
+
const newVisibility = newState === "open" ? "visible" : "hidden";
|
388
|
+
|
389
|
+
if (container.hasAttribute(ATTRIBUTE_INTEND)) {
|
390
|
+
const intend = container.getAttribute(ATTRIBUTE_INTEND);
|
391
|
+
let ref = container.nextElementSibling;
|
392
|
+
const childIntend = parseInt(intend) + 1;
|
393
|
+
|
394
|
+
const cmp = (a, b) => {
|
395
|
+
if (newState === "open") {
|
396
|
+
return a === b;
|
397
|
+
}
|
398
|
+
|
399
|
+
return a >= b;
|
400
|
+
};
|
401
|
+
|
402
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
403
|
+
const refIntend = ref.getAttribute(ATTRIBUTE_INTEND);
|
404
|
+
|
405
|
+
if (!cmp(Number.parseInt(refIntend), childIntend)) {
|
406
|
+
if (refIntend === intend) {
|
407
|
+
break;
|
408
|
+
}
|
409
|
+
ref = ref.nextElementSibling;
|
410
|
+
continue;
|
411
|
+
}
|
412
|
+
|
413
|
+
const refIndex = ref
|
414
|
+
.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
|
415
|
+
.split("-")
|
416
|
+
.pop();
|
417
|
+
|
418
|
+
this.setOption("entries." + refIndex + ".visibility", newVisibility);
|
419
|
+
|
420
|
+
if (newState === "close") {
|
421
|
+
this.setOption("entries." + refIndex + ".state", "close");
|
422
|
+
}
|
423
|
+
|
424
|
+
ref = ref.nextElementSibling;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
};
|
428
|
+
|
429
|
+
const types = this.getOption("toggleEventType", ["click"]);
|
430
|
+
for (const [, type] of Object.entries(types)) {
|
431
|
+
this.shadowRoot.addEventListener(type, this[openEntryEventHandlerSymbol]);
|
432
|
+
}
|
433
|
+
|
434
|
+
return this;
|
435
435
|
}
|
436
436
|
|
437
437
|
/**
|
@@ -449,81 +449,81 @@ function initObserver() {}
|
|
449
449
|
* @private
|
450
450
|
*/
|
451
451
|
function importEntries() {
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
452
|
+
const data = this.getOption("data");
|
453
|
+
this[internalNodesSymbol] = new Map();
|
454
|
+
|
455
|
+
const mappingOptions = this.getOption("mapping", {});
|
456
|
+
|
457
|
+
const filter = mappingOptions?.["filter"];
|
458
|
+
const rootReferences = mappingOptions?.["rootReferences"];
|
459
|
+
|
460
|
+
const id = this.getOption("mapping.idTemplate");
|
461
|
+
const parentKey = this.getOption("mapping.parentKey");
|
462
|
+
|
463
|
+
const selector = mappingOptions?.["selector"];
|
464
|
+
|
465
|
+
let filteredData;
|
466
|
+
if (this[firstRunDoneSymbol] !== true) {
|
467
|
+
filteredData = data?.filter(
|
468
|
+
(entry) =>
|
469
|
+
!entry[parentKey] ||
|
470
|
+
entry[parentKey] === null ||
|
471
|
+
entry[parentKey] === undefined ||
|
472
|
+
entry[parentKey] === 0,
|
473
|
+
);
|
474
|
+
setTimeout(() => {
|
475
|
+
this[firstRunDoneSymbol] = true;
|
476
|
+
importEntries.call(this);
|
477
|
+
}, 0);
|
478
|
+
} else {
|
479
|
+
filteredData = data;
|
480
|
+
}
|
481
|
+
|
482
|
+
let nodes;
|
483
|
+
try {
|
484
|
+
nodes = buildTree(filteredData, selector, id, parentKey, {
|
485
|
+
filter,
|
486
|
+
rootReferences,
|
487
|
+
});
|
488
|
+
} catch (error) {
|
489
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
490
|
+
return this;
|
491
|
+
}
|
492
|
+
|
493
|
+
const options = [];
|
494
|
+
for (const node of nodes) {
|
495
|
+
const iterator = new NodeRecursiveIterator(node);
|
496
|
+
for (const n of iterator) {
|
497
|
+
const formattedValues = formatKeyLabel.call(this, n);
|
498
|
+
|
499
|
+
const label = formattedValues?.label;
|
500
|
+
const value = formattedValues?.value;
|
501
|
+
const icon = formattedValues?.icon;
|
502
|
+
const intend = n.level;
|
503
|
+
|
504
|
+
const visibility = intend > 0 ? "hidden" : "visible";
|
505
|
+
const state = "close";
|
506
|
+
|
507
|
+
this[internalNodesSymbol].set(value, n);
|
508
|
+
|
509
|
+
options.push({
|
510
|
+
value,
|
511
|
+
label,
|
512
|
+
icon,
|
513
|
+
intend,
|
514
|
+
state,
|
515
|
+
visibility,
|
516
|
+
["has-children"]: n.hasChildNodes(),
|
517
|
+
});
|
518
|
+
}
|
519
|
+
}
|
520
|
+
|
521
|
+
queueMicrotask(() => {
|
522
|
+
this.setOption("entries", options);
|
523
|
+
fireEvent(this, "entries-imported");
|
524
|
+
});
|
525
|
+
|
526
|
+
return this;
|
527
527
|
}
|
528
528
|
|
529
529
|
/**
|
@@ -533,27 +533,27 @@ function importEntries() {
|
|
533
533
|
* @private
|
534
534
|
*/
|
535
535
|
function formatKeyLabel(node) {
|
536
|
-
|
536
|
+
validateInstance(node, Node);
|
537
537
|
|
538
|
-
|
539
|
-
|
540
|
-
|
538
|
+
const label = new Formatter(node.value).format(
|
539
|
+
this.getOption("mapping.labelTemplate"),
|
540
|
+
);
|
541
541
|
|
542
|
-
|
543
|
-
|
544
|
-
|
542
|
+
const value = new Formatter(node.value).format(
|
543
|
+
this.getOption("mapping.valueTemplate"),
|
544
|
+
);
|
545
545
|
|
546
|
-
|
547
|
-
|
548
|
-
|
546
|
+
const iconID = new Formatter(node.value).format(
|
547
|
+
this.getOption("mapping.iconTemplate"),
|
548
|
+
);
|
549
549
|
|
550
|
-
|
550
|
+
const icon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><use xlink:href="#${iconID}"></use></svg>`;
|
551
551
|
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
552
|
+
return {
|
553
|
+
value,
|
554
|
+
label,
|
555
|
+
icon,
|
556
|
+
};
|
557
557
|
}
|
558
558
|
|
559
559
|
/**
|
@@ -561,15 +561,15 @@ function formatKeyLabel(node) {
|
|
561
561
|
* @return {TreeMenu}
|
562
562
|
*/
|
563
563
|
function initControlReferences() {
|
564
|
-
|
565
|
-
|
566
|
-
|
564
|
+
if (!this.shadowRoot) {
|
565
|
+
throw new Error("no shadow-root is defined");
|
566
|
+
}
|
567
567
|
|
568
|
-
|
569
|
-
|
570
|
-
|
568
|
+
this[controlElementSymbol] = this.shadowRoot.querySelector(
|
569
|
+
"[data-monster-role=control]",
|
570
|
+
);
|
571
571
|
|
572
|
-
|
572
|
+
return this;
|
573
573
|
}
|
574
574
|
|
575
575
|
/**
|
@@ -577,8 +577,8 @@ function initControlReferences() {
|
|
577
577
|
* @return {string}
|
578
578
|
*/
|
579
579
|
function getTemplate() {
|
580
|
-
|
581
|
-
|
580
|
+
// language=HTML
|
581
|
+
return `
|
582
582
|
<slot></slot>
|
583
583
|
|
584
584
|
<template id="entries">
|