feat: binary highlight nested enums

This commit is contained in:
Victor Oliva
2024-10-28 10:39:55 +01:00
parent d1a9646b21
commit 2a06a5f3cf
4 changed files with 31 additions and 24 deletions
@@ -11,6 +11,7 @@ import {
TitleContext,
useReportBinaryStatus,
} from "./codec-components"
import { setHovered } from "@/codec-components/common/paths.state"
export const CEnum: EditEnum = ({
value,
@@ -39,12 +40,17 @@ export const CEnum: EditEnum = ({
if (value === NOTIN) return null
const innerPath = [...path, value.type]
const pathStr = path.join(".")
if (titleContainer) {
return (
<>
{titleElement ? (
<Portal node={titleElement}>
<span onClick={() => scrollToMarker(innerPath)}>
<span
onClick={() => scrollToMarker(innerPath)}
onMouseEnter={() => setHovered({ id: pathStr, hover: true })}
onMouseLeave={() => setHovered({ id: pathStr, hover: false })}
>
/ {value.type}
</span>
</Portal>
@@ -67,9 +73,9 @@ export const CEnum: EditEnum = ({
<div className="border-l border-polkadot-700">
<ItemTitle
icon={Enum}
path={innerPath.join(".")}
path={path.join(".")}
titleRef={setNewElement}
onNavigate={() => scrollToMarker(innerPath)}
onNavigate={() => scrollToMarker(path)}
onZoom={innerIsComplex ? () => focus.setFocus(innerPath) : undefined}
binaryStatus={{
encodedValue,
@@ -23,9 +23,7 @@ import {
PropsWithChildren,
ReactElement,
useContext,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react"
import { twMerge } from "tailwind-merge"
@@ -140,33 +138,17 @@ export const ItemTitle: FC<
const [binaryOpen, setBinaryOpen] = useState(false)
const isActive = useStateObservable(isActive$(path))
// react listeners don't work across portals, we need native listeners
const ref = useRef<HTMLDivElement | null>(null)
useEffect(() => {
if (!ref.current) return
const element = ref.current
const onMouseEnter = () => setHovered({ id: path, hover: true })
const onMouseLeave = () => setHovered({ id: path, hover: false })
element.addEventListener("mouseenter", onMouseEnter)
element.addEventListener("mouseleave", onMouseLeave)
return () => {
element.removeEventListener("mouseenter", onMouseEnter)
element.removeEventListener("mouseleave", onMouseLeave)
onMouseLeave()
}
}, [path])
return (
<>
<div
ref={ref}
className={twMerge(
"flex items-center",
isActive && "bg-polkadot-600 bg-opacity-20",
className,
)}
data-marker={`marker-${path}`}
onMouseEnter={() => setHovered({ id: path, hover: true })}
onMouseLeave={() => setHovered({ id: path, hover: false })}
>
<span
className={twMerge(
+18 -1
View File
@@ -40,7 +40,24 @@ export const Modal: FC<ModalProps> = ({
if (ref.open && !open) {
ref.close()
} else if (!ref.open && open) {
ref.showModal()
// Not sure why, having this run in a useEffect (or useLayoutEffect) causes
// an issue: on EditCodec+Tree, when hovering over a line of the tree view
// and pressing on "Edit binary", the modal causes the `mouseleave` event
// to not trigger, so the line becomes "Active" (and the binary view shows
// highlight of something not being hovered on).
// Seems that if `.showModal()` is called synchronously it doesn't happen.
// It doesn't happen if `.showModal()` is called in a setTimeout.
// But within a useEffect, the issue is present.
let canceled = false
setTimeout(() => {
if (canceled) {
return
}
ref.showModal()
})
return () => {
canceled = true
}
}
}, [open, ref])
+2
View File
@@ -1,4 +1,5 @@
import {
Marker,
MarkersContextProvider,
VisibleWindow,
} from "@/codec-components/common/Markers"
@@ -66,6 +67,7 @@ export const EditMode: React.FC<{
</div>
<div className="flex-1">
<div className="p-2 rounded bg-polkadot-900">
<Marker id={[]} />
<EditCodec {...props} />
</div>
</div>