@tldiagram/core-ui 1.87.0 → 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,10 +1,10 @@
1
1
  {
2
2
  "name": "@tldiagram/core-ui",
3
- "version": "1.87.0",
3
+ "version": "1.90.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://github.com/Mertcikla/tld"
7
+ "url": "git+https://github.com/Mertcikla/tld.git"
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "module": "./dist/index.js",
package/src/index.ts CHANGED
@@ -99,7 +99,7 @@ export { HeaderProvider, useSetHeader, useHeader } from './components/HeaderCont
99
99
  export * from './types'
100
100
 
101
101
  // ─── Platform ────────────────────────────────────────────────────────────────
102
- export type { PlatformFeatures } from './platform/types'
102
+ export type { PlatformFeatures, PlatformRouteContext } from './platform/types'
103
103
  export { platform as localPlatform } from './platform/local'
104
104
  export { PlatformProvider } from './platform/PlatformContext'
105
105
  export { usePlatform } from './platform/context'
@@ -18,7 +18,6 @@ import {
18
18
  useDisclosure,
19
19
  VStack,
20
20
  } from '@chakra-ui/react'
21
- import { useSetHeader } from '../components/HeaderContext'
22
21
  import { api } from '../api/client'
23
22
  import type { ExploreData, ViewLayer } from '../types'
24
23
  import { FitViewIcon as FitViewSvg, TagsIcon, EyeIcon, EyeOffIcon, FocusIcon as FocusSvg } from '../components/Icons'
@@ -40,7 +39,6 @@ const MINI_ONBOARDING_KEY = 'shared_zoom_onboarding_dismissed'
40
39
  // ── Inner component ────────────────────────────────────────────────
41
40
  function InfiniteZoomInner({ sharedToken, shareSlot }: Props) {
42
41
  const navigate = useNavigate()
43
- const setHeader = useSetHeader()
44
42
 
45
43
  const [data, setData] = useState<ExploreData | null>(null)
46
44
  const [loading, setLoading] = useState(true)
@@ -111,11 +109,6 @@ function InfiniteZoomInner({ sharedToken, shareSlot }: Props) {
111
109
  setHiddenTags(prev => prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag])
112
110
  }, [])
113
111
 
114
- // Set page header
115
- useEffect(() => {
116
- setHeader({ node: <Text fontWeight="medium" fontSize="sm" color="gray.300">Explore</Text> })
117
- return () => setHeader(null)
118
- }, [setHeader])
119
112
  useEffect(() => {
120
113
  if (sharedToken && canvasReady && !localStorage.getItem(MINI_ONBOARDING_KEY)) {
121
114
  setShowMiniOnboarding(true)
@@ -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,
@@ -860,9 +865,14 @@ function ViewEditorInner({
860
865
 
861
866
  // ── Dynamic viewport bounds ────────────────────────────────────────────────
862
867
  useEffect(() => {
868
+ const vw = window.innerWidth; const vh = window.innerHeight
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
+ ]
863
873
  if (flowNodes.length === 0 && drawingPaths.length === 0) {
864
- setComputedMinZoom((prev) => prev === 0.05 ? prev : 0.05)
865
- setComputedTranslateExtent((prev) => prev === undefined ? prev : undefined)
874
+ setComputedMinZoom((prev) => prev === VIEW_EDITOR_MIN_ZOOM_FLOOR ? prev : VIEW_EDITOR_MIN_ZOOM_FLOOR)
875
+ setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, emptyExtent) ? prev : emptyExtent)
866
876
  return
867
877
  }
868
878
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity
@@ -874,18 +884,24 @@ function ViewEditorInner({
874
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) }
875
885
  }
876
886
  if (!isFinite(minX)) {
877
- setComputedMinZoom((prev) => prev === 0.05 ? prev : 0.05)
878
- setComputedTranslateExtent((prev) => prev === undefined ? prev : undefined)
887
+ setComputedMinZoom((prev) => prev === VIEW_EDITOR_MIN_ZOOM_FLOOR ? prev : VIEW_EDITOR_MIN_ZOOM_FLOOR)
888
+ setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, emptyExtent) ? prev : emptyExtent)
879
889
  return
880
890
  }
881
- const vw = window.innerWidth; const vh = window.innerHeight
882
891
  const bboxW = maxX - minX; const bboxH = maxY - minY
883
892
  let minZoom = Math.sqrt((0.12 * vw * vh) / Math.max(1, bboxW * bboxH))
884
- if (!isFinite(minZoom) || isNaN(minZoom) || minZoom <= 0) minZoom = 0.05
885
- 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))
886
895
  setComputedMinZoom((prev) => prev === nextMinZoom ? prev : nextMinZoom)
887
- const pmX = Math.max(vw * 2, 2000); const pmY = Math.max(vh * 2, 2000)
888
- const nextTranslateExtent: [[number, number], [number, number]] = [[minX - pmX, minY - pmY], [maxX + pmX, maxY + pmY]]
896
+ // Extent must be viewport at minZoom (else pan locks). Center on content bbox.
897
+ // Keep only modest content-proportional slack so the canvas stays discoverable.
898
+ const vwFlowMax = vw / nextMinZoom; const vhFlowMax = vh / nextMinZoom
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)
903
+ const cx = (minX + maxX) / 2; const cy = (minY + maxY) / 2
904
+ const nextTranslateExtent: [[number, number], [number, number]] = [[cx - spanX / 2, cy - spanY / 2], [cx + spanX / 2, cy + spanY / 2]]
889
905
  setComputedTranslateExtent((prev) => areTranslateExtentsEqual(prev, nextTranslateExtent) ? prev : nextTranslateExtent)
890
906
  }, [flowNodes, drawingPaths])
891
907
 
@@ -1133,7 +1149,7 @@ function ViewEditorInner({
1133
1149
  onPaneContextMenu={onPaneContextMenu} onPaneClick={onPaneClick}
1134
1150
  onPaneMouseMove={onPaneMouseMove}
1135
1151
  onMoveStart={onMoveStart} onMove={onMove} onMoveEnd={onMoveEnd}
1136
- translateExtent={computedTranslateExtent} minZoom={computedMinZoom}
1152
+ translateExtent={computedTranslateExtent} nodeExtent={computedTranslateExtent} minZoom={computedMinZoom} maxZoom={4}
1137
1153
  onReconnect={onReconnect} onReconnectStart={onReconnectStart} onReconnectEnd={onReconnectEnd}
1138
1154
  nodeTypes={nodeTypesMemo} edgeTypes={edgeTypesMemo}
1139
1155
  nodesDraggable={canEdit} connectionMode={ConnectionMode.Loose} connectionRadius={25}
package/dist/favicon.svg DELETED
@@ -1,35 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">
3
- <defs>
4
- <clipPath id="roundsq">
5
- <rect width="1024" height="1024" rx="224" ry="224" />
6
- </clipPath>
7
- <filter id="dshadow" x="-50%" y="-50%" width="200%" height="200%">
8
- <feGaussianBlur in="SourceAlpha" stdDeviation="32" result="blur1" />
9
- <feFlood flood-color="#63b3ed" flood-opacity="0.3" result="c1" />
10
- <feComposite in="c1" in2="blur1" operator="in" result="glow1" />
11
- <feGaussianBlur in="SourceAlpha" stdDeviation="10" result="blur2" />
12
- <feFlood flood-color="#90cdf4" flood-opacity="0.5" result="c2" />
13
- <feComposite in="c2" in2="blur2" operator="in" result="glow2" />
14
- <feDropShadow dx="0" dy="20" stdDeviation="20" flood-color="#000" flood-opacity="0.9"
15
- result="drop" />
16
- <feMerge>
17
- <feMergeNode in="glow1" />
18
- <feMergeNode in="glow2" />
19
- <feMergeNode in="SourceGraphic" />
20
- </feMerge>
21
- </filter>
22
- <linearGradient id="dgrad" x1="0" y1="0" x2="0.6" y2="1">
23
- <stop offset="0" stop-color="#90cdf4" />
24
- <stop offset="0.45" stop-color="#63b3ed" />
25
- <stop offset="1" stop-color="#2b6cb0" />
26
- </linearGradient>
27
- </defs>
28
- <g clip-path="url(#roundsq)" transform="matrix(1, 0, 0, 1, -1.4210854715202004e-14, 0)">
29
- <g filter="url(#dshadow)" transform="translate(78, 118) scale(0.8)" fill-rule="evenodd">
30
- <path
31
- d="M201 18s169-39 340-2c171 38 342 152 342 457S713 902 544 949c-170 48-344 19-344 19l1-566h302V217H201z M455 715c-67 83-122 141-62 48q23-35 33-62h-4a78 78 0 1 1 78-78q0 24-12 44-11 21-33 48"
32
- fill="url(#dgrad)" />
33
- </g>
34
- </g>
35
- </svg>
package/dist/logo-120.png DELETED
Binary file
package/dist/logo-bw.png DELETED
Binary file
package/dist/logo-bw.svg DELETED
@@ -1,15 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">
3
- <defs>
4
- <clipPath id="roundsq">
5
- <rect width="1024" height="1024" rx="224" ry="224" />
6
- </clipPath>
7
- </defs>
8
- <g clip-path="url(#roundsq)">
9
- <g transform="translate(78, 118) scale(0.8)" fill-rule="evenodd">
10
- <path
11
- d="M201 18s169-39 340-2c171 38 342 152 342 457S713 902 544 949c-170 48-344 19-344 19l1-566h302V217H201z M455 715c-67 83-122 141-62 48q23-35 33-62h-4a78 78 0 1 1 78-78q0 24-12 44-11 21-33 48"
12
- fill="#000000" />
13
- </g>
14
- </g>
15
- </svg>