made-refine 0.2.3 → 0.2.5-beta.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/dist/index.js CHANGED
@@ -4103,6 +4103,8 @@ var MAX_ZOOM = 5;
4103
4103
  var ZOOM_SENSITIVITY = 0.0145;
4104
4104
  var LINE_HEIGHT_PX = 40;
4105
4105
  var PAGE_HEIGHT_PX = 800;
4106
+ var CANVAS_MEASURE_NODE_BUDGET = 12e3;
4107
+ var CANVAS_PRIORITY_ROOT_SELECTORS = ["#root", "#app", "#__next", "main"];
4106
4108
  function normalizeWheelDelta(e) {
4107
4109
  let { deltaX, deltaY } = e;
4108
4110
  if (e.deltaMode === 1) {
@@ -4114,6 +4116,52 @@ function normalizeWheelDelta(e) {
4114
4116
  }
4115
4117
  return { deltaX, deltaY };
4116
4118
  }
4119
+ function getResolvedOverflowY(style) {
4120
+ return style.overflowY || style.overflow;
4121
+ }
4122
+ function isScrollableOverflowY(value) {
4123
+ return value === "auto" || value === "scroll" || value === "overlay";
4124
+ }
4125
+ function isClippedOverflowY(value) {
4126
+ return value === "hidden" || value === "clip";
4127
+ }
4128
+ function getParentAcrossShadowTree(el) {
4129
+ const parent = el.parentElement;
4130
+ if (parent) return parent;
4131
+ const root = el.getRootNode();
4132
+ if (root instanceof ShadowRoot && root.host instanceof HTMLElement) {
4133
+ return root.host;
4134
+ }
4135
+ return null;
4136
+ }
4137
+ function enqueueChildren(el, queue) {
4138
+ for (const child of el.children) {
4139
+ if (child instanceof HTMLElement) queue.push(child);
4140
+ }
4141
+ const shadowRoot = el.shadowRoot;
4142
+ if (!shadowRoot) return;
4143
+ for (const child of shadowRoot.children) {
4144
+ if (child instanceof HTMLElement) queue.push(child);
4145
+ }
4146
+ }
4147
+ function measureContentBounds(el) {
4148
+ const rect = el.getBoundingClientRect();
4149
+ const pageLeft = rect.left + (window.scrollX || window.pageXOffset || 0);
4150
+ const pageTop = rect.top + (window.scrollY || window.pageYOffset || 0);
4151
+ return {
4152
+ width: Math.max(0, pageLeft) + el.scrollWidth,
4153
+ height: Math.max(0, pageTop) + el.scrollHeight
4154
+ };
4155
+ }
4156
+ function hasClippedAncestor(el) {
4157
+ let ancestor = getParentAcrossShadowTree(el);
4158
+ while (ancestor && ancestor !== document.body) {
4159
+ const ancestorStyle = getComputedStyle(ancestor);
4160
+ if (isClippedOverflowY(getResolvedOverflowY(ancestorStyle))) return true;
4161
+ ancestor = getParentAcrossShadowTree(ancestor);
4162
+ }
4163
+ return false;
4164
+ }
4117
4165
  var PAN_MARGIN = 0.1;
4118
4166
  function clampPan(zoom, panX, panY, bodyW, bodyH) {
4119
4167
  const vw = window.innerWidth;
@@ -4134,7 +4182,9 @@ function useCanvas({ stateRef, setState }) {
4134
4182
  const savedBodyOverflowRef = React7.useRef("");
4135
4183
  const savedHtmlOverflowRef = React7.useRef("");
4136
4184
  const savedHtmlBgColorRef = React7.useRef("");
4185
+ const domStateSavedRef = React7.useRef(false);
4137
4186
  const savedBodyDimensionsRef = React7.useRef({ width: 0, height: 0 });
4187
+ const savedExpandedNodesRef = React7.useRef([]);
4138
4188
  const rafIdRef = React7.useRef(null);
4139
4189
  const rafPendingRef = React7.useRef(false);
4140
4190
  const spaceHeldRef = React7.useRef(false);
@@ -4190,54 +4240,162 @@ function useCanvas({ stateRef, setState }) {
4190
4240
  });
4191
4241
  }
4192
4242
  }, [applyTransform, dispatchCanvasChange, setState]);
4243
+ function collectTraversalSeeds() {
4244
+ const out = [];
4245
+ const seen = /* @__PURE__ */ new Set();
4246
+ const push = (el) => {
4247
+ if (!(el instanceof HTMLElement)) return;
4248
+ if (!document.body.contains(el)) return;
4249
+ if (seen.has(el)) return;
4250
+ seen.add(el);
4251
+ out.push(el);
4252
+ };
4253
+ for (const selector of CANVAS_PRIORITY_ROOT_SELECTORS) {
4254
+ push(document.querySelector(selector));
4255
+ }
4256
+ for (const child of document.body.children) {
4257
+ push(child);
4258
+ }
4259
+ return out;
4260
+ }
4261
+ function expandScrollableRegionsAndMeasureBody() {
4262
+ const snapshots = /* @__PURE__ */ new Map();
4263
+ const expandedOrder = [];
4264
+ const queue = collectTraversalSeeds();
4265
+ const visited = /* @__PURE__ */ new Set();
4266
+ let visitedCount = 0;
4267
+ let fallbackWidth = 0;
4268
+ let fallbackHeight = 0;
4269
+ const expandNode = (el) => {
4270
+ if (snapshots.has(el)) return;
4271
+ snapshots.set(el, {
4272
+ height: el.style.height,
4273
+ maxHeight: el.style.maxHeight,
4274
+ overflowY: el.style.overflowY
4275
+ });
4276
+ expandedOrder.push(el);
4277
+ el.style.height = "auto";
4278
+ el.style.maxHeight = "none";
4279
+ el.style.overflowY = "visible";
4280
+ };
4281
+ while (queue.length > 0 && visitedCount < CANVAS_MEASURE_NODE_BUDGET) {
4282
+ const el = queue.shift();
4283
+ if (!el || visited.has(el)) continue;
4284
+ visited.add(el);
4285
+ visitedCount++;
4286
+ const hasVerticalOverflow = el.scrollHeight > el.clientHeight + 1;
4287
+ const style = getComputedStyle(el);
4288
+ const overflowY = getResolvedOverflowY(style);
4289
+ const isScrollable = hasVerticalOverflow && isScrollableOverflowY(overflowY);
4290
+ if (isScrollable) {
4291
+ expandNode(el);
4292
+ let ancestor = getParentAcrossShadowTree(el);
4293
+ while (ancestor && ancestor !== document.body) {
4294
+ const ancestorStyle = getComputedStyle(ancestor);
4295
+ if (isClippedOverflowY(getResolvedOverflowY(ancestorStyle))) {
4296
+ expandNode(ancestor);
4297
+ }
4298
+ ancestor = getParentAcrossShadowTree(ancestor);
4299
+ }
4300
+ }
4301
+ const canContributeFallback = hasVerticalOverflow && (isScrollable || !isClippedOverflowY(overflowY) && !hasClippedAncestor(el));
4302
+ if (canContributeFallback) {
4303
+ const bounds = measureContentBounds(el);
4304
+ fallbackWidth = Math.max(fallbackWidth, bounds.width);
4305
+ fallbackHeight = Math.max(fallbackHeight, bounds.height);
4306
+ }
4307
+ enqueueChildren(el, queue);
4308
+ }
4309
+ savedExpandedNodesRef.current = expandedOrder.map((el) => ({ el, ...snapshots.get(el) }));
4310
+ return {
4311
+ width: Math.max(document.body.scrollWidth, document.documentElement.scrollWidth, fallbackWidth, window.innerWidth),
4312
+ height: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, fallbackHeight, window.innerHeight)
4313
+ };
4314
+ }
4315
+ function restoreExpandedNodes() {
4316
+ for (let i = savedExpandedNodesRef.current.length - 1; i >= 0; i--) {
4317
+ const { el, height, maxHeight, overflowY } = savedExpandedNodesRef.current[i];
4318
+ el.style.height = height;
4319
+ el.style.maxHeight = maxHeight;
4320
+ el.style.overflowY = overflowY;
4321
+ }
4322
+ savedExpandedNodesRef.current = [];
4323
+ }
4193
4324
  const enterCanvas = React7.useCallback(() => {
4325
+ if (canvasRef.current.active) return;
4326
+ if (domStateSavedRef.current || savedExpandedNodesRef.current.length > 0) {
4327
+ restoreExpandedNodes();
4328
+ domStateSavedRef.current = false;
4329
+ }
4194
4330
  const scrollX = window.scrollX;
4195
4331
  const scrollY = window.scrollY;
4196
4332
  savedScrollRef.current = { x: scrollX, y: scrollY };
4197
4333
  savedBodyOverflowRef.current = document.body.style.overflow;
4198
4334
  savedHtmlOverflowRef.current = document.documentElement.style.overflow;
4199
4335
  savedHtmlBgColorRef.current = document.documentElement.style.backgroundColor;
4200
- savedBodyDimensionsRef.current = {
4201
- width: document.body.scrollWidth,
4202
- height: document.body.scrollHeight
4203
- };
4336
+ domStateSavedRef.current = true;
4204
4337
  const existingTransform = document.body.style.transform;
4205
4338
  if (existingTransform && existingTransform !== "none" && existingTransform !== "") {
4206
4339
  console.warn("[made-refine] canvas mode: overriding existing body transform:", existingTransform);
4207
4340
  }
4208
- window.scrollTo(0, 0);
4209
- updateBodyOffset();
4210
- document.body.style.overflow = "hidden";
4211
- document.documentElement.style.overflow = "hidden";
4212
- document.documentElement.style.backgroundColor = "#F5F5F5";
4213
- const initialPanX = -scrollX;
4214
- const initialPanY = -scrollY;
4215
- applyTransform(1, initialPanX, initialPanY);
4216
- canvasRef.current = { active: true, zoom: 1, panX: initialPanX, panY: initialPanY };
4217
- setCanvasSnapshot(canvasRef.current);
4218
- setState((prev) => ({
4219
- ...prev,
4220
- canvas: { active: true, zoom: 1, panX: initialPanX, panY: initialPanY }
4221
- }));
4222
- dispatchCanvasChange();
4341
+ let entered = false;
4342
+ try {
4343
+ window.scrollTo(0, 0);
4344
+ savedBodyDimensionsRef.current = expandScrollableRegionsAndMeasureBody();
4345
+ updateBodyOffset();
4346
+ document.body.style.overflow = "hidden";
4347
+ document.documentElement.style.overflow = "hidden";
4348
+ document.documentElement.style.backgroundColor = "#F5F5F5";
4349
+ const initialPanX = -scrollX;
4350
+ const initialPanY = -scrollY;
4351
+ applyTransform(1, initialPanX, initialPanY);
4352
+ canvasRef.current = { active: true, zoom: 1, panX: initialPanX, panY: initialPanY };
4353
+ setCanvasSnapshot(canvasRef.current);
4354
+ setState((prev) => ({
4355
+ ...prev,
4356
+ canvas: { active: true, zoom: 1, panX: initialPanX, panY: initialPanY }
4357
+ }));
4358
+ dispatchCanvasChange();
4359
+ entered = true;
4360
+ } finally {
4361
+ if (!entered) {
4362
+ document.body.style.transform = "";
4363
+ document.body.style.transformOrigin = "";
4364
+ restoreExpandedNodes();
4365
+ document.body.style.overflow = savedBodyOverflowRef.current;
4366
+ document.documentElement.style.overflow = savedHtmlOverflowRef.current;
4367
+ document.documentElement.style.backgroundColor = savedHtmlBgColorRef.current;
4368
+ window.scrollTo(scrollX, scrollY);
4369
+ domStateSavedRef.current = false;
4370
+ }
4371
+ }
4223
4372
  }, [applyTransform, dispatchCanvasChange, setState, updateBodyOffset]);
4224
4373
  const exitCanvas = React7.useCallback(() => {
4374
+ const shouldRestoreDom = domStateSavedRef.current || savedExpandedNodesRef.current.length > 0;
4375
+ const wasActive = canvasRef.current.active;
4376
+ if (!wasActive && !shouldRestoreDom) return;
4225
4377
  cancelPendingRaf();
4226
4378
  document.body.style.transform = "";
4227
4379
  document.body.style.transformOrigin = "";
4228
- document.body.style.overflow = savedBodyOverflowRef.current;
4229
- document.documentElement.style.overflow = savedHtmlOverflowRef.current;
4230
- document.documentElement.style.backgroundColor = savedHtmlBgColorRef.current;
4380
+ restoreExpandedNodes();
4381
+ if (shouldRestoreDom) {
4382
+ document.body.style.overflow = savedBodyOverflowRef.current;
4383
+ document.documentElement.style.overflow = savedHtmlOverflowRef.current;
4384
+ document.documentElement.style.backgroundColor = savedHtmlBgColorRef.current;
4385
+ window.scrollTo(savedScrollRef.current.x, savedScrollRef.current.y);
4386
+ }
4231
4387
  document.body.style.cursor = "";
4232
- window.scrollTo(savedScrollRef.current.x, savedScrollRef.current.y);
4388
+ domStateSavedRef.current = false;
4233
4389
  setBodyOffset({ x: 0, y: 0 });
4234
4390
  canvasRef.current = { active: false, zoom: 1, panX: 0, panY: 0 };
4235
4391
  setCanvasSnapshot(canvasRef.current);
4236
- setState((prev) => ({
4237
- ...prev,
4238
- canvas: { active: false, zoom: 1, panX: 0, panY: 0 }
4239
- }));
4240
- dispatchCanvasChange();
4392
+ if (wasActive) {
4393
+ setState((prev) => ({
4394
+ ...prev,
4395
+ canvas: { active: false, zoom: 1, panX: 0, panY: 0 }
4396
+ }));
4397
+ dispatchCanvasChange();
4398
+ }
4241
4399
  }, [cancelPendingRaf, dispatchCanvasChange, setState]);
4242
4400
  const toggleCanvas = React7.useCallback(() => {
4243
4401
  if (canvasRef.current.active) {
@@ -4364,7 +4522,7 @@ function useCanvas({ stateRef, setState }) {
4364
4522
  React7.useEffect(() => {
4365
4523
  return () => {
4366
4524
  cancelPendingRaf();
4367
- if (canvasRef.current.active) {
4525
+ if (canvasRef.current.active || domStateSavedRef.current || savedExpandedNodesRef.current.length > 0) {
4368
4526
  exitCanvas();
4369
4527
  }
4370
4528
  };