@threadlabs/looma 0.39.3 → 0.39.4

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/docs/catalog.json CHANGED
@@ -458,7 +458,7 @@
458
458
  ],
459
459
  "schemaVersion": 1,
460
460
  "package": "@threadlabs/looma",
461
- "version": "0.39.3",
461
+ "version": "0.39.4",
462
462
  "groups": [
463
463
  {
464
464
  "id": "layout",
@@ -66,11 +66,19 @@ export function connect(host) {
66
66
  };
67
67
  const header = document.querySelector('[data-component~="markupress-header"]');
68
68
  const previews = [...root.querySelectorAll('[data-editor-preview], .palette-preview')];
69
+ let layoutFrame = 0;
69
70
  const updatePreviewLayout = () => {
70
71
  const chrome = header?.getBoundingClientRect().height ?? 0;
71
72
  root.style.setProperty('--_editor-chrome-height', `${chrome}px`);
72
73
  for (const preview of previews) preview.toggleAttribute('data-page-flow', preview.offsetHeight > (view.innerHeight - chrome) / 2);
73
74
  };
75
+ // Layout writes must run outside ResizeObserver delivery, including when a preview appears.
76
+ const schedulePreviewLayout = () => {
77
+ if (!layoutFrame) layoutFrame = view.requestAnimationFrame(() => {
78
+ layoutFrame = 0;
79
+ updatePreviewLayout();
80
+ });
81
+ };
74
82
  const replayMotion = () => {
75
83
  const element = root.querySelector('[data-motion-object]');
76
84
  const duration = parseFloat(convertValueUnit(recipe.values['response-time'], 'ms', unitContext()));
@@ -405,9 +413,9 @@ export function connect(host) {
405
413
  filterExamples();
406
414
  };
407
415
  const motionPreferenceChanged = () => { motionAnimation?.cancel(); paint(); };
408
- const previewObserver = new view.ResizeObserver(updatePreviewLayout);
416
+ const previewObserver = new view.ResizeObserver(schedulePreviewLayout);
409
417
  for (const element of [...previews, ...(header ? [header] : [])]) previewObserver.observe(element);
410
- view.addEventListener('resize', updatePreviewLayout);
418
+ view.addEventListener('resize', schedulePreviewLayout);
411
419
  motionPreference.addEventListener('change', motionPreferenceChanged);
412
420
  root.addEventListener('toggle', updateSizes, true);
413
421
  root.addEventListener('looma-example-remove', remove);
@@ -438,5 +446,5 @@ export function connect(host) {
438
446
  root.querySelector('[data-action="save"]').hidden = false;
439
447
  }).catch(error => { if (alive && error.name !== 'AbortError') say(error.message, true); });
440
448
  }
441
- return () => { previewObserver.disconnect(); view.removeEventListener('resize', updatePreviewLayout); motionPreference.removeEventListener('change', motionPreferenceChanged); root.removeEventListener('toggle', updateSizes, true); motionAnimation?.cancel(); flush(); root.removeEventListener('cancel', cancel); root.removeEventListener('keydown', keyboard); alive = false; abort.abort(); root.removeEventListener('looma-example-remove', remove); root.removeEventListener('input', input); root.removeEventListener('value-change', choose); root.removeEventListener('value-change', selectExample); root.removeEventListener('value-change', selectFont); root.removeEventListener('blur', blur, true); root.removeEventListener('change', change); root.removeEventListener('click', click); view.removeEventListener('beforeunload', flush); view.removeEventListener('message', ready); view.removeEventListener('popstate', renderView); view.removeEventListener('hashchange', renderView); view.removeEventListener(themeEvent, synchronize); };
449
+ return () => { previewObserver.disconnect(); if (layoutFrame) view.cancelAnimationFrame(layoutFrame); view.removeEventListener('resize', schedulePreviewLayout); motionPreference.removeEventListener('change', motionPreferenceChanged); root.removeEventListener('toggle', updateSizes, true); motionAnimation?.cancel(); flush(); root.removeEventListener('cancel', cancel); root.removeEventListener('keydown', keyboard); alive = false; abort.abort(); root.removeEventListener('looma-example-remove', remove); root.removeEventListener('input', input); root.removeEventListener('value-change', choose); root.removeEventListener('value-change', selectExample); root.removeEventListener('value-change', selectFont); root.removeEventListener('blur', blur, true); root.removeEventListener('change', change); root.removeEventListener('click', click); view.removeEventListener('beforeunload', flush); view.removeEventListener('message', ready); view.removeEventListener('popstate', renderView); view.removeEventListener('hashchange', renderView); view.removeEventListener(themeEvent, synchronize); };
442
450
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@threadlabs/looma",
3
- "version": "0.39.3",
3
+ "version": "0.39.4",
4
4
  "type": "module",
5
5
  "description": "Looma components as HTML, Vue, and plain DOM, with design tokens.",
6
6
  "license": "MIT",