@schukai/monster 4.128.3 → 4.129.1
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 +3 -0
- package/package.json +1 -1
- package/source/components/datatable/datatable.mjs +4 -1
- package/source/components/datatable/pagination.mjs +39 -1
- package/source/components/form/login.mjs +197 -0
- package/source/components/form/message-state-button.mjs +233 -18
- package/source/components/form/select.mjs +4 -4
- package/source/components/form/style/message-state-button.pcss +46 -3
- package/source/components/form/stylesheet/message-state-button.mjs +7 -14
- package/source/components/form/stylesheet/popper-button.mjs +7 -14
- package/source/components/form/tree-select.mjs +2 -2
- package/source/components/layout/popper.mjs +72 -1
- package/source/components/layout/stylesheet/popper.mjs +7 -14
- package/source/components/style/floating-ui.css +1 -49
- package/source/components/style/floating-ui.pcss +10 -0
- package/source/components/stylesheet/floating-ui.mjs +7 -14
- package/source/dom/customelement.mjs +182 -2
- package/source/dom/util/extract-keys.mjs +46 -10
- package/source/dom/util/init-options-from-attributes.mjs +4 -2
- package/source/dom/util/set-option-from-attribute.mjs +4 -2
- package/source/types/version.mjs +1 -1
- package/test/cases/components/form/login.mjs +168 -0
- package/test/cases/components/form/message-state-button.mjs +272 -0
- package/test/cases/components/form/popper-button.mjs +89 -0
- package/test/cases/components/form/select.mjs +24 -0
- package/test/cases/components/form/tree-select.mjs +22 -1
- package/test/cases/dom/util/extract-keys.mjs +34 -23
- package/test/cases/dom/util/init-options-from-attributes.mjs +21 -0
- package/test/cases/monster.mjs +1 -1
- package/test/web/import.js +1 -0
- package/test/web/test.html +2 -2
- package/test/web/tests.js +9300 -6050
|
@@ -216,4 +216,276 @@ describe("MessageStateButton", function () {
|
|
|
216
216
|
}, 0);
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
|
+
|
|
220
|
+
describe("popper content presentation", function () {
|
|
221
|
+
afterEach(() => {
|
|
222
|
+
let mocks = document.getElementById("mocks");
|
|
223
|
+
mocks.innerHTML = "";
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it("should resolve plain prose content to default popper clipping", function (done) {
|
|
227
|
+
let mocks = document.getElementById("mocks");
|
|
228
|
+
const button = document.createElement("monster-message-state-button");
|
|
229
|
+
button.innerHTML = "Save";
|
|
230
|
+
mocks.appendChild(button);
|
|
231
|
+
|
|
232
|
+
setTimeout(() => {
|
|
233
|
+
try {
|
|
234
|
+
button.setMessage("<div><strong>Saved</strong><p>plain html</p></div>");
|
|
235
|
+
button.showMessage();
|
|
236
|
+
|
|
237
|
+
setTimeout(() => {
|
|
238
|
+
try {
|
|
239
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
240
|
+
const message = button.shadowRoot.querySelector(
|
|
241
|
+
'[data-monster-role="message"]',
|
|
242
|
+
);
|
|
243
|
+
expect(content).to.exist;
|
|
244
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
245
|
+
"both",
|
|
246
|
+
);
|
|
247
|
+
expect(
|
|
248
|
+
content.getAttribute("data-monster-message-layout"),
|
|
249
|
+
).to.equal("prose");
|
|
250
|
+
expect(
|
|
251
|
+
message.getAttribute("data-monster-message-layout"),
|
|
252
|
+
).to.equal("prose");
|
|
253
|
+
done();
|
|
254
|
+
} catch (e) {
|
|
255
|
+
done(e);
|
|
256
|
+
}
|
|
257
|
+
}, 0);
|
|
258
|
+
} catch (e) {
|
|
259
|
+
done(e);
|
|
260
|
+
}
|
|
261
|
+
}, 0);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it("should resolve nested select message content to horizontal clipping only", function (done) {
|
|
265
|
+
let mocks = document.getElementById("mocks");
|
|
266
|
+
const button = document.createElement("monster-message-state-button");
|
|
267
|
+
button.innerHTML = "Save";
|
|
268
|
+
mocks.appendChild(button);
|
|
269
|
+
|
|
270
|
+
setTimeout(() => {
|
|
271
|
+
try {
|
|
272
|
+
const wrapper = document.createElement("div");
|
|
273
|
+
wrapper.appendChild(document.createElement("monster-select"));
|
|
274
|
+
button.setMessage(wrapper);
|
|
275
|
+
button.showMessage();
|
|
276
|
+
|
|
277
|
+
setTimeout(() => {
|
|
278
|
+
try {
|
|
279
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
280
|
+
const message = button.shadowRoot.querySelector(
|
|
281
|
+
'[data-monster-role="message"]',
|
|
282
|
+
);
|
|
283
|
+
expect(content).to.exist;
|
|
284
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
285
|
+
"horizontal",
|
|
286
|
+
);
|
|
287
|
+
expect(
|
|
288
|
+
content.getAttribute("data-monster-message-layout"),
|
|
289
|
+
).to.equal("overlay");
|
|
290
|
+
expect(
|
|
291
|
+
message.getAttribute("data-monster-message-layout"),
|
|
292
|
+
).to.equal("overlay");
|
|
293
|
+
done();
|
|
294
|
+
} catch (e) {
|
|
295
|
+
done(e);
|
|
296
|
+
}
|
|
297
|
+
}, 0);
|
|
298
|
+
} catch (e) {
|
|
299
|
+
done(e);
|
|
300
|
+
}
|
|
301
|
+
}, 0);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("should resolve wide plain content to the wide layout", function (done) {
|
|
305
|
+
let mocks = document.getElementById("mocks");
|
|
306
|
+
const button = document.createElement("monster-message-state-button");
|
|
307
|
+
button.innerHTML = "Save";
|
|
308
|
+
mocks.appendChild(button);
|
|
309
|
+
|
|
310
|
+
setTimeout(() => {
|
|
311
|
+
try {
|
|
312
|
+
const wrapper = document.createElement("div");
|
|
313
|
+
const line = document.createElement("div");
|
|
314
|
+
line.setAttribute(
|
|
315
|
+
"style",
|
|
316
|
+
"white-space: nowrap; overflow-x: auto;",
|
|
317
|
+
);
|
|
318
|
+
line.textContent =
|
|
319
|
+
"this is intentionally a single long line to trigger wide layout";
|
|
320
|
+
wrapper.appendChild(line);
|
|
321
|
+
|
|
322
|
+
button.setMessage(wrapper);
|
|
323
|
+
button.showMessage();
|
|
324
|
+
|
|
325
|
+
setTimeout(() => {
|
|
326
|
+
try {
|
|
327
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
328
|
+
const message = button.shadowRoot.querySelector(
|
|
329
|
+
'[data-monster-role="message"]',
|
|
330
|
+
);
|
|
331
|
+
expect(content).to.exist;
|
|
332
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
333
|
+
"both",
|
|
334
|
+
);
|
|
335
|
+
expect(
|
|
336
|
+
content.getAttribute("data-monster-message-layout"),
|
|
337
|
+
).to.equal("wide");
|
|
338
|
+
expect(
|
|
339
|
+
message.getAttribute("data-monster-message-layout"),
|
|
340
|
+
).to.equal("wide");
|
|
341
|
+
done();
|
|
342
|
+
} catch (e) {
|
|
343
|
+
done(e);
|
|
344
|
+
}
|
|
345
|
+
}, 0);
|
|
346
|
+
} catch (e) {
|
|
347
|
+
done(e);
|
|
348
|
+
}
|
|
349
|
+
}, 0);
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
describe("message width behavior", function () {
|
|
354
|
+
let originalInnerWidth;
|
|
355
|
+
let originalGetBoundingClientRect;
|
|
356
|
+
|
|
357
|
+
beforeEach(() => {
|
|
358
|
+
originalInnerWidth = window.innerWidth;
|
|
359
|
+
originalGetBoundingClientRect = HTMLElement.prototype.getBoundingClientRect;
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
afterEach(() => {
|
|
363
|
+
Object.defineProperty(window, "innerWidth", {
|
|
364
|
+
configurable: true,
|
|
365
|
+
writable: true,
|
|
366
|
+
value: originalInnerWidth,
|
|
367
|
+
});
|
|
368
|
+
HTMLElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
|
|
369
|
+
let mocks = document.getElementById("mocks");
|
|
370
|
+
mocks.innerHTML = "";
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it("should keep prose content on a readable max width", function (done) {
|
|
374
|
+
let mocks = document.getElementById("mocks");
|
|
375
|
+
const button = document.createElement("monster-message-state-button");
|
|
376
|
+
button.innerHTML = "Save";
|
|
377
|
+
mocks.appendChild(button);
|
|
378
|
+
|
|
379
|
+
Object.defineProperty(window, "innerWidth", {
|
|
380
|
+
configurable: true,
|
|
381
|
+
writable: true,
|
|
382
|
+
value: 800,
|
|
383
|
+
});
|
|
384
|
+
HTMLElement.prototype.getBoundingClientRect = function () {
|
|
385
|
+
if (this?.getAttribute?.("data-measurement") === "true") {
|
|
386
|
+
return {
|
|
387
|
+
width: 900,
|
|
388
|
+
height: 120,
|
|
389
|
+
top: 0,
|
|
390
|
+
left: 0,
|
|
391
|
+
right: 900,
|
|
392
|
+
bottom: 120,
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
width: 100,
|
|
398
|
+
height: 40,
|
|
399
|
+
top: 0,
|
|
400
|
+
left: 0,
|
|
401
|
+
right: 100,
|
|
402
|
+
bottom: 40,
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
setTimeout(() => {
|
|
407
|
+
try {
|
|
408
|
+
button.setMessage(
|
|
409
|
+
"<div><p>This long prose content should wrap instead of forcing the message popper to use the full viewport width.</p></div>",
|
|
410
|
+
);
|
|
411
|
+
button.showMessage();
|
|
412
|
+
|
|
413
|
+
setTimeout(() => {
|
|
414
|
+
try {
|
|
415
|
+
const popper = button.shadowRoot.querySelector(
|
|
416
|
+
'[data-monster-role="popper"]',
|
|
417
|
+
);
|
|
418
|
+
expect(popper.style.width).to.equal("512px");
|
|
419
|
+
expect(popper.style.maxWidth).to.equal("512px");
|
|
420
|
+
done();
|
|
421
|
+
} catch (e) {
|
|
422
|
+
done(e);
|
|
423
|
+
}
|
|
424
|
+
}, 0);
|
|
425
|
+
} catch (e) {
|
|
426
|
+
done(e);
|
|
427
|
+
}
|
|
428
|
+
}, 0);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("should allow wide content to grow until the viewport limit", function (done) {
|
|
432
|
+
let mocks = document.getElementById("mocks");
|
|
433
|
+
const button = document.createElement("monster-message-state-button");
|
|
434
|
+
button.innerHTML = "Save";
|
|
435
|
+
mocks.appendChild(button);
|
|
436
|
+
|
|
437
|
+
Object.defineProperty(window, "innerWidth", {
|
|
438
|
+
configurable: true,
|
|
439
|
+
writable: true,
|
|
440
|
+
value: 800,
|
|
441
|
+
});
|
|
442
|
+
HTMLElement.prototype.getBoundingClientRect = function () {
|
|
443
|
+
if (this?.getAttribute?.("data-measurement") === "true") {
|
|
444
|
+
return {
|
|
445
|
+
width: 900,
|
|
446
|
+
height: 120,
|
|
447
|
+
top: 0,
|
|
448
|
+
left: 0,
|
|
449
|
+
right: 900,
|
|
450
|
+
bottom: 120,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
return {
|
|
455
|
+
width: 100,
|
|
456
|
+
height: 40,
|
|
457
|
+
top: 0,
|
|
458
|
+
left: 0,
|
|
459
|
+
right: 100,
|
|
460
|
+
bottom: 40,
|
|
461
|
+
};
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
setTimeout(() => {
|
|
465
|
+
try {
|
|
466
|
+
const wrapper = document.createElement("div");
|
|
467
|
+
wrapper.setAttribute("data-monster-message-layout", "wide");
|
|
468
|
+
wrapper.textContent =
|
|
469
|
+
"wide content placeholder that should grow until the viewport edge";
|
|
470
|
+
button.setMessage(wrapper);
|
|
471
|
+
button.showMessage();
|
|
472
|
+
|
|
473
|
+
setTimeout(() => {
|
|
474
|
+
try {
|
|
475
|
+
const popper = button.shadowRoot.querySelector(
|
|
476
|
+
'[data-monster-role="popper"]',
|
|
477
|
+
);
|
|
478
|
+
expect(popper.style.width).to.equal("768px");
|
|
479
|
+
expect(popper.style.maxWidth).to.equal("768px");
|
|
480
|
+
done();
|
|
481
|
+
} catch (e) {
|
|
482
|
+
done(e);
|
|
483
|
+
}
|
|
484
|
+
}, 0);
|
|
485
|
+
} catch (e) {
|
|
486
|
+
done(e);
|
|
487
|
+
}
|
|
488
|
+
}, 0);
|
|
489
|
+
});
|
|
490
|
+
});
|
|
219
491
|
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as chai from "chai";
|
|
2
|
+
import { chaiDom } from "../../../util/chai-dom.mjs";
|
|
3
|
+
import { initJSDOM } from "../../../util/jsdom.mjs";
|
|
4
|
+
|
|
5
|
+
let expect = chai.expect;
|
|
6
|
+
chai.use(chaiDom);
|
|
7
|
+
|
|
8
|
+
let PopperButton;
|
|
9
|
+
|
|
10
|
+
describe("PopperButton", function () {
|
|
11
|
+
before(function (done) {
|
|
12
|
+
initJSDOM()
|
|
13
|
+
.then(() => {
|
|
14
|
+
return import("../../../../source/components/form/popper-button.mjs");
|
|
15
|
+
})
|
|
16
|
+
.then((m) => {
|
|
17
|
+
PopperButton = m["PopperButton"];
|
|
18
|
+
done();
|
|
19
|
+
})
|
|
20
|
+
.catch((e) => done(e));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
let mocks = document.getElementById("mocks");
|
|
25
|
+
mocks.innerHTML = "";
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should instance of popper-button", function () {
|
|
29
|
+
expect(document.createElement("monster-popper-button")).is.instanceof(
|
|
30
|
+
PopperButton,
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should apply content overflow mode to the rendered content wrapper", function (done) {
|
|
35
|
+
let mocks = document.getElementById("mocks");
|
|
36
|
+
const button = document.createElement("monster-popper-button");
|
|
37
|
+
mocks.appendChild(button);
|
|
38
|
+
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
try {
|
|
41
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
42
|
+
expect(content).to.exist;
|
|
43
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
44
|
+
"both",
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
button.setOption("popper.contentOverflow", "horizontal");
|
|
48
|
+
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
try {
|
|
51
|
+
expect(
|
|
52
|
+
content.getAttribute("data-monster-overflow-mode"),
|
|
53
|
+
).to.equal("horizontal");
|
|
54
|
+
done();
|
|
55
|
+
} catch (e) {
|
|
56
|
+
done(e);
|
|
57
|
+
}
|
|
58
|
+
}, 0);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
done(e);
|
|
61
|
+
}
|
|
62
|
+
}, 0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("should apply content overflow mode from the HTML attribute", function (done) {
|
|
66
|
+
let mocks = document.getElementById("mocks");
|
|
67
|
+
mocks.innerHTML = `
|
|
68
|
+
<monster-popper-button
|
|
69
|
+
data-monster-option-popper-content-overflow="horizontal"
|
|
70
|
+
></monster-popper-button>
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
try {
|
|
75
|
+
const button = mocks.querySelector("monster-popper-button");
|
|
76
|
+
const content = button.shadowRoot.querySelector('[part="content"]');
|
|
77
|
+
expect(button.getOption("popper.contentOverflow")).to.equal(
|
|
78
|
+
"horizontal",
|
|
79
|
+
);
|
|
80
|
+
expect(content.getAttribute("data-monster-overflow-mode")).to.equal(
|
|
81
|
+
"horizontal",
|
|
82
|
+
);
|
|
83
|
+
done();
|
|
84
|
+
} catch (e) {
|
|
85
|
+
done(e);
|
|
86
|
+
}
|
|
87
|
+
}, 0);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -371,6 +371,30 @@ describe('Select', function () {
|
|
|
371
371
|
|
|
372
372
|
});
|
|
373
373
|
|
|
374
|
+
it('should expose styling parts for container, filter messages and pagination', function (done) {
|
|
375
|
+
|
|
376
|
+
let mocks = document.getElementById('mocks');
|
|
377
|
+
const select = document.createElement('monster-select');
|
|
378
|
+
select.setOption('filter.mode', 'remote');
|
|
379
|
+
mocks.appendChild(select);
|
|
380
|
+
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
try {
|
|
383
|
+
const container = select.shadowRoot.querySelector('[data-monster-role=container]');
|
|
384
|
+
const selectionMessages = select.shadowRoot.querySelector('[data-monster-role=selection-messages]');
|
|
385
|
+
const pagination = select.shadowRoot.querySelector('[data-monster-role=pagination]');
|
|
386
|
+
|
|
387
|
+
expect(container.getAttribute('part')).to.equal('container');
|
|
388
|
+
expect(selectionMessages.getAttribute('part')).to.equal('selection-messages');
|
|
389
|
+
expect(pagination.getAttribute('part')).to.equal('pagination');
|
|
390
|
+
} catch (e) {
|
|
391
|
+
return done(e);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
done();
|
|
395
|
+
}, 0)
|
|
396
|
+
});
|
|
397
|
+
|
|
374
398
|
it('should normalize options without throwing', function (done) {
|
|
375
399
|
this.timeout(2000);
|
|
376
400
|
|
|
@@ -212,7 +212,28 @@ describe('Treeselect', function () {
|
|
|
212
212
|
|
|
213
213
|
});
|
|
214
214
|
|
|
215
|
+
it('should expose styling parts for container and popper filter control', function (done) {
|
|
216
|
+
|
|
217
|
+
let mocks = document.getElementById('mocks');
|
|
218
|
+
const select = document.createElement('monster-tree-select');
|
|
219
|
+
mocks.appendChild(select);
|
|
220
|
+
|
|
221
|
+
setTimeout(() => {
|
|
222
|
+
try {
|
|
223
|
+
const container = select.shadowRoot.querySelector('[data-monster-role=container]');
|
|
224
|
+
const popperFilterControl = select.shadowRoot.querySelector('.option-filter-control');
|
|
225
|
+
|
|
226
|
+
expect(container.getAttribute('part')).to.equal('container');
|
|
227
|
+
expect(popperFilterControl.getAttribute('part')).to.equal('popper-filter-control');
|
|
228
|
+
} catch (e) {
|
|
229
|
+
return done(e);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
done();
|
|
233
|
+
}, 0)
|
|
234
|
+
});
|
|
235
|
+
|
|
215
236
|
});
|
|
216
237
|
|
|
217
238
|
|
|
218
|
-
});
|
|
239
|
+
});
|
|
@@ -13,16 +13,14 @@ describe('extractKeys', () => {
|
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const expected = new Map([
|
|
17
|
-
['firstname', 'firstName'],
|
|
18
|
-
['lastname', 'lastName'],
|
|
19
|
-
['address-street', 'address.street'],
|
|
20
|
-
['address-city', 'address.city'],
|
|
21
|
-
]);
|
|
22
|
-
|
|
23
16
|
const result = extractKeys(obj);
|
|
24
17
|
|
|
25
|
-
expect(
|
|
18
|
+
expect(result.get('firstname')).to.equal('firstName');
|
|
19
|
+
expect(result.get('first-name')).to.equal('firstName');
|
|
20
|
+
expect(result.get('lastname')).to.equal('lastName');
|
|
21
|
+
expect(result.get('last-name')).to.equal('lastName');
|
|
22
|
+
expect(result.get('address-street')).to.equal('address.street');
|
|
23
|
+
expect(result.get('address-city')).to.equal('address.city');
|
|
26
24
|
});
|
|
27
25
|
|
|
28
26
|
it('should use custom key and value separators', () => {
|
|
@@ -31,14 +29,12 @@ describe('extractKeys', () => {
|
|
|
31
29
|
lastName: 'Doe',
|
|
32
30
|
};
|
|
33
31
|
|
|
34
|
-
const expected = new Map([
|
|
35
|
-
['prefix+firstname', 'prefix+firstName'],
|
|
36
|
-
['prefix+lastname', 'prefix+lastName'],
|
|
37
|
-
]);
|
|
38
|
-
|
|
39
32
|
const result = extractKeys(obj, 'prefix', '+', '+');
|
|
40
33
|
|
|
41
|
-
expect(
|
|
34
|
+
expect(result.get('prefix+firstname')).to.equal('prefix+firstName');
|
|
35
|
+
expect(result.get('prefix+first-name')).to.equal('prefix+firstName');
|
|
36
|
+
expect(result.get('prefix+lastname')).to.equal('prefix+lastName');
|
|
37
|
+
expect(result.get('prefix+last-name')).to.equal('prefix+lastName');
|
|
42
38
|
});
|
|
43
39
|
|
|
44
40
|
it('check if value is null', () => {
|
|
@@ -48,17 +44,32 @@ describe('extractKeys', () => {
|
|
|
48
44
|
address: null,
|
|
49
45
|
};
|
|
50
46
|
|
|
51
|
-
const expected = new Map([
|
|
52
|
-
['firstname', 'firstName'],
|
|
53
|
-
['lastname', 'lastName'],
|
|
54
|
-
['address', 'address'],
|
|
55
|
-
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
47
|
const result = extractKeys(obj);
|
|
59
48
|
|
|
60
|
-
expect(
|
|
49
|
+
expect(result.get('firstname')).to.equal('firstName');
|
|
50
|
+
expect(result.get('first-name')).to.equal('firstName');
|
|
51
|
+
expect(result.get('lastname')).to.equal('lastName');
|
|
52
|
+
expect(result.get('last-name')).to.equal('lastName');
|
|
53
|
+
expect(result.get('address')).to.equal('address');
|
|
61
54
|
});
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
it('should expose kebab-case aliases for camelCase nested keys', () => {
|
|
57
|
+
const obj = {
|
|
58
|
+
popper: {
|
|
59
|
+
contentOverflow: 'both',
|
|
60
|
+
},
|
|
61
|
+
message: {
|
|
62
|
+
width: {
|
|
63
|
+
viewportRatio: 0.7,
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const result = extractKeys(obj);
|
|
69
|
+
|
|
70
|
+
expect(result.get('popper-contentoverflow')).to.equal('popper.contentOverflow');
|
|
71
|
+
expect(result.get('popper-content-overflow')).to.equal('popper.contentOverflow');
|
|
72
|
+
expect(result.get('message-width-viewportratio')).to.equal('message.width.viewportRatio');
|
|
73
|
+
expect(result.get('message-width-viewport-ratio')).to.equal('message.width.viewportRatio');
|
|
74
|
+
});
|
|
64
75
|
});
|
|
@@ -164,4 +164,25 @@ describe('initOptionsFromAttributes', () => {
|
|
|
164
164
|
expect(result.key.caseSensitive).to.equal(false);
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
+
it('should support kebab-case aliases for camelCase option names', () => {
|
|
168
|
+
options = {
|
|
169
|
+
popper: {
|
|
170
|
+
contentOverflow: 'both',
|
|
171
|
+
},
|
|
172
|
+
message: {
|
|
173
|
+
width: {
|
|
174
|
+
viewportRatio: 0.7,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
element.setAttribute('data-monster-option-popper-content-overflow', 'horizontal');
|
|
180
|
+
element.setAttribute('data-monster-option-message-width-viewport-ratio', '0.9');
|
|
181
|
+
|
|
182
|
+
const result = initOptionsFromAttributes(element, options);
|
|
183
|
+
|
|
184
|
+
expect(result.popper.contentOverflow).to.equal('horizontal');
|
|
185
|
+
expect(result.message.width.viewportRatio).to.equal(0.9);
|
|
186
|
+
});
|
|
187
|
+
|
|
167
188
|
});
|
package/test/cases/monster.mjs
CHANGED
package/test/web/import.js
CHANGED
|
@@ -10,6 +10,7 @@ import "../cases/components/form/button-bar.mjs";
|
|
|
10
10
|
import "../cases/components/form/reload.mjs";
|
|
11
11
|
import "../cases/components/form/state-button.mjs";
|
|
12
12
|
import "../cases/components/form/select.mjs";
|
|
13
|
+
import "../cases/components/form/login.mjs";
|
|
13
14
|
import "../cases/components/form/confirm-button.mjs";
|
|
14
15
|
import "../cases/components/form/form.mjs";
|
|
15
16
|
import "../cases/components/form/tree-select.mjs";
|
package/test/web/test.html
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
|
12
|
-
<h1 style='margin-bottom: 0.1em;'>Monster 4.128.
|
|
13
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
|
12
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 4.128.3</h1>
|
|
13
|
+
<div id="lastupdate" style='font-size:0.7em'>last update So 5. Apr 19:19:33 CEST 2026</div>
|
|
14
14
|
</div>
|
|
15
15
|
<div id="mocha-errors"
|
|
16
16
|
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
|