feat(app): collapsible map legend (persisted)
This commit is contained in:
@@ -19,6 +19,7 @@ import "@xyflow/react/dist/style.css"
|
|||||||
import { useNavigate, useSearchParams } from "react-router-dom"
|
import { useNavigate, useSearchParams } from "react-router-dom"
|
||||||
import {
|
import {
|
||||||
BoxSelect,
|
BoxSelect,
|
||||||
|
ChevronDown,
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
Globe,
|
Globe,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
@@ -1310,7 +1311,26 @@ export function SystemMapPage() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LEGEND_KEY = "castle-map-legend-open"
|
||||||
|
|
||||||
function Legend() {
|
function Legend() {
|
||||||
|
const [open, setOpen] = useState(() => {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem(LEGEND_KEY) !== "false"
|
||||||
|
} catch {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const toggle = () =>
|
||||||
|
setOpen((o) => {
|
||||||
|
const next = !o
|
||||||
|
try {
|
||||||
|
localStorage.setItem(LEGEND_KEY, String(next))
|
||||||
|
} catch {
|
||||||
|
/* storage disabled */
|
||||||
|
}
|
||||||
|
return next
|
||||||
|
})
|
||||||
const items = [
|
const items = [
|
||||||
{ c: PROTO_COLOR.http, label: "consumes — http" },
|
{ c: PROTO_COLOR.http, label: "consumes — http" },
|
||||||
{ c: PROTO_COLOR.pg, label: "consumes — pg / db" },
|
{ c: PROTO_COLOR.pg, label: "consumes — pg / db" },
|
||||||
@@ -1322,7 +1342,16 @@ function Legend() {
|
|||||||
{ c: "#2ea043", label: "public — internet" },
|
{ c: "#2ea043", label: "public — internet" },
|
||||||
]
|
]
|
||||||
return (
|
return (
|
||||||
<div className="absolute bottom-3 right-3 z-10 flex flex-col gap-1.5 rounded-md border border-[var(--border)] bg-[var(--card)]/90 px-3 py-2 text-[11px] text-[var(--muted)]">
|
<div className="absolute bottom-3 right-3 z-10 overflow-hidden rounded-md border border-[var(--border)] bg-[var(--card)]/90 text-[11px] text-[var(--muted)]">
|
||||||
|
<button
|
||||||
|
onClick={toggle}
|
||||||
|
className="flex w-full items-center gap-1.5 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wide hover:text-[var(--card-foreground)]"
|
||||||
|
>
|
||||||
|
<ChevronDown size={12} className={`transition-transform ${open ? "" : "-rotate-90"}`} />
|
||||||
|
Legend
|
||||||
|
</button>
|
||||||
|
{open && (
|
||||||
|
<div className="flex flex-col gap-1.5 px-3 pb-2">
|
||||||
{items.map((i) => (
|
{items.map((i) => (
|
||||||
<div key={i.label} className="flex items-center gap-2">
|
<div key={i.label} className="flex items-center gap-2">
|
||||||
<span
|
<span
|
||||||
@@ -1345,6 +1374,8 @@ function Legend() {
|
|||||||
Select a line or node + <kbd className="rounded bg-black/40 px-1">Del</kbd> to remove.
|
Select a line or node + <kbd className="rounded bg-black/40 px-1">Del</kbd> to remove.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user