@schukai/monster 4.14.0 → 4.15.0
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
CHANGED
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.1","@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.
|
1
|
+
{"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.7.1","@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.15.0"}
|
@@ -23,6 +23,9 @@ import { clone } from "../../util/clone.mjs";
|
|
23
23
|
import { ColumnBarStyleSheet } from "./stylesheet/column-bar.mjs";
|
24
24
|
import { createPopper } from "@popperjs/core";
|
25
25
|
import { getLocaleOfDocument } from "../../dom/locale.mjs";
|
26
|
+
import {hasObjectLink} from "../../dom/attributes.mjs";
|
27
|
+
import {customElementUpdaterLinkSymbol} from "../../dom/constants.mjs";
|
28
|
+
import {getGlobalObject} from "../../types/global.mjs";
|
26
29
|
|
27
30
|
export { ColumnBar };
|
28
31
|
|
@@ -56,6 +59,12 @@ const dotsContainerElementSymbol = Symbol("dotsContainerElement");
|
|
56
59
|
*/
|
57
60
|
const popperInstanceSymbol = Symbol("popperInstance");
|
58
61
|
|
62
|
+
/**
|
63
|
+
* @private
|
64
|
+
* @type {symbol}
|
65
|
+
*/
|
66
|
+
const closeEventHandlerSymbol = Symbol("closeEventHandler");
|
67
|
+
|
59
68
|
/**
|
60
69
|
* A column bar for a datatable
|
61
70
|
*
|
@@ -72,7 +81,18 @@ class ColumnBar extends CustomElement {
|
|
72
81
|
* @return {symbol}
|
73
82
|
*/
|
74
83
|
static get [instanceSymbol]() {
|
75
|
-
return Symbol.for("@schukai/monster/components/column-bar");
|
84
|
+
return Symbol.for("@schukai/monster/components/column-bar@@instance");
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* This method is called to customize the component.
|
89
|
+
* @returns {Map<unknown, unknown>}
|
90
|
+
*/
|
91
|
+
get customization() {
|
92
|
+
return new Map([
|
93
|
+
...super.customization,
|
94
|
+
["templateFormatter.i18n", true],
|
95
|
+
]);
|
76
96
|
}
|
77
97
|
|
78
98
|
/**
|
@@ -83,24 +103,61 @@ class ColumnBar extends CustomElement {
|
|
83
103
|
*
|
84
104
|
* @property {Object} templates Template definitions
|
85
105
|
* @property {string} templates.main Main template
|
86
|
-
* @property {object}
|
87
|
-
* @property {
|
106
|
+
* @property {object} labels Locale definitions
|
107
|
+
* @property {string} locale.settings The text for the settings button
|
88
108
|
*/
|
89
109
|
get defaults() {
|
90
|
-
|
110
|
+
return Object.assign({}, super.defaults, {
|
91
111
|
templates: {
|
92
112
|
main: getTemplate(),
|
93
113
|
},
|
94
|
-
|
114
|
+
labels: getTranslations(),
|
95
115
|
|
96
116
|
columns: [],
|
97
117
|
});
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Called every time the element is added to the DOM. Useful for running initialization code.
|
122
|
+
* @return {void}
|
123
|
+
* @since 4.14.0
|
124
|
+
*/
|
125
|
+
connectedCallback() {
|
126
|
+
super.connectedCallback();
|
127
|
+
|
128
|
+
this[closeEventHandlerSymbol] = (event) => {
|
129
|
+
const path = event.composedPath();
|
130
|
+
const isOutsideElement = !path.includes(this);
|
131
|
+
const isOutsideShadow = !path.includes(this.shadowRoot);
|
132
|
+
|
133
|
+
if (isOutsideElement && isOutsideShadow && this[settingsLayerElementSymbol]) {
|
134
|
+
this[settingsLayerElementSymbol].classList.remove("visible");
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
getGlobalObject("document").addEventListener("click" , this[closeEventHandlerSymbol]);
|
139
|
+
getGlobalObject("document").addEventListener("touch" , this[closeEventHandlerSymbol]);
|
98
140
|
|
99
|
-
return obj;
|
100
141
|
}
|
101
142
|
|
102
143
|
/**
|
144
|
+
* Called every time the element is removed from the DOM. Useful for running clean up code.
|
103
145
|
*
|
146
|
+
* @return {void}
|
147
|
+
* @since 4.14.0
|
148
|
+
*/
|
149
|
+
disconnectedCallback() {
|
150
|
+
super.disconnectedCallback();
|
151
|
+
|
152
|
+
if(this[closeEventHandlerSymbol]) {
|
153
|
+
getGlobalObject("document").removeEventListener("click", this[closeEventHandlerSymbol]);
|
154
|
+
getGlobalObject("document").removeEventListener("touch", this[closeEventHandlerSymbol]);
|
155
|
+
this[closeEventHandlerSymbol] = null;
|
156
|
+
}
|
157
|
+
|
158
|
+
}
|
159
|
+
|
160
|
+
/**
|
104
161
|
* @return {string}
|
105
162
|
*/
|
106
163
|
static getTag() {
|
@@ -133,43 +190,47 @@ class ColumnBar extends CustomElement {
|
|
133
190
|
function getTranslations() {
|
134
191
|
const locale = getLocaleOfDocument();
|
135
192
|
switch (locale.language) {
|
136
|
-
case "de":
|
137
|
-
return {
|
138
|
-
|
139
|
-
};
|
140
|
-
case "
|
141
|
-
return {
|
142
|
-
|
143
|
-
};
|
144
|
-
case "
|
145
|
-
return {
|
146
|
-
|
147
|
-
};
|
148
|
-
case "
|
149
|
-
return {
|
150
|
-
|
151
|
-
};
|
152
|
-
case "
|
153
|
-
return {
|
154
|
-
|
155
|
-
};
|
156
|
-
case "
|
157
|
-
return {
|
158
|
-
|
159
|
-
};
|
160
|
-
case "
|
161
|
-
return {
|
162
|
-
|
163
|
-
};
|
164
|
-
case "
|
165
|
-
return {
|
166
|
-
|
167
|
-
};
|
168
|
-
|
193
|
+
case "de": // German
|
194
|
+
return { settings: "Einstellungen" };
|
195
|
+
case "fr": // French
|
196
|
+
return { settings: "Paramètres" };
|
197
|
+
case "es": // Spanish
|
198
|
+
return { settings: "Configuración" };
|
199
|
+
case "zh": // Mandarin (Chinese)
|
200
|
+
return { settings: "设置" };
|
201
|
+
case "hi": // Hindi
|
202
|
+
return { settings: "सेटिंग्स" };
|
203
|
+
case "bn": // Bengali
|
204
|
+
return { settings: "সেটিংস" };
|
205
|
+
case "pt": // Portuguese
|
206
|
+
return { settings: "Configurações" };
|
207
|
+
case "ru": // Russian
|
208
|
+
return { settings: "Настройки" };
|
209
|
+
case "ja": // Japanese
|
210
|
+
return { settings: "設定" };
|
211
|
+
case "pa": // Western Punjabi
|
212
|
+
return { settings: "ਸੈਟਿੰਗਾਂ" };
|
213
|
+
case "mr": // Marathi
|
214
|
+
return { settings: "सेटिंग्ज" };
|
215
|
+
case "it": // Italian
|
216
|
+
return { settings: "Impostazioni" };
|
217
|
+
case "nl": // Dutch
|
218
|
+
return { settings: "Instellingen" };
|
219
|
+
case "sv": // Swedish
|
220
|
+
return { settings: "Inställningar" };
|
221
|
+
case "pl": // Polish
|
222
|
+
return { settings: "Ustawienia" };
|
223
|
+
case "da": // Danish
|
224
|
+
return { settings: "Indstillinger" };
|
225
|
+
case "fi": // Finnish
|
226
|
+
return { settings: "Asetukset" };
|
227
|
+
case "no": // Norwegian
|
228
|
+
return { settings: "Innstillinger" };
|
229
|
+
case "cs": // Czech
|
230
|
+
return { settings: "Nastavení" };
|
231
|
+
default: // English fallback
|
169
232
|
case "en":
|
170
|
-
return {
|
171
|
-
settings: "Settings",
|
172
|
-
};
|
233
|
+
return { settings: "Settings" };
|
173
234
|
}
|
174
235
|
}
|
175
236
|
|
@@ -325,7 +386,7 @@ function getTemplate() {
|
|
325
386
|
<div data-monster-role="control" part="control" data-monster-select-this="true" data-monster-attributes="class path:columns | has-entries | ?::hidden">
|
326
387
|
<ul data-monster-insert="dots path:columns"
|
327
388
|
data-monster-role="dots"></ul>
|
328
|
-
<a href="#" data-monster-role="settings-button"
|
389
|
+
<a href="#" data-monster-role="settings-button">i18n{settings}</a>
|
329
390
|
<div data-monster-role="settings-layer">
|
330
391
|
<div data-monster-insert="column path:columns" data-monster-role="settings-popup-list">
|
331
392
|
</div>
|
@@ -390,6 +390,7 @@ class Select extends CustomControl {
|
|
390
390
|
* @property {"radio"|"checkbox"} type Selection mode: "radio" for single, "checkbox" for multiple.
|
391
391
|
* @property {string} name Name of the hidden form field for form submission.
|
392
392
|
* @property {string|null} url URL to dynamically fetch options via HTTP when opening or filtering.
|
393
|
+
* @property {Object} lookup Configuration for lookup requests.
|
393
394
|
* @property {string} lookup.url URL template with ${filter} placeholder to fetch only selected entries on init when `url` is set and either `features.lazyLoad` or `filter.mode==="remote"`.
|
394
395
|
* @property {boolean} lookup.grouping Group lookup requests: true to fetch all selected values in one request, false to fetch each individually.
|
395
396
|
* @property {string} fetch.redirect Fetch redirect mode (e.g. "error").
|
@@ -1354,51 +1355,64 @@ function getTranslations() {
|
|
1354
1355
|
function lookupSelection() {
|
1355
1356
|
const self = this;
|
1356
1357
|
|
1357
|
-
|
1358
|
-
const
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1358
|
+
const observer = new IntersectionObserver((entries, obs) => {
|
1359
|
+
for (const entry of entries) {
|
1360
|
+
if (entry.isIntersecting) {
|
1361
|
+
console.log("IntersectionObserver: entry.target is visible");
|
1362
|
+
obs.disconnect(); // Only observe once
|
1362
1363
|
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1364
|
+
setTimeout(() => {
|
1365
|
+
const selection = self.getOption("selection");
|
1366
|
+
if (selection.length === 0) {
|
1367
|
+
return;
|
1368
|
+
}
|
1366
1369
|
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
+
if (self[isLoadingSymbol] === true) {
|
1371
|
+
return;
|
1372
|
+
}
|
1370
1373
|
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
url = lookupUrl;
|
1375
|
-
}
|
1374
|
+
if (self[lazyLoadDoneSymbol] === true) {
|
1375
|
+
return;
|
1376
|
+
}
|
1376
1377
|
|
1377
|
-
|
1378
|
+
let url = self.getOption("url");
|
1379
|
+
const lookupUrl = self.getOption("lookup.url");
|
1380
|
+
if (lookupUrl !== null) {
|
1381
|
+
url = lookupUrl;
|
1382
|
+
}
|
1378
1383
|
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1384
|
+
self[cleanupOptionsListSymbol] = false;
|
1385
|
+
|
1386
|
+
if (self.getOption("lookup.grouping") === true) {
|
1387
|
+
filterFromRemoteByValue
|
1388
|
+
.call(
|
1389
|
+
self,
|
1390
|
+
url,
|
1391
|
+
selection.map((s) => s?.["value"]),
|
1392
|
+
)
|
1393
|
+
.catch((e) => {
|
1394
|
+
addErrorAttribute(self, e);
|
1395
|
+
});
|
1396
|
+
return;
|
1397
|
+
}
|
1391
1398
|
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1399
|
+
for (const s of selection) {
|
1400
|
+
if (s?.["value"]) {
|
1401
|
+
filterFromRemoteByValue.call(self, url, s["value"]).catch((e) => {
|
1402
|
+
addErrorAttribute(self, e);
|
1403
|
+
});
|
1404
|
+
}
|
1405
|
+
}
|
1406
|
+
}, 100);
|
1397
1407
|
}
|
1398
1408
|
}
|
1399
|
-
},
|
1409
|
+
}, { threshold: 0.1 });
|
1410
|
+
|
1411
|
+
// Beobachte das Element selbst (dieses Element muss im DOM sein)
|
1412
|
+
observer.observe(self);
|
1400
1413
|
}
|
1401
1414
|
|
1415
|
+
|
1402
1416
|
/**
|
1403
1417
|
*
|
1404
1418
|
* @param url
|