@schukai/monster 4.136.26 → 4.136.27
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/package.json +1 -1
- package/source/components/form/util/floating-ui.mjs +4 -1
- package/source/components/layout/tabs.mjs +3 -0
- package/source/components/style/floating-ui.css +2 -1
- package/source/components/style/floating-ui.pcss +2 -1
- package/source/components/stylesheet/floating-ui.mjs +1 -1
- package/test/cases/components/form/floating-ui.mjs +25 -0
- package/test/cases/components/layout/tabs.mjs +140 -50
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"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.136.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.6"},"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.136.27"}
|
|
@@ -456,7 +456,10 @@ function applyOverlayAwareContentHeight(
|
|
|
456
456
|
preferredHeight > contentMaxHeight;
|
|
457
457
|
|
|
458
458
|
contentElement.style.removeProperty("overflow");
|
|
459
|
-
contentElement.style.overflowX =
|
|
459
|
+
contentElement.style.overflowX =
|
|
460
|
+
contentElement.dataset.monsterOverflowMode === "horizontal"
|
|
461
|
+
? "auto"
|
|
462
|
+
: "visible";
|
|
460
463
|
contentElement.style.overflowY = isConstrained ? "auto" : "visible";
|
|
461
464
|
|
|
462
465
|
if (Number.isFinite(constrainedHeight) && constrainedHeight > 0) {
|
|
@@ -43,7 +43,8 @@ div[data-monster-role="popper"] > [part="content"] {
|
|
|
43
43
|
div[data-monster-role="popper"]
|
|
44
44
|
> [part="content"][data-monster-overflow-mode="horizontal"] {
|
|
45
45
|
clip-path: none;
|
|
46
|
-
overflow:
|
|
46
|
+
overflow-x: auto;
|
|
47
|
+
overflow-y: visible;
|
|
47
48
|
}
|
|
48
49
|
div[data-monster-role="popper"]
|
|
49
50
|
> [part="content"][data-monster-overflow-mode="visible"] {
|
|
@@ -25,7 +25,7 @@ try {
|
|
|
25
25
|
FloatingUiStyleSheet.insertRule(
|
|
26
26
|
`
|
|
27
27
|
@layer floatingui {
|
|
28
|
-
div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));opacity:1;padding:1.1em;position:absolute;top:0;transition:opacity var(--monster-popper-fade-duration,.14s) var(--monster-popper-fade-timing,cubic-bezier(.2,0,0,1));width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper][data-monster-appearance=opening]{opacity:0}div[data-monster-role=popper][data-monster-appearance=open]{opacity:1}@media (prefers-reduced-motion:reduce){div[data-monster-role=popper]{transition:none}}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:none;overflow:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}
|
|
28
|
+
div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;max-height:var(--monster-popper-max-height,calc(100vh - 2rem));max-width:var(--monster-popper-max-width,calc(100vw - 2rem));opacity:1;padding:1.1em;position:absolute;top:0;transition:opacity var(--monster-popper-fade-duration,.14s) var(--monster-popper-fade-timing,cubic-bezier(.2,0,0,1));width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper][data-monster-appearance=opening]{opacity:0}div[data-monster-role=popper][data-monster-appearance=open]{opacity:1}@media (prefers-reduced-motion:reduce){div[data-monster-role=popper]{transition:none}}div[data-monster-role=popper]>[part=content]{max-height:var(--monster-popper-content-max-height,calc(100vh - 4.2rem));max-width:100%;overflow:auto}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=horizontal]{clip-path:none;overflow-x:auto;overflow-y:visible}div[data-monster-role=popper]>[part=content][data-monster-overflow-mode=visible]{clip-path:none;max-height:none;max-width:none;overflow:visible}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}
|
|
29
29
|
}`,
|
|
30
30
|
0,
|
|
31
31
|
);
|
|
@@ -310,4 +310,29 @@ describe("form floating-ui boundary resolution", function () {
|
|
|
310
310
|
expect(popper.style.width).to.equal("240px");
|
|
311
311
|
expect(popper.style.minWidth).to.equal("240px");
|
|
312
312
|
});
|
|
313
|
+
|
|
314
|
+
it("should constrain horizontal overlay-aware content on the inline axis", function () {
|
|
315
|
+
const mocks = document.getElementById("mocks");
|
|
316
|
+
const popper = document.createElement("div");
|
|
317
|
+
const content = document.createElement("div");
|
|
318
|
+
|
|
319
|
+
content.setAttribute("part", "content");
|
|
320
|
+
content.setAttribute("data-monster-overflow-mode", "horizontal");
|
|
321
|
+
|
|
322
|
+
Object.defineProperty(content, "scrollHeight", {
|
|
323
|
+
configurable: true,
|
|
324
|
+
value: 120,
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
popper.appendChild(content);
|
|
328
|
+
mocks.appendChild(popper);
|
|
329
|
+
|
|
330
|
+
applyAdaptiveFloatingElementSize(popper, {
|
|
331
|
+
availableWidth: 240,
|
|
332
|
+
availableHeight: 200,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
expect(content.style.overflowX).to.equal("auto");
|
|
336
|
+
expect(content.style.overflowY).to.equal("visible");
|
|
337
|
+
});
|
|
313
338
|
});
|
|
@@ -2,6 +2,7 @@ import {getGlobal} from "../../../../source/types/global.mjs";
|
|
|
2
2
|
import * as chai from 'chai';
|
|
3
3
|
import {chaiDom} from "../../../util/chai-dom.mjs";
|
|
4
4
|
import {initJSDOM} from "../../../util/jsdom.mjs";
|
|
5
|
+
import {ResizeObserverMock} from "../../../util/resize-observer.mjs";
|
|
5
6
|
|
|
6
7
|
let expect = chai.expect;
|
|
7
8
|
chai.use(chaiDom);
|
|
@@ -61,6 +62,35 @@ let htmlOverflow = `
|
|
|
61
62
|
`;
|
|
62
63
|
|
|
63
64
|
let Tabs;
|
|
65
|
+
let restoreBoundingClientRect = null;
|
|
66
|
+
let restoreResizeObserver = null;
|
|
67
|
+
|
|
68
|
+
function waitForCondition(check, {timeout = 4000, interval = 10} = {}) {
|
|
69
|
+
const startedAt = Date.now();
|
|
70
|
+
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
|
+
const tick = () => {
|
|
73
|
+
try {
|
|
74
|
+
if (check() === true) {
|
|
75
|
+
resolve();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
} catch (e) {
|
|
79
|
+
reject(e);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (Date.now() - startedAt > timeout) {
|
|
84
|
+
reject(new Error('condition timed out'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
setTimeout(tick, interval);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
tick();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
64
94
|
|
|
65
95
|
describe('Tabs', function () {
|
|
66
96
|
|
|
@@ -92,6 +122,14 @@ describe('Tabs', function () {
|
|
|
92
122
|
describe('document.createElement()', function () {
|
|
93
123
|
|
|
94
124
|
afterEach(() => {
|
|
125
|
+
if (restoreBoundingClientRect instanceof Function) {
|
|
126
|
+
restoreBoundingClientRect();
|
|
127
|
+
restoreBoundingClientRect = null;
|
|
128
|
+
}
|
|
129
|
+
if (restoreResizeObserver instanceof Function) {
|
|
130
|
+
restoreResizeObserver();
|
|
131
|
+
restoreResizeObserver = null;
|
|
132
|
+
}
|
|
95
133
|
let mocks = document.getElementById('mocks');
|
|
96
134
|
mocks.innerHTML = "";
|
|
97
135
|
})
|
|
@@ -219,10 +257,35 @@ describe('Tabs', function () {
|
|
|
219
257
|
});
|
|
220
258
|
|
|
221
259
|
it('should move overflowing tabs into the popper without losing them', function (done) {
|
|
260
|
+
this.timeout(5000);
|
|
222
261
|
|
|
223
262
|
let mocks = document.getElementById('mocks');
|
|
263
|
+
const OriginalResizeObserver = window.ResizeObserver;
|
|
264
|
+
const originalGlobalResizeObserver = global.ResizeObserver;
|
|
265
|
+
class TrackingResizeObserver extends ResizeObserverMock {
|
|
266
|
+
static instances = [];
|
|
267
|
+
static callbackCount = 0;
|
|
268
|
+
|
|
269
|
+
constructor(callback) {
|
|
270
|
+
super((entries, observer) => {
|
|
271
|
+
TrackingResizeObserver.callbackCount++;
|
|
272
|
+
callback(entries, observer);
|
|
273
|
+
});
|
|
274
|
+
TrackingResizeObserver.instances.push(this);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
window.ResizeObserver = TrackingResizeObserver;
|
|
278
|
+
global.ResizeObserver = TrackingResizeObserver;
|
|
279
|
+
restoreResizeObserver = () => {
|
|
280
|
+
window.ResizeObserver = OriginalResizeObserver;
|
|
281
|
+
global.ResizeObserver = originalGlobalResizeObserver;
|
|
282
|
+
};
|
|
224
283
|
const originalGetBoundingClientRect =
|
|
225
284
|
global.HTMLElement.prototype.getBoundingClientRect;
|
|
285
|
+
restoreBoundingClientRect = () => {
|
|
286
|
+
global.HTMLElement.prototype.getBoundingClientRect =
|
|
287
|
+
originalGetBoundingClientRect;
|
|
288
|
+
};
|
|
226
289
|
global.HTMLElement.prototype.getBoundingClientRect = function () {
|
|
227
290
|
const role = this.getAttribute?.('data-monster-role');
|
|
228
291
|
const label = this.textContent?.trim() || '';
|
|
@@ -258,63 +321,90 @@ describe('Tabs', function () {
|
|
|
258
321
|
|
|
259
322
|
mocks.innerHTML = htmlOverflow;
|
|
260
323
|
|
|
261
|
-
|
|
324
|
+
waitForCondition(() => {
|
|
325
|
+
const tabs = document.getElementById('overflow-tabs');
|
|
326
|
+
const switchButton = tabs?.shadowRoot?.querySelector(
|
|
327
|
+
'[data-monster-role="switch"]',
|
|
328
|
+
);
|
|
329
|
+
const standardButtons = tabs?.getOption?.('buttons.standard') || [];
|
|
330
|
+
const popperButtons = tabs?.getOption?.('buttons.popper') || [];
|
|
331
|
+
|
|
332
|
+
return (
|
|
333
|
+
tabs instanceof Tabs &&
|
|
334
|
+
switchButton !== null &&
|
|
335
|
+
standardButtons.length > 0 &&
|
|
336
|
+
popperButtons.length > 0 &&
|
|
337
|
+
standardButtons.length + popperButtons.length === 11 &&
|
|
338
|
+
switchButton.classList.contains('hidden') === false
|
|
339
|
+
);
|
|
340
|
+
}).then(() => {
|
|
262
341
|
try {
|
|
263
342
|
const tabs = document.getElementById('overflow-tabs');
|
|
264
343
|
expect(tabs).is.instanceof(Tabs);
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
344
|
+
const switchButton = tabs.shadowRoot.querySelector(
|
|
345
|
+
'[data-monster-role="switch"]',
|
|
346
|
+
);
|
|
347
|
+
let standardButtons = tabs.getOption('buttons.standard');
|
|
348
|
+
let popperButtons = tabs.getOption('buttons.popper');
|
|
349
|
+
|
|
350
|
+
expect(switchButton).to.not.equal(null);
|
|
351
|
+
expect(standardButtons.length).to.be.greaterThan(0);
|
|
352
|
+
expect(popperButtons.length).to.be.greaterThan(0);
|
|
353
|
+
expect(standardButtons.length + popperButtons.length).to.equal(11);
|
|
354
|
+
expect(switchButton.classList.contains('hidden')).to.equal(false);
|
|
355
|
+
|
|
356
|
+
const resizeObserver = TrackingResizeObserver.instances.find(
|
|
357
|
+
(observer) => observer.elements.includes(tabs.shadowRoot.querySelector('[data-monster-role="nav"]')),
|
|
358
|
+
);
|
|
359
|
+
expect(resizeObserver).to.not.equal(undefined);
|
|
360
|
+
resizeObserver.triggerResize([]);
|
|
361
|
+
|
|
362
|
+
return waitForCondition(() => {
|
|
363
|
+
return (
|
|
364
|
+
TrackingResizeObserver.callbackCount > 0 &&
|
|
365
|
+
tabs.getOption('buttons.standard').length === 11 &&
|
|
366
|
+
tabs.getOption('buttons.popper').length === 0
|
|
367
|
+
);
|
|
368
|
+
}).then(() => {
|
|
369
|
+
return waitForCondition(() => {
|
|
370
|
+
standardButtons = tabs.getOption('buttons.standard');
|
|
371
|
+
popperButtons = tabs.getOption('buttons.popper');
|
|
372
|
+
return (
|
|
373
|
+
standardButtons.length > 0 &&
|
|
374
|
+
popperButtons.length > 0 &&
|
|
375
|
+
standardButtons.length + popperButtons.length === 11 &&
|
|
376
|
+
new Set(
|
|
377
|
+
standardButtons
|
|
378
|
+
.concat(popperButtons)
|
|
379
|
+
.map((button) => button.reference),
|
|
380
|
+
).size === 11
|
|
270
381
|
);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
).to.equal(11);
|
|
280
|
-
expect(switchButton.classList.contains('hidden')).to.equal(false);
|
|
281
|
-
|
|
282
|
-
window.dispatchEvent(new Event('resize'));
|
|
283
|
-
setTimeout(() => {
|
|
284
|
-
try {
|
|
285
|
-
standardButtons = tabs.getOption('buttons.standard');
|
|
286
|
-
popperButtons = tabs.getOption('buttons.popper');
|
|
287
|
-
expect(standardButtons.length).to.be.greaterThan(0);
|
|
288
|
-
expect(popperButtons.length).to.be.greaterThan(0);
|
|
289
|
-
expect(
|
|
290
|
-
standardButtons.length + popperButtons.length,
|
|
291
|
-
).to.equal(11);
|
|
292
|
-
expect(
|
|
293
|
-
new Set(
|
|
294
|
-
standardButtons.concat(popperButtons).map((button) => button.reference),
|
|
295
|
-
).size,
|
|
296
|
-
).to.equal(11);
|
|
297
|
-
global.HTMLElement.prototype.getBoundingClientRect =
|
|
298
|
-
originalGetBoundingClientRect;
|
|
299
|
-
done();
|
|
300
|
-
} catch (e) {
|
|
301
|
-
global.HTMLElement.prototype.getBoundingClientRect =
|
|
302
|
-
originalGetBoundingClientRect;
|
|
303
|
-
done(e);
|
|
304
|
-
}
|
|
305
|
-
}, 250);
|
|
306
|
-
} catch (e) {
|
|
307
|
-
global.HTMLElement.prototype.getBoundingClientRect =
|
|
308
|
-
originalGetBoundingClientRect;
|
|
309
|
-
done(e);
|
|
310
|
-
}
|
|
311
|
-
}, 250);
|
|
382
|
+
});
|
|
383
|
+
}).then(() => {
|
|
384
|
+
restoreBoundingClientRect();
|
|
385
|
+
restoreBoundingClientRect = null;
|
|
386
|
+
restoreResizeObserver();
|
|
387
|
+
restoreResizeObserver = null;
|
|
388
|
+
done();
|
|
389
|
+
});
|
|
312
390
|
} catch (e) {
|
|
313
|
-
|
|
314
|
-
|
|
391
|
+
restoreBoundingClientRect();
|
|
392
|
+
restoreBoundingClientRect = null;
|
|
393
|
+
restoreResizeObserver();
|
|
394
|
+
restoreResizeObserver = null;
|
|
315
395
|
return done(e);
|
|
316
396
|
}
|
|
317
|
-
|
|
397
|
+
}).catch((e) => {
|
|
398
|
+
if (restoreBoundingClientRect instanceof Function) {
|
|
399
|
+
restoreBoundingClientRect();
|
|
400
|
+
restoreBoundingClientRect = null;
|
|
401
|
+
}
|
|
402
|
+
if (restoreResizeObserver instanceof Function) {
|
|
403
|
+
restoreResizeObserver();
|
|
404
|
+
restoreResizeObserver = null;
|
|
405
|
+
}
|
|
406
|
+
done(e);
|
|
407
|
+
});
|
|
318
408
|
});
|
|
319
409
|
|
|
320
410
|
});
|