@papyrus-sdk/ui-react 0.2.16 → 0.2.18

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.mjs CHANGED
@@ -1339,6 +1339,7 @@ import {
1339
1339
  PapyrusEventType
1340
1340
  } from "@papyrus-sdk/types";
1341
1341
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1342
+ var SCALE_PRECISION = 1e3;
1342
1343
  var PageRenderer = ({
1343
1344
  engine,
1344
1345
  pageIndex,
@@ -1410,21 +1411,22 @@ var PageRenderer = ({
1410
1411
  if (!availableWidth || !pageSize?.width) return 1;
1411
1412
  const targetWidth = Math.max(0, availableWidth - 48);
1412
1413
  if (!targetWidth) return 1;
1413
- return Math.min(1, targetWidth / pageSize.width);
1414
+ const rawScale = Math.min(1, targetWidth / pageSize.width);
1415
+ return Math.round(rawScale * SCALE_PRECISION) / SCALE_PRECISION;
1414
1416
  }, [availableWidth, pageSize]);
1415
1417
  const displaySize = useMemo(() => {
1416
1418
  if (!pageSize) return null;
1417
1419
  const scale = zoom * fitScale;
1418
1420
  return {
1419
- width: pageSize.width * scale,
1420
- height: pageSize.height * scale
1421
+ width: Math.max(1, Math.round(pageSize.width * scale)),
1422
+ height: Math.max(1, Math.round(pageSize.height * scale))
1421
1423
  };
1422
1424
  }, [pageSize, zoom, fitScale]);
1423
1425
  useEffect3(() => {
1424
1426
  if (!displaySize || !onMeasuredSize) return;
1425
1427
  onMeasuredSize(pageIndex, {
1426
- width: Math.round(displaySize.width),
1427
- height: Math.round(displaySize.height)
1428
+ width: displaySize.width,
1429
+ height: displaySize.height
1428
1430
  });
1429
1431
  }, [displaySize, onMeasuredSize, pageIndex]);
1430
1432
  useEffect3(() => {
@@ -2075,6 +2077,8 @@ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2075
2077
  var BASE_OVERSCAN = 6;
2076
2078
  var MIN_ZOOM = 0.2;
2077
2079
  var MAX_ZOOM = 5;
2080
+ var WIDTH_SNAP_PX = 4;
2081
+ var WIDTH_HYSTERESIS_PX = 6;
2078
2082
  var Viewer = ({ engine }) => {
2079
2083
  const {
2080
2084
  pageCount,
@@ -2145,26 +2149,47 @@ var Viewer = ({ engine }) => {
2145
2149
  []
2146
2150
  );
2147
2151
  useEffect4(() => {
2148
- const element = viewerRef.current;
2149
- if (!element) return;
2152
+ const viewerElement = viewerRef.current;
2153
+ if (!viewerElement) return;
2154
+ const measurementTarget = viewerElement.parentElement ?? viewerElement;
2155
+ let rafId = null;
2156
+ const normalizeWidth = (rawWidth) => Math.max(0, Math.floor(rawWidth / WIDTH_SNAP_PX) * WIDTH_SNAP_PX);
2150
2157
  const updateWidth = () => {
2151
- const rawWidth = element.getBoundingClientRect?.().width ?? element.offsetWidth;
2152
- const nextWidth = Math.round(rawWidth);
2158
+ const rawWidth = measurementTarget.getBoundingClientRect?.().width ?? measurementTarget.clientWidth ?? measurementTarget.offsetWidth;
2159
+ const nextWidth = normalizeWidth(rawWidth);
2153
2160
  if (nextWidth <= 0) return;
2154
2161
  const previousWidth = lastWidthRef.current;
2155
- if (previousWidth != null && Math.abs(nextWidth - previousWidth) < 2)
2162
+ if (previousWidth != null && Math.abs(nextWidth - previousWidth) < WIDTH_HYSTERESIS_PX)
2156
2163
  return;
2157
2164
  lastWidthRef.current = nextWidth;
2158
2165
  setAvailableWidth(nextWidth);
2159
2166
  };
2160
- updateWidth();
2167
+ const scheduleWidthUpdate = () => {
2168
+ if (rafId != null) cancelAnimationFrame(rafId);
2169
+ rafId = requestAnimationFrame(() => {
2170
+ rafId = null;
2171
+ updateWidth();
2172
+ });
2173
+ };
2174
+ scheduleWidthUpdate();
2161
2175
  if (typeof ResizeObserver === "undefined") {
2162
- window.addEventListener("resize", updateWidth);
2163
- return () => window.removeEventListener("resize", updateWidth);
2176
+ window.addEventListener("resize", scheduleWidthUpdate);
2177
+ window.visualViewport?.addEventListener("resize", scheduleWidthUpdate);
2178
+ return () => {
2179
+ if (rafId != null) cancelAnimationFrame(rafId);
2180
+ window.removeEventListener("resize", scheduleWidthUpdate);
2181
+ window.visualViewport?.removeEventListener(
2182
+ "resize",
2183
+ scheduleWidthUpdate
2184
+ );
2185
+ };
2164
2186
  }
2165
- const observer = new ResizeObserver(() => updateWidth());
2166
- observer.observe(element);
2167
- return () => observer.disconnect();
2187
+ const observer = new ResizeObserver(() => scheduleWidthUpdate());
2188
+ observer.observe(measurementTarget);
2189
+ return () => {
2190
+ if (rafId != null) cancelAnimationFrame(rafId);
2191
+ observer.disconnect();
2192
+ };
2168
2193
  }, []);
2169
2194
  useEffect4(() => {
2170
2195
  let active = true;