@tldiagram/core-ui 1.89.7 → 1.90.1

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@tldiagram/core-ui",
3
- "version": "1.89.7",
3
+ "version": "1.90.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -94,6 +94,11 @@ const nodeTypes = {
94
94
  }
95
95
  const edgeTypes = { default: ViewBezierConnector, contextStraightConnector: ContextStraightConnector, proxyConnectorEdge: ProxyConnectorEdge }
96
96
  const EMPTY_LINKS: ViewConnector[] = []
97
+ const VIEW_EDITOR_MIN_ZOOM_FLOOR = 0.12
98
+ const VIEW_EDITOR_EMPTY_EXTENT_RATIO = 0.75
99
+ const VIEW_EDITOR_PAN_MARGIN_RATIO = 0.25
100
+ const VIEW_EDITOR_PAN_MARGIN_MIN = 180
101
+ const VIEW_EDITOR_PAN_MARGIN_MAX = 720
97
102
 
98
103
  function alphaColor(color: string, opacity: number): string {
99
104
  if (opacity >= 1) return color
@@ -808,7 +813,7 @@ function ViewEditorInner({
808
813
  // ── FitView ────────────────────────────────────────────────────────────────
809
814
  const fitViewRef = useRef(safeFitView)
810
815
  fitViewRef.current = safeFitView
811
- const [computedMinZoom, setComputedMinZoom] = useState(0.05)
816
+ const [computedMinZoom, setComputedMinZoom] = useState(VIEW_EDITOR_MIN_ZOOM_FLOOR)
812
817
  const [computedTranslateExtent, setComputedTranslateExtent] = useState<[[number, number], [number, number]] | undefined>(undefined)
813
818
  const {
814
819
  clampedRevealProgress,
@@ -861,9 +866,12 @@ function ViewEditorInner({
861
866
  // ── Dynamic viewport bounds ────────────────────────────────────────────────
862
867
  useEffect(() => {
863
868
  const vw = window.innerWidth; const vh = window.innerHeight
864
- const emptyExtent: [[number, number], [number, number]] = [[-vw, -vh], [vw, vh]]
869
+ const emptyExtent: [[number, number], [number, number]] = [
870
+ [-vw * VIEW_EDITOR_EMPTY_EXTENT_RATIO, -vh * VIEW_EDITOR_EMPTY_EXTENT_RATIO],
871
+ [vw * VIEW_EDITOR_EMPTY_EXTENT_RATIO, vh * VIEW_EDITOR_EMPTY_EXTENT_RATIO],
872
+ ]
865
873
  if (flowNodes.length === 0 && drawingPaths.length === 0) {
866
- setComputedMinZoom((prev) => prev === 0.05 ? prev : 0.05)
874
+ setComputedMinZoom((prev) => prev === VIEW_EDITOR_MIN_ZOOM_FLOOR ? prev : VIEW_EDITOR_MIN_ZOOM_FLOOR)
867
875
  setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, emptyExtent) ? prev : emptyExtent)
868
876
  return
869
877
  }
@@ -876,22 +884,22 @@ function ViewEditorInner({
876
884
  for (const pt of p.points) { minX = Math.min(minX, pt.x); minY = Math.min(minY, pt.y); maxX = Math.max(maxX, pt.x); maxY = Math.max(maxY, pt.y) }
877
885
  }
878
886
  if (!isFinite(minX)) {
879
- setComputedMinZoom((prev) => prev === 0.05 ? prev : 0.05)
887
+ setComputedMinZoom((prev) => prev === VIEW_EDITOR_MIN_ZOOM_FLOOR ? prev : VIEW_EDITOR_MIN_ZOOM_FLOOR)
880
888
  setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, emptyExtent) ? prev : emptyExtent)
881
889
  return
882
890
  }
883
891
  const bboxW = maxX - minX; const bboxH = maxY - minY
884
892
  let minZoom = Math.sqrt((0.12 * vw * vh) / Math.max(1, bboxW * bboxH))
885
- if (!isFinite(minZoom) || isNaN(minZoom) || minZoom <= 0) minZoom = 0.05
886
- const nextMinZoom = Math.max(0.05, Math.min(minZoom, 1))
893
+ if (!isFinite(minZoom) || isNaN(minZoom) || minZoom <= 0) minZoom = VIEW_EDITOR_MIN_ZOOM_FLOOR
894
+ const nextMinZoom = Math.max(VIEW_EDITOR_MIN_ZOOM_FLOOR, Math.min(minZoom, 1))
887
895
  setComputedMinZoom((prev) => prev === nextMinZoom ? prev : nextMinZoom)
888
896
  // Extent must be ≥ viewport at minZoom (else pan locks). Center on content bbox.
889
- // Slack = content-proportional so user can always pan a bit past content edges.
897
+ // Keep only modest content-proportional slack so the canvas stays discoverable.
890
898
  const vwFlowMax = vw / nextMinZoom; const vhFlowMax = vh / nextMinZoom
891
- const slackX = Math.max(bboxW * 0.5, 400)
892
- const slackY = Math.max(bboxH * 0.5, 400)
893
- const spanX = Math.max(bboxW + 2 * slackX, vwFlowMax + 2 * slackX)
894
- const spanY = Math.max(bboxH + 2 * slackY, vhFlowMax + 2 * slackY)
899
+ const slackX = Math.min(Math.max(bboxW * VIEW_EDITOR_PAN_MARGIN_RATIO, VIEW_EDITOR_PAN_MARGIN_MIN), VIEW_EDITOR_PAN_MARGIN_MAX)
900
+ const slackY = Math.min(Math.max(bboxH * VIEW_EDITOR_PAN_MARGIN_RATIO, VIEW_EDITOR_PAN_MARGIN_MIN), VIEW_EDITOR_PAN_MARGIN_MAX)
901
+ const spanX = Math.max(bboxW + 2 * slackX, vwFlowMax)
902
+ const spanY = Math.max(bboxH + 2 * slackY, vhFlowMax)
895
903
  const cx = (minX + maxX) / 2; const cy = (minY + maxY) / 2
896
904
  const nextTranslateExtent: [[number, number], [number, number]] = [[cx - spanX / 2, cy - spanY / 2], [cx + spanX / 2, cy + spanY / 2]]
897
905
  setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, nextTranslateExtent) ? prev : nextTranslateExtent)