@industry-theme/file-city-panel 0.5.63 → 0.5.64
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/panels/FileCityTrailExplorerPanel/FileCityTrailExplorerPanel.d.ts.map +1 -1
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailFilePath.d.ts +34 -0
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailFilePath.d.ts.map +1 -0
- package/dist/panels/FileCityTrailExplorerPanel/overlays/TrailLeaderLine.d.ts.map +1 -1
- package/dist/panels.bundle.js +282 -38
- package/dist/panels.bundle.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileCityTrailExplorerPanel.d.ts","sourceRoot":"","sources":["../../../src/panels/FileCityTrailExplorerPanel/FileCityTrailExplorerPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"FileCityTrailExplorerPanel.d.ts","sourceRoot":"","sources":["../../../src/panels/FileCityTrailExplorerPanel/FileCityTrailExplorerPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,8BAA8B,CAAC;AAiBtC,OAAO,KAAK,EAEV,oCAAoC,EAErC,MAAM,wCAAwC,CAAC;AA4BhD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,EAAE,KAAK,CAAC,EAAE,CAC/C,oCAAoC,CA+ErC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CityBuilding } from '@principal-ai/file-city-react';
|
|
3
|
+
import type { OnCameraFrame } from './TrailLeaderLine';
|
|
4
|
+
export interface TrailFilePathHandle {
|
|
5
|
+
/** Pass this through alongside the leader-line's `onCameraFrame`. */
|
|
6
|
+
onCameraFrame: OnCameraFrame;
|
|
7
|
+
}
|
|
8
|
+
export interface TrailFilePathProps {
|
|
9
|
+
/** Container the SVG sits inside; used to convert client-rect coords to local. */
|
|
10
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Ordered list of buildings to walk through, one per marker. Empty
|
|
13
|
+
* (or single-entry) lists hide the path entirely. Repeats are kept
|
|
14
|
+
* — if a trail visits the same file twice, the path returns there.
|
|
15
|
+
*/
|
|
16
|
+
buildings: readonly CityBuilding[];
|
|
17
|
+
/**
|
|
18
|
+
* `FileCity3D` re-centers the city around the world origin, so building
|
|
19
|
+
* positions need this offset subtracted before projecting through the
|
|
20
|
+
* camera. Compute as `(bounds.minX + bounds.maxX) / 2` etc.
|
|
21
|
+
*/
|
|
22
|
+
cityCenter: {
|
|
23
|
+
x: number;
|
|
24
|
+
z: number;
|
|
25
|
+
} | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sequential-path overlay: connects every marker's building in order
|
|
29
|
+
* with a dashed curve, dots at each step, and step indices floating
|
|
30
|
+
* above the dots. Drawn imperatively from inside `onCameraFrame` so it
|
|
31
|
+
* stays in lockstep with the city's camera without re-rendering React.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TrailFilePath: React.ForwardRefExoticComponent<TrailFilePathProps & React.RefAttributes<TrailFilePathHandle>>;
|
|
34
|
+
//# sourceMappingURL=TrailFilePath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrailFilePath.d.ts","sourceRoot":"","sources":["../../../../src/panels/FileCityTrailExplorerPanel/overlays/TrailFilePath.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD;;;;OAIG;IACH,SAAS,EAAE,SAAS,YAAY,EAAE,CAAC;IACnC;;;;OAIG;IACH,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7C;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gGAsKxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrailLeaderLine.d.ts","sourceRoot":"","sources":["../../../../src/panels/FileCityTrailExplorerPanel/overlays/TrailLeaderLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KACpC,IAAI,CAAC;AAEV,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,0DAA0D;IAC1D,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5C,2EAA2E;IAC3E,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAChD;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"TrailLeaderLine.d.ts","sourceRoot":"","sources":["../../../../src/panels/FileCityTrailExplorerPanel/overlays/TrailLeaderLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KACpC,IAAI,CAAC;AAEV,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,0DAA0D;IAC1D,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,UAAU,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5C,2EAA2E;IAC3E,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAChD;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,oGAoM1B,CAAC"}
|
package/dist/panels.bundle.js
CHANGED
|
@@ -257701,14 +257701,30 @@ const TrailLeaderLine = React.forwardRef(function TrailLeaderLine2({ containerRe
|
|
|
257701
257701
|
const sx = canvasLeft + (v.x * 0.5 + 0.5) * size.width;
|
|
257702
257702
|
const sy = canvasTop + (v.y * -0.5 + 0.5) * size.height;
|
|
257703
257703
|
const HEADER_BAND_OFFSET = 22;
|
|
257704
|
-
const
|
|
257705
|
-
const aimRight = nodeCenterX < sx;
|
|
257706
|
-
const bx = aimRight ? nodeRect.right - containerRect.left : nodeRect.left - containerRect.left;
|
|
257704
|
+
const bx = nodeRect.left - containerRect.left;
|
|
257707
257705
|
const by = nodeRect.top - containerRect.top + HEADER_BAND_OFFSET;
|
|
257708
|
-
const
|
|
257709
|
-
const
|
|
257710
|
-
const
|
|
257711
|
-
|
|
257706
|
+
const ELBOW_GAP = 60;
|
|
257707
|
+
const CORNER_RADIUS = 14;
|
|
257708
|
+
const elbowX = Math.max(
|
|
257709
|
+
canvasLeft + 8,
|
|
257710
|
+
Math.min(sx, bx) - ELBOW_GAP
|
|
257711
|
+
);
|
|
257712
|
+
const goingUp = by < sy;
|
|
257713
|
+
const r2 = Math.min(
|
|
257714
|
+
CORNER_RADIUS,
|
|
257715
|
+
Math.abs(sy - by) / 2,
|
|
257716
|
+
Math.abs(sx - elbowX) / 2,
|
|
257717
|
+
Math.abs(bx - elbowX) / 2
|
|
257718
|
+
);
|
|
257719
|
+
const cornerSign = goingUp ? -1 : 1;
|
|
257720
|
+
const d = [
|
|
257721
|
+
`M ${sx} ${sy}`,
|
|
257722
|
+
`L ${elbowX + r2} ${sy}`,
|
|
257723
|
+
`Q ${elbowX} ${sy} ${elbowX} ${sy + cornerSign * r2}`,
|
|
257724
|
+
`L ${elbowX} ${by - cornerSign * r2}`,
|
|
257725
|
+
`Q ${elbowX} ${by} ${elbowX + r2} ${by}`,
|
|
257726
|
+
`L ${bx} ${by}`
|
|
257727
|
+
].join(" ");
|
|
257712
257728
|
const pathEl = pathRef.current;
|
|
257713
257729
|
const buildingEl = buildingMarkerRef.current;
|
|
257714
257730
|
const nodeMarkerEl = nodeMarkerRef.current;
|
|
@@ -257790,6 +257806,139 @@ const TrailLeaderLine = React.forwardRef(function TrailLeaderLine2({ containerRe
|
|
|
257790
257806
|
)
|
|
257791
257807
|
] });
|
|
257792
257808
|
});
|
|
257809
|
+
const TrailFilePath = React.forwardRef(function TrailFilePath2({ containerRef, buildings, cityCenter }, ref) {
|
|
257810
|
+
const { theme: theme2 } = useTheme();
|
|
257811
|
+
const color2 = theme2.colors.accent ?? "#22d3ee";
|
|
257812
|
+
const groupRef = React.useRef(null);
|
|
257813
|
+
const projectScratch = React.useRef(new THREE.Vector3());
|
|
257814
|
+
const buildingsRef = React.useRef(buildings);
|
|
257815
|
+
const cityCenterRef = React.useRef(cityCenter);
|
|
257816
|
+
React.useEffect(() => {
|
|
257817
|
+
buildingsRef.current = buildings;
|
|
257818
|
+
}, [buildings]);
|
|
257819
|
+
React.useEffect(() => {
|
|
257820
|
+
cityCenterRef.current = cityCenter;
|
|
257821
|
+
}, [cityCenter]);
|
|
257822
|
+
const hideAll = React.useCallback(() => {
|
|
257823
|
+
const g2 = groupRef.current;
|
|
257824
|
+
if (!g2) return;
|
|
257825
|
+
g2.setAttribute("opacity", "0");
|
|
257826
|
+
}, []);
|
|
257827
|
+
React.useEffect(() => {
|
|
257828
|
+
if (buildings.length < 2) hideAll();
|
|
257829
|
+
}, [buildings, hideAll]);
|
|
257830
|
+
const onCameraFrame = React.useCallback(
|
|
257831
|
+
(camera, size) => {
|
|
257832
|
+
const targets = buildingsRef.current;
|
|
257833
|
+
const center = cityCenterRef.current;
|
|
257834
|
+
const container = containerRef.current;
|
|
257835
|
+
const g2 = groupRef.current;
|
|
257836
|
+
if (!targets || targets.length < 2 || !center || !container || !g2 || size.width === 0) {
|
|
257837
|
+
hideAll();
|
|
257838
|
+
return;
|
|
257839
|
+
}
|
|
257840
|
+
const containerRect = container.getBoundingClientRect();
|
|
257841
|
+
const canvasEl = container.querySelector("canvas");
|
|
257842
|
+
if (!canvasEl) {
|
|
257843
|
+
hideAll();
|
|
257844
|
+
return;
|
|
257845
|
+
}
|
|
257846
|
+
const canvasRect = canvasEl.getBoundingClientRect();
|
|
257847
|
+
const canvasLeft = canvasRect.left - containerRect.left;
|
|
257848
|
+
const canvasTop = canvasRect.top - containerRect.top;
|
|
257849
|
+
const points = [];
|
|
257850
|
+
const v = projectScratch.current;
|
|
257851
|
+
for (const b of targets) {
|
|
257852
|
+
v.set(b.position.x - center.x, 0, b.position.z - center.z).project(
|
|
257853
|
+
camera
|
|
257854
|
+
);
|
|
257855
|
+
const visible = v.z <= 1;
|
|
257856
|
+
const x2 = canvasLeft + (v.x * 0.5 + 0.5) * size.width;
|
|
257857
|
+
const y2 = canvasTop + (v.y * -0.5 + 0.5) * size.height;
|
|
257858
|
+
points.push({ x: x2, y: y2, visible });
|
|
257859
|
+
}
|
|
257860
|
+
let d = "";
|
|
257861
|
+
for (let i = 0; i < points.length; i++) {
|
|
257862
|
+
const p2 = points[i];
|
|
257863
|
+
if (!p2.visible) {
|
|
257864
|
+
d += "";
|
|
257865
|
+
continue;
|
|
257866
|
+
}
|
|
257867
|
+
if (i === 0 || !points[i - 1].visible) {
|
|
257868
|
+
d += `M ${p2.x} ${p2.y} `;
|
|
257869
|
+
} else {
|
|
257870
|
+
d += `L ${p2.x} ${p2.y} `;
|
|
257871
|
+
}
|
|
257872
|
+
}
|
|
257873
|
+
while (g2.children.length < 1 + targets.length * 2) {
|
|
257874
|
+
g2.appendChild(
|
|
257875
|
+
document.createElementNS("http://www.w3.org/2000/svg", "path")
|
|
257876
|
+
);
|
|
257877
|
+
g2.appendChild(
|
|
257878
|
+
document.createElementNS("http://www.w3.org/2000/svg", "circle")
|
|
257879
|
+
);
|
|
257880
|
+
g2.appendChild(
|
|
257881
|
+
document.createElementNS("http://www.w3.org/2000/svg", "text")
|
|
257882
|
+
);
|
|
257883
|
+
}
|
|
257884
|
+
while (g2.children.length > 1 + targets.length * 2) {
|
|
257885
|
+
g2.removeChild(g2.children[g2.children.length - 1]);
|
|
257886
|
+
}
|
|
257887
|
+
const pathEl = g2.children[0];
|
|
257888
|
+
pathEl.setAttribute("d", d.trim() || "M 0 0");
|
|
257889
|
+
pathEl.setAttribute("fill", "none");
|
|
257890
|
+
pathEl.setAttribute("stroke", color2);
|
|
257891
|
+
pathEl.setAttribute("stroke-width", "2");
|
|
257892
|
+
pathEl.setAttribute("stroke-dasharray", "6 4");
|
|
257893
|
+
pathEl.setAttribute("opacity", "0.75");
|
|
257894
|
+
for (let i = 0; i < targets.length; i++) {
|
|
257895
|
+
const dot = g2.children[1 + i * 2];
|
|
257896
|
+
const label = g2.children[1 + i * 2 + 1];
|
|
257897
|
+
const p2 = points[i];
|
|
257898
|
+
if (!p2.visible) {
|
|
257899
|
+
dot.setAttribute("opacity", "0");
|
|
257900
|
+
label.setAttribute("opacity", "0");
|
|
257901
|
+
continue;
|
|
257902
|
+
}
|
|
257903
|
+
dot.setAttribute("cx", String(p2.x));
|
|
257904
|
+
dot.setAttribute("cy", String(p2.y));
|
|
257905
|
+
dot.setAttribute("r", "6");
|
|
257906
|
+
dot.setAttribute("fill", color2);
|
|
257907
|
+
dot.setAttribute("stroke", "#0f1419");
|
|
257908
|
+
dot.setAttribute("stroke-width", "1.5");
|
|
257909
|
+
dot.setAttribute("opacity", "1");
|
|
257910
|
+
label.setAttribute("x", String(p2.x));
|
|
257911
|
+
label.setAttribute("y", String(p2.y - 10));
|
|
257912
|
+
label.setAttribute("text-anchor", "middle");
|
|
257913
|
+
label.setAttribute("fill", color2);
|
|
257914
|
+
label.setAttribute("font-size", "11");
|
|
257915
|
+
label.setAttribute("font-weight", "600");
|
|
257916
|
+
label.setAttribute("opacity", "1");
|
|
257917
|
+
label.textContent = String(i + 1);
|
|
257918
|
+
}
|
|
257919
|
+
g2.setAttribute("opacity", "1");
|
|
257920
|
+
},
|
|
257921
|
+
[containerRef, hideAll, color2]
|
|
257922
|
+
);
|
|
257923
|
+
React.useImperativeHandle(ref, () => ({ onCameraFrame }), [onCameraFrame]);
|
|
257924
|
+
return /* @__PURE__ */ jsx(
|
|
257925
|
+
"svg",
|
|
257926
|
+
{
|
|
257927
|
+
width: "100%",
|
|
257928
|
+
height: "100%",
|
|
257929
|
+
style: {
|
|
257930
|
+
position: "absolute",
|
|
257931
|
+
inset: 0,
|
|
257932
|
+
pointerEvents: "none",
|
|
257933
|
+
overflow: "visible",
|
|
257934
|
+
// Above the city canvas (auto z-index) but below the floating
|
|
257935
|
+
// overlays (z 1900) so the path only paints over the city.
|
|
257936
|
+
zIndex: 26
|
|
257937
|
+
},
|
|
257938
|
+
children: /* @__PURE__ */ jsx("g", { ref: groupRef, opacity: 0 })
|
|
257939
|
+
}
|
|
257940
|
+
);
|
|
257941
|
+
});
|
|
257793
257942
|
const PANEL_WIDTH_PCT = 38;
|
|
257794
257943
|
const FLOAT_INSET = 16;
|
|
257795
257944
|
const MIN_WIDTH_PX = 360;
|
|
@@ -257970,8 +258119,8 @@ const TrailMarkdownOverlay = ({
|
|
|
257970
258119
|
) })
|
|
257971
258120
|
}
|
|
257972
258121
|
),
|
|
257973
|
-
files && files.length > 0 ? /* @__PURE__ */ jsx(TrailFilesList, { files }) : null,
|
|
257974
258122
|
nav ? /* @__PURE__ */ jsx(TrailMarkdownOverlayFooter, { nav }) : null,
|
|
258123
|
+
files && files.length > 0 ? /* @__PURE__ */ jsx(TrailFilesList, { files }) : null,
|
|
257975
258124
|
/* @__PURE__ */ jsx(
|
|
257976
258125
|
"div",
|
|
257977
258126
|
{
|
|
@@ -258533,7 +258682,7 @@ const pierreOptionsBase = {
|
|
|
258533
258682
|
const pierreStyle = {
|
|
258534
258683
|
display: "block"
|
|
258535
258684
|
};
|
|
258536
|
-
const SEQUENCE_DRAWER_HEIGHT_PCT =
|
|
258685
|
+
const SEQUENCE_DRAWER_HEIGHT_PCT = 45;
|
|
258537
258686
|
const SNIPPET_PANE_WIDTH_PX = 460;
|
|
258538
258687
|
const HEADER_HEIGHT_PX = 48;
|
|
258539
258688
|
const PANEL_TRANSITION_MS = 280;
|
|
@@ -258648,6 +258797,10 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258648
258797
|
const first = markersForThisRepo[0];
|
|
258649
258798
|
if (first) onSelectMarker(first.id);
|
|
258650
258799
|
}, [markersForThisRepo, onSelectMarker]);
|
|
258800
|
+
const [snippetExpanded, setSnippetExpanded] = React.useState(false);
|
|
258801
|
+
React.useEffect(() => {
|
|
258802
|
+
setSnippetExpanded(false);
|
|
258803
|
+
}, [selectedMarkerId]);
|
|
258651
258804
|
const handleStepPrev = React.useCallback(() => {
|
|
258652
258805
|
if (stepperIndex < 0) return;
|
|
258653
258806
|
if (stepperIndex === 0) {
|
|
@@ -258756,6 +258909,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258756
258909
|
const containerRef = React.useRef(null);
|
|
258757
258910
|
const snippetPaneRef = React.useRef(null);
|
|
258758
258911
|
const leaderLineRef = React.useRef(null);
|
|
258912
|
+
const filePathRef = React.useRef(null);
|
|
258759
258913
|
const [markdownOverlayWidth, setMarkdownOverlayWidth] = React.useState(null);
|
|
258760
258914
|
const [snippetPaneEl, setSnippetPaneEl] = React.useState(null);
|
|
258761
258915
|
const snippetPaneCallbackRef = React.useCallback(
|
|
@@ -258779,10 +258933,22 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258779
258933
|
z: (cityData.bounds.minZ + cityData.bounds.maxZ) / 2
|
|
258780
258934
|
};
|
|
258781
258935
|
}, [cityData]);
|
|
258936
|
+
const trailPathBuildings = React.useMemo(() => {
|
|
258937
|
+
if (!cityData || markersForThisRepo.length === 0) return [];
|
|
258938
|
+
const buildingByPath = new Map(cityData.buildings.map((b) => [b.path, b]));
|
|
258939
|
+
const out = [];
|
|
258940
|
+
for (const m of markersForThisRepo) {
|
|
258941
|
+
if (!m.sourcePath) continue;
|
|
258942
|
+
const b = buildingByPath.get(m.sourcePath) ?? cityData.buildings.find((cb) => cb.path.endsWith(`/${m.sourcePath}`));
|
|
258943
|
+
if (b) out.push(b);
|
|
258944
|
+
}
|
|
258945
|
+
return out;
|
|
258946
|
+
}, [cityData, markersForThisRepo]);
|
|
258782
258947
|
const onCameraFrame = React.useCallback(
|
|
258783
258948
|
(camera, size) => {
|
|
258784
|
-
var _a2;
|
|
258949
|
+
var _a2, _b2;
|
|
258785
258950
|
(_a2 = leaderLineRef.current) == null ? void 0 : _a2.onCameraFrame(camera, size);
|
|
258951
|
+
(_b2 = filePathRef.current) == null ? void 0 : _b2.onCameraFrame(camera, size);
|
|
258786
258952
|
},
|
|
258787
258953
|
[]
|
|
258788
258954
|
);
|
|
@@ -258844,10 +259010,9 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258844
259010
|
if (showSnippetPane && snippetPaneWidth == null) return;
|
|
258845
259011
|
const FLOAT_INSET2 = 16;
|
|
258846
259012
|
const leftInset = hasOverlayMarkdown ? markdownOverlayWidth ?? 0 : 0;
|
|
258847
|
-
const
|
|
258848
|
-
const
|
|
258849
|
-
const
|
|
258850
|
-
const bottomInset = drawerHeightPct / 100 * containerSize.height;
|
|
259013
|
+
const rightInset = 0;
|
|
259014
|
+
const topInset = showSnippetPane ? containerSize.height * 0.5 + FLOAT_INSET2 : FLOAT_INSET2;
|
|
259015
|
+
const bottomInset = showSnippetPane ? 0 : drawerHeightPct / 100 * containerSize.height;
|
|
258851
259016
|
const result = computeCameraFraming({
|
|
258852
259017
|
canvasW: containerSize.width,
|
|
258853
259018
|
canvasH: containerSize.height,
|
|
@@ -258920,6 +259085,13 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258920
259085
|
onToggleSequenceDrawer: () => {
|
|
258921
259086
|
setDrawerHeightOverridePct(null);
|
|
258922
259087
|
setShowSequenceDrawer((v) => !v);
|
|
259088
|
+
},
|
|
259089
|
+
canExit: selectedMarkerId != null || showSequenceDrawer || snippetExpanded,
|
|
259090
|
+
onExitTrail: () => {
|
|
259091
|
+
onSelectMarker(null);
|
|
259092
|
+
setShowSequenceDrawer(false);
|
|
259093
|
+
setDrawerHeightOverridePct(null);
|
|
259094
|
+
setSnippetExpanded(false);
|
|
258923
259095
|
}
|
|
258924
259096
|
}
|
|
258925
259097
|
),
|
|
@@ -258951,6 +259123,15 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258951
259123
|
defaultBuildingColor: trailFilesActive ? theme2.colors.textTertiary : void 0
|
|
258952
259124
|
}
|
|
258953
259125
|
) : /* @__PURE__ */ jsx(CityLoadingPlaceholder, {}),
|
|
259126
|
+
/* @__PURE__ */ jsx(
|
|
259127
|
+
TrailFilePath,
|
|
259128
|
+
{
|
|
259129
|
+
ref: filePathRef,
|
|
259130
|
+
containerRef,
|
|
259131
|
+
buildings: trailPathBuildings,
|
|
259132
|
+
cityCenter
|
|
259133
|
+
}
|
|
259134
|
+
),
|
|
258954
259135
|
/* @__PURE__ */ jsx(
|
|
258955
259136
|
TrailLeaderLine,
|
|
258956
259137
|
{
|
|
@@ -258978,7 +259159,7 @@ const FileCityTrailSequenceLayout = ({
|
|
|
258978
259159
|
onPrev: handleStepPrev,
|
|
258979
259160
|
onNext: handleStepNext
|
|
258980
259161
|
} : void 0,
|
|
258981
|
-
files: trailFiles
|
|
259162
|
+
files: showSequenceDrawer ? void 0 : trailFiles
|
|
258982
259163
|
}
|
|
258983
259164
|
) : null,
|
|
258984
259165
|
/* @__PURE__ */ jsx(
|
|
@@ -259005,7 +259186,9 @@ const FileCityTrailSequenceLayout = ({
|
|
|
259005
259186
|
readFile,
|
|
259006
259187
|
onClose: () => onSelectMarker(null),
|
|
259007
259188
|
drawerHeightPct,
|
|
259008
|
-
disableBottomTransition: isResizingDrawer
|
|
259189
|
+
disableBottomTransition: isResizingDrawer,
|
|
259190
|
+
expanded: snippetExpanded,
|
|
259191
|
+
onToggleExpanded: () => setSnippetExpanded((v) => !v)
|
|
259009
259192
|
}
|
|
259010
259193
|
) : null
|
|
259011
259194
|
]
|
|
@@ -259167,7 +259350,9 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259167
259350
|
readFile,
|
|
259168
259351
|
onClose,
|
|
259169
259352
|
drawerHeightPct,
|
|
259170
|
-
disableBottomTransition
|
|
259353
|
+
disableBottomTransition,
|
|
259354
|
+
expanded,
|
|
259355
|
+
onToggleExpanded
|
|
259171
259356
|
}, ref) {
|
|
259172
259357
|
const { theme: theme2 } = useTheme();
|
|
259173
259358
|
if (!marker.sourcePath) {
|
|
@@ -259179,6 +259364,8 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259179
259364
|
onClose,
|
|
259180
259365
|
drawerHeightPct,
|
|
259181
259366
|
disableBottomTransition,
|
|
259367
|
+
expanded,
|
|
259368
|
+
onToggleExpanded,
|
|
259182
259369
|
children: /* @__PURE__ */ jsx(
|
|
259183
259370
|
"div",
|
|
259184
259371
|
{
|
|
@@ -259202,6 +259389,8 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259202
259389
|
onClose,
|
|
259203
259390
|
drawerHeightPct,
|
|
259204
259391
|
disableBottomTransition,
|
|
259392
|
+
expanded,
|
|
259393
|
+
onToggleExpanded,
|
|
259205
259394
|
children: snippet2.kind === "slice" ? /* @__PURE__ */ jsx(
|
|
259206
259395
|
TrailSnippetView,
|
|
259207
259396
|
{
|
|
@@ -259236,7 +259425,15 @@ const SnippetSidePane = React.forwardRef(function SnippetSidePane2({
|
|
|
259236
259425
|
const SNIPPET_PANE_MIN_WIDTH_PX = 320;
|
|
259237
259426
|
const SNIPPET_PANE_RESIZE_HANDLE_WIDTH = 6;
|
|
259238
259427
|
const SidePaneFrame = React.forwardRef(
|
|
259239
|
-
function SidePaneFrame2({
|
|
259428
|
+
function SidePaneFrame2({
|
|
259429
|
+
marker,
|
|
259430
|
+
onClose,
|
|
259431
|
+
children: children2,
|
|
259432
|
+
drawerHeightPct,
|
|
259433
|
+
disableBottomTransition,
|
|
259434
|
+
expanded,
|
|
259435
|
+
onToggleExpanded
|
|
259436
|
+
}, ref) {
|
|
259240
259437
|
const { theme: theme2 } = useTheme();
|
|
259241
259438
|
const [widthPx, setWidthPx] = React.useState(null);
|
|
259242
259439
|
const [isResizing, setIsResizing] = React.useState(false);
|
|
@@ -259307,7 +259504,7 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259307
259504
|
position: "absolute",
|
|
259308
259505
|
top: 16,
|
|
259309
259506
|
right: 16,
|
|
259310
|
-
bottom: `calc(${drawerHeightPct}% + 16px)
|
|
259507
|
+
bottom: expanded ? `calc(${drawerHeightPct}% + 16px)` : "50%",
|
|
259311
259508
|
width: widthPx ?? SNIPPET_PANE_WIDTH_PX,
|
|
259312
259509
|
minWidth: SNIPPET_PANE_MIN_WIDTH_PX,
|
|
259313
259510
|
backgroundColor: theme2.colors.background,
|
|
@@ -259398,24 +259595,45 @@ const SidePaneFrame = React.forwardRef(
|
|
|
259398
259595
|
}
|
|
259399
259596
|
) : null
|
|
259400
259597
|
] }),
|
|
259401
|
-
/* @__PURE__ */
|
|
259402
|
-
|
|
259403
|
-
|
|
259404
|
-
|
|
259405
|
-
|
|
259406
|
-
|
|
259407
|
-
|
|
259408
|
-
|
|
259409
|
-
|
|
259410
|
-
|
|
259411
|
-
|
|
259412
|
-
|
|
259413
|
-
|
|
259414
|
-
|
|
259415
|
-
|
|
259416
|
-
|
|
259417
|
-
|
|
259418
|
-
|
|
259598
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, flexShrink: 0 }, children: [
|
|
259599
|
+
/* @__PURE__ */ jsx(
|
|
259600
|
+
"button",
|
|
259601
|
+
{
|
|
259602
|
+
onClick: onToggleExpanded,
|
|
259603
|
+
"aria-pressed": expanded,
|
|
259604
|
+
title: expanded ? "Collapse to top half (city visible below)" : "Expand to fill the right column",
|
|
259605
|
+
style: {
|
|
259606
|
+
background: "transparent",
|
|
259607
|
+
color: theme2.colors.text,
|
|
259608
|
+
border: `1px solid ${theme2.colors.muted}`,
|
|
259609
|
+
borderRadius: theme2.radii[2],
|
|
259610
|
+
padding: "2px 8px",
|
|
259611
|
+
cursor: "pointer",
|
|
259612
|
+
fontSize: theme2.fontSizes[0],
|
|
259613
|
+
fontFamily: theme2.fonts.body,
|
|
259614
|
+
lineHeight: 1.2
|
|
259615
|
+
},
|
|
259616
|
+
children: expanded ? "▾" : "▴"
|
|
259617
|
+
}
|
|
259618
|
+
),
|
|
259619
|
+
/* @__PURE__ */ jsx(
|
|
259620
|
+
"button",
|
|
259621
|
+
{
|
|
259622
|
+
onClick: onClose,
|
|
259623
|
+
style: {
|
|
259624
|
+
background: "transparent",
|
|
259625
|
+
color: theme2.colors.text,
|
|
259626
|
+
border: `1px solid ${theme2.colors.muted}`,
|
|
259627
|
+
borderRadius: theme2.radii[2],
|
|
259628
|
+
padding: "2px 8px",
|
|
259629
|
+
cursor: "pointer",
|
|
259630
|
+
fontSize: theme2.fontSizes[0],
|
|
259631
|
+
fontFamily: theme2.fonts.body
|
|
259632
|
+
},
|
|
259633
|
+
children: "Close"
|
|
259634
|
+
}
|
|
259635
|
+
)
|
|
259636
|
+
] })
|
|
259419
259637
|
]
|
|
259420
259638
|
}
|
|
259421
259639
|
),
|
|
@@ -259432,7 +259650,9 @@ const TrailHeader = ({
|
|
|
259432
259650
|
onToggle3D,
|
|
259433
259651
|
hideToggle = false,
|
|
259434
259652
|
showSequenceDrawer,
|
|
259435
|
-
onToggleSequenceDrawer
|
|
259653
|
+
onToggleSequenceDrawer,
|
|
259654
|
+
canExit,
|
|
259655
|
+
onExitTrail
|
|
259436
259656
|
}) => {
|
|
259437
259657
|
const { theme: theme2 } = useTheme();
|
|
259438
259658
|
const toggleButtonStyle = (active) => ({
|
|
@@ -259517,6 +259737,30 @@ const TrailHeader = ({
|
|
|
259517
259737
|
children: "Diagram"
|
|
259518
259738
|
}
|
|
259519
259739
|
),
|
|
259740
|
+
/* @__PURE__ */ jsx(
|
|
259741
|
+
"button",
|
|
259742
|
+
{
|
|
259743
|
+
type: "button",
|
|
259744
|
+
onClick: onExitTrail,
|
|
259745
|
+
disabled: !canExit,
|
|
259746
|
+
title: canExit ? "Return to the trail summary" : "Already at the trail summary",
|
|
259747
|
+
style: {
|
|
259748
|
+
flexShrink: 0,
|
|
259749
|
+
fontFamily: theme2.fonts.body,
|
|
259750
|
+
fontSize: theme2.fontSizes[0],
|
|
259751
|
+
fontWeight: theme2.fontWeights.medium,
|
|
259752
|
+
color: canExit ? theme2.colors.text : theme2.colors.textTertiary,
|
|
259753
|
+
background: "transparent",
|
|
259754
|
+
border: `1px solid ${theme2.colors.muted}`,
|
|
259755
|
+
borderRadius: theme2.radii[3],
|
|
259756
|
+
padding: "4px 10px",
|
|
259757
|
+
cursor: canExit ? "pointer" : "not-allowed",
|
|
259758
|
+
opacity: canExit ? 1 : 0.5,
|
|
259759
|
+
lineHeight: 1.2
|
|
259760
|
+
},
|
|
259761
|
+
children: "Exit"
|
|
259762
|
+
}
|
|
259763
|
+
),
|
|
259520
259764
|
hideToggle ? null : /* @__PURE__ */ jsx(
|
|
259521
259765
|
"button",
|
|
259522
259766
|
{
|