@schukai/monster 4.141.0 → 4.141.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/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.141.0"}
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.141.2"}
@@ -266,11 +266,14 @@ class ControlBar extends CustomElement {
266
266
  needsMeasure: true,
267
267
  needsLayout: true,
268
268
  needsObserve: true,
269
+ initialLayoutPending: true,
270
+ initialLayoutOpacity: undefined,
269
271
  suppressSlotChange: false,
270
272
  suppressMutation: false,
271
273
  };
272
274
 
273
275
  initControlReferences.call(this);
276
+ hideControlBarUntilInitialLayout.call(this);
274
277
  initEventHandler.call(this);
275
278
 
276
279
  // setup structure
@@ -462,6 +465,44 @@ function isElementSelfHidden(element) {
462
465
  );
463
466
  }
464
467
 
468
+ /**
469
+ * @private
470
+ * @return {void}
471
+ */
472
+ function hideControlBarUntilInitialLayout() {
473
+ const state = this[layoutStateSymbol];
474
+ if (!state || !(this[controlBarElementSymbol] instanceof HTMLElement)) {
475
+ return;
476
+ }
477
+
478
+ state.initialLayoutOpacity = this[controlBarElementSymbol].style.opacity;
479
+ this[controlBarElementSymbol].style.opacity = "0";
480
+ }
481
+
482
+ /**
483
+ * @private
484
+ * @return {void}
485
+ */
486
+ function revealControlBarAfterInitialLayout() {
487
+ const state = this[layoutStateSymbol];
488
+ if (
489
+ !state ||
490
+ state.initialLayoutPending !== true ||
491
+ !(this[controlBarElementSymbol] instanceof HTMLElement)
492
+ ) {
493
+ return;
494
+ }
495
+
496
+ state.initialLayoutPending = false;
497
+ const initialOpacity = state.initialLayoutOpacity;
498
+ if (typeof initialOpacity === "string" && initialOpacity !== "") {
499
+ this[controlBarElementSymbol].style.opacity = initialOpacity;
500
+ return;
501
+ }
502
+
503
+ this[controlBarElementSymbol].style.removeProperty("opacity");
504
+ }
505
+
465
506
  /**
466
507
  * @private
467
508
  */
@@ -664,6 +705,7 @@ function runLayout() {
664
705
  })
665
706
  .finally(() => {
666
707
  state.running = false;
708
+ revealControlBarAfterInitialLayout.call(this);
667
709
  if (state.needsObserve || state.needsMeasure || state.needsLayout) {
668
710
  scheduleLayoutFrame.call(this);
669
711
  }
@@ -1203,10 +1245,12 @@ function calculateControlBarDimensions() {
1203
1245
  }
1204
1246
 
1205
1247
  let width = this.parentElement.clientWidth;
1248
+ let containerWidth = width;
1206
1249
  if (computedStyle.getPropertyValue("box-sizing") !== "border-box") {
1207
1250
  width = computedStyle.getPropertyValue("width");
1208
1251
 
1209
1252
  const pixel = getComputedCssPixels(width);
1253
+ containerWidth = pixel;
1210
1254
 
1211
1255
  this[dimensionsSymbol].setVia("data.space", pixel);
1212
1256
  } else {
@@ -1226,8 +1270,8 @@ function calculateControlBarDimensions() {
1226
1270
  );
1227
1271
  }
1228
1272
 
1229
- this[dimensionsSymbol].setVia("data.visible", !(width === 0));
1230
- this[dimensionsSymbol].setVia("data.containerWidth", width);
1273
+ this[dimensionsSymbol].setVia("data.visible", !(containerWidth === 0));
1274
+ this[dimensionsSymbol].setVia("data.containerWidth", containerWidth);
1231
1275
 
1232
1276
  const itemReferences = [];
1233
1277
 
@@ -1549,6 +1593,10 @@ function isStackedBreakpointMatched() {
1549
1593
  } catch {}
1550
1594
  }
1551
1595
 
1596
+ if (!(width > 0)) {
1597
+ width = getComputedCssPixels(width);
1598
+ }
1599
+
1552
1600
  if (!(width > 0)) {
1553
1601
  return false;
1554
1602
  }
@@ -1583,6 +1631,7 @@ function setLayoutStackedState(stacked) {
1583
1631
  )) {
1584
1632
  queueLayoutChangedEvent.call(this);
1585
1633
  }
1634
+ applyLayoutAlignment.call(this);
1586
1635
  }
1587
1636
 
1588
1637
  /**
@@ -734,6 +734,98 @@ describe("ControlBar", function () {
734
734
  value: 20,
735
735
  });
736
736
 
737
+ expect(controlBar.style.opacity).to.equal("0");
738
+
739
+ await flushFrames();
740
+ await new Promise((resolve) => setTimeout(resolve, 0));
741
+ await new Promise((resolve) => setTimeout(resolve, 0));
742
+
743
+ expect(switchButton.hasAttribute("hidden")).to.be.true;
744
+ expect(button.hasAttribute("slot")).to.be.false;
745
+ expect(controlBar.style.opacity).to.equal("");
746
+ expect(controlBar.getAttribute("data-monster-layout-stacked")).to.equal(
747
+ "true",
748
+ );
749
+ expect(controlBar.getAttribute("data-monster-layout-alignment")).to.equal(
750
+ "left",
751
+ );
752
+ } finally {
753
+ window.requestAnimationFrame = originalRequestAnimationFrame;
754
+ globalThis.requestAnimationFrame = originalGlobalRequestAnimationFrame;
755
+ }
756
+ });
757
+
758
+ it("should match the stacked breakpoint when the content-box container width is a css string", async function () {
759
+ const originalRequestAnimationFrame = window.requestAnimationFrame;
760
+ const originalGlobalRequestAnimationFrame = globalThis.requestAnimationFrame;
761
+
762
+ const scheduledCallbacks = [];
763
+ const flushFrames = async () => {
764
+ while (scheduledCallbacks.length > 0) {
765
+ scheduledCallbacks.shift()();
766
+ await new Promise((resolve) => setTimeout(resolve, 0));
767
+ }
768
+ };
769
+
770
+ try {
771
+ window.requestAnimationFrame = (callback) => {
772
+ scheduledCallbacks.push(callback);
773
+ return scheduledCallbacks.length;
774
+ };
775
+ globalThis.requestAnimationFrame = window.requestAnimationFrame;
776
+
777
+ const mocks = document.getElementById("mocks");
778
+ mocks.innerHTML = `
779
+ <div id="content-box-breakpoint-wrapper">
780
+ <monster-control-bar
781
+ id="content-box-breakpoint-bar"
782
+ data-monster-option-layout-alignment="right"
783
+ data-monster-option-layout-stacked-alignment="left"
784
+ data-monster-option-layout-stacked-breakpoint="480px"
785
+ >
786
+ <button id="content-box-breakpoint-button">Run</button>
787
+ </monster-control-bar>
788
+ </div>
789
+ `;
790
+
791
+ const wrapper = document.getElementById(
792
+ "content-box-breakpoint-wrapper",
793
+ );
794
+ const button = document.getElementById("content-box-breakpoint-button");
795
+ const bar = document.getElementById("content-box-breakpoint-bar");
796
+ const controlBar = bar.shadowRoot.querySelector(
797
+ '[data-monster-role="control-bar"]',
798
+ );
799
+ const switchButton = bar.shadowRoot.querySelector(
800
+ '[data-monster-role="switch"]',
801
+ );
802
+
803
+ wrapper.style.boxSizing = "content-box";
804
+ wrapper.style.width = "350.156px";
805
+ Object.defineProperty(button, "offsetWidth", {
806
+ configurable: true,
807
+ value: 40,
808
+ });
809
+ Object.defineProperty(button, "offsetHeight", {
810
+ configurable: true,
811
+ value: 30,
812
+ });
813
+ button.getBoundingClientRect = () => ({
814
+ width: 40,
815
+ height: 30,
816
+ top: 0,
817
+ right: 40,
818
+ bottom: 30,
819
+ left: 0,
820
+ x: 0,
821
+ y: 0,
822
+ toJSON: () => {},
823
+ });
824
+ Object.defineProperty(switchButton, "offsetWidth", {
825
+ configurable: true,
826
+ value: 20,
827
+ });
828
+
737
829
  await flushFrames();
738
830
  await new Promise((resolve) => setTimeout(resolve, 0));
739
831
  await new Promise((resolve) => setTimeout(resolve, 0));