Skip to content

Commit a53183d

Browse files
authored
fix long ass errors overlapping (#363)
1 parent 51d7632 commit a53183d

File tree

10 files changed

+3711
-54
lines changed

10 files changed

+3711
-54
lines changed

bun.lock

Lines changed: 99 additions & 29 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@
2828
"@tscircuit/soup-util": "^0.0.41",
2929
"@types/color": "^3.0.6",
3030
"@types/node": "18.7.23",
31-
"@types/react": "^18.3.3",
31+
"@types/react": "19",
3232
"circuit-json": "^0.0.194",
3333
"next": "^14.1.4",
3434
"pixi.js": "^8.6.6",
35-
"react": "^18.2.0",
35+
"react": "19.1.0",
3636
"react-cosmos": "7.0.0-beta.4",
3737
"react-cosmos-plugin-vite": "7.0.0-beta.0",
38-
"react-dom": "^18.2.0",
38+
"react-dom": "19.1.0",
3939
"react-use": "^17.4.0",
4040
"tscircuit": "^0.0.606",
4141
"tsup": "^8.0.2",
@@ -51,7 +51,7 @@
5151
},
5252
"dependencies": {
5353
"@emotion/css": "^11.11.2",
54-
"@vitejs/plugin-react": "^4.5.0",
54+
"@vitejs/plugin-react": "^5.0.2",
5555
"circuit-to-svg": "^0.0.166",
5656
"color": "^4.2.3",
5757
"react-supergrid": "^1.0.10",

src/components/CanvasPrimitiveRenderer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const CanvasPrimitiveRenderer = ({
4040
width = 500,
4141
height = 500,
4242
}: Props) => {
43-
const canvasRefs = useRef<Record<string, HTMLCanvasElement>>()
43+
const canvasRefs = useRef<Record<string, HTMLCanvasElement>>({})
4444
const selectedLayer = useGlobalStore((s) => s.selected_layer)
4545

4646
useEffect(() => {

src/components/ToolbarOverlay.tsx

Lines changed: 162 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -286,26 +286,172 @@ export const ToolbarOverlay = ({ children, elements }: Props) => {
286286
</ToolbarButton>
287287
<ToolbarButton
288288
isSmallScreen={isSmallScreen}
289-
style={errorCount > 0 ? { color: "red" } : {}}
289+
style={{
290+
position: "relative",
291+
...(errorCount > 0 ? { color: "red" } : {}),
292+
}}
290293
onClick={() => setErrorsOpen(!isErrorsOpen)}
291-
onMouseLeave={() => setErrorsOpen(false)}
292294
>
293295
<div>{errorCount} errors</div>
294-
{isErrorsOpen && (
295-
<div
296-
style={{ display: "grid", gridTemplateColumns: "100px 300px" }}
297-
>
298-
{elements
299-
?.filter((e): e is PcbTraceError => e.type.includes("error"))
300-
.map((e, i) => (
301-
<Fragment key={i}>
302-
<div>{e.error_type}</div>
303-
<div>{e.message}</div>
304-
</Fragment>
305-
))}
306-
</div>
307-
)}
308296
</ToolbarButton>
297+
{isErrorsOpen && (
298+
<div
299+
style={{
300+
position: "absolute",
301+
top: "100%",
302+
left: 0,
303+
backgroundColor: "#2a2a2a",
304+
border: "1px solid #666",
305+
borderRadius: 4,
306+
marginTop: 4,
307+
zIndex: 1000,
308+
minWidth: isSmallScreen ? "280px" : "400px",
309+
maxWidth: isSmallScreen ? "90vw" : "600px",
310+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.3)",
311+
}}
312+
>
313+
{(() => {
314+
const errorElements =
315+
elements?.filter((el): el is PcbTraceError =>
316+
el.type.includes("error"),
317+
) || []
318+
const errorCount = errorElements.length
319+
320+
return errorElements.map((e, i) => (
321+
<div
322+
key={i}
323+
style={{
324+
borderBottom:
325+
i < errorCount - 1 ? "1px solid #444" : "none",
326+
}}
327+
>
328+
<div
329+
style={{
330+
display: "flex",
331+
alignItems: "center",
332+
gap: 12,
333+
padding: "12px 16px",
334+
cursor: "pointer",
335+
backgroundColor: "#2a2a2a",
336+
transition: "background-color 0.2s ease",
337+
touchAction: "manipulation",
338+
userSelect: "none",
339+
}}
340+
onMouseEnter={(e) => {
341+
e.currentTarget.style.backgroundColor = "#333"
342+
}}
343+
onMouseLeave={(e) => {
344+
e.currentTarget.style.backgroundColor = "#2a2a2a"
345+
}}
346+
onTouchStart={(e) => {
347+
e.stopPropagation()
348+
e.currentTarget.style.backgroundColor = "#333"
349+
}}
350+
onTouchEnd={(e) => {
351+
e.stopPropagation()
352+
e.preventDefault()
353+
e.currentTarget.style.backgroundColor = "#2a2a2a"
354+
355+
const errorElement = document.querySelector(
356+
`[data-error-id="${i}"]`,
357+
) as HTMLElement
358+
const arrow = document.querySelector(
359+
`[data-arrow-id="${i}"]`,
360+
) as HTMLElement
361+
if (errorElement && arrow) {
362+
const isVisible = errorElement.style.display !== "none"
363+
errorElement.style.display = isVisible
364+
? "none"
365+
: "block"
366+
arrow.style.transform = isVisible
367+
? "rotate(90deg)"
368+
: "rotate(0deg)"
369+
}
370+
}}
371+
onClick={(e) => {
372+
e.stopPropagation()
373+
const errorElement = document.querySelector(
374+
`[data-error-id="${i}"]`,
375+
) as HTMLElement
376+
const arrow = document.querySelector(
377+
`[data-arrow-id="${i}"]`,
378+
) as HTMLElement
379+
if (errorElement && arrow) {
380+
const isVisible = errorElement.style.display !== "none"
381+
errorElement.style.display = isVisible
382+
? "none"
383+
: "block"
384+
arrow.style.transform = isVisible
385+
? "rotate(90deg)"
386+
: "rotate(0deg)"
387+
}
388+
}}
389+
>
390+
<div
391+
style={{
392+
fontWeight: "bold",
393+
fontSize: isSmallScreen ? "12px" : "13px",
394+
whiteSpace: "nowrap",
395+
flexShrink: 0,
396+
color: "#ff6b6b",
397+
display: isSmallScreen ? "none" : "block",
398+
}}
399+
>
400+
{e.error_type}
401+
</div>
402+
<div
403+
style={{
404+
flex: 1,
405+
fontSize: isSmallScreen ? "12px" : "13px",
406+
color: "#ddd",
407+
lineHeight: 1.4,
408+
overflow: "hidden",
409+
textOverflow: "ellipsis",
410+
whiteSpace: "nowrap",
411+
}}
412+
>
413+
{e.message}
414+
</div>
415+
<div
416+
data-arrow-id={i}
417+
style={{
418+
color: "#888",
419+
fontSize: "16px",
420+
transform: "rotate(90deg)",
421+
transition: "transform 0.2s ease",
422+
flexShrink: 0,
423+
}}
424+
>
425+
426+
</div>
427+
</div>
428+
<div
429+
data-error-id={i}
430+
style={{
431+
display: "none",
432+
padding: "12px 16px",
433+
backgroundColor: "#1a1a1a",
434+
borderTop: "1px solid #444",
435+
}}
436+
>
437+
<div
438+
style={{
439+
fontSize: isSmallScreen ? "11px" : "12px",
440+
color: "#ccc",
441+
lineHeight: 1.5,
442+
wordWrap: "break-word",
443+
overflowWrap: "break-word",
444+
hyphens: "auto",
445+
}}
446+
>
447+
{e.message}
448+
</div>
449+
</div>
450+
</div>
451+
))
452+
})()}
453+
</div>
454+
)}
309455
<ToolbarButton
310456
isSmallScreen={isSmallScreen}
311457
style={{}}

0 commit comments

Comments
 (0)