add light theme support, underline links to block detail

This commit is contained in:
Victor Oliva
2024-11-09 13:51:47 +07:00
parent da8468a88d
commit bc80975e6b
8 changed files with 82 additions and 30 deletions

44
src/ThemeProvider.tsx Normal file
View File

@@ -0,0 +1,44 @@
import { state, useStateObservable } from "@react-rxjs/core"
import {
createContext,
FC,
PropsWithChildren,
useContext,
useLayoutEffect,
} from "react"
import { fromEvent, map } from "rxjs"
const getCurrentMedia = (): "light" | "dark" =>
window.matchMedia
? window.matchMedia("(prefers-color-scheme: dark)")
? "dark"
: "light"
: "dark"
const defaultTheme = getCurrentMedia()
const ThemeContext = createContext<"light" | "dark">(defaultTheme)
export const useTheme = () => useContext(ThemeContext)
const theme$ = state(
fromEvent<MediaQueryListEvent>(
window.matchMedia("(prefers-color-scheme: dark)"),
"change",
).pipe(map((evt) => (evt.matches ? "dark" : "light"))),
defaultTheme,
)
export const ThemeProvider: FC<PropsWithChildren> = ({ children }) => {
const theme = useStateObservable(theme$)
useLayoutEffect(() => {
if (theme === "dark") {
document.body.classList.add("dark")
} else {
document.body.classList.remove("dark")
}
}, [theme])
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
}

View File

@@ -110,7 +110,7 @@ export const CStruct: ViewStruct = ({
<ul
className={twMerge(
"flex flex-col w-full",
hasParentTitle && "border-l border-primary",
hasParentTitle && "border-l border-treeBorder",
)}
>
{Object.entries(innerComponents).map(([name, jsx]) => (

View File

@@ -5,26 +5,31 @@ import ReactJson from "react18-json-view"
import "react18-json-view/src/dark.css"
import "react18-json-view/src/style.css"
import "./jsonDisplay.css"
import { useTheme } from "@/ThemeProvider"
export const JsonDisplay: FC<{
src: unknown
}> = ({ src }) => (
<ReactJson
src={src}
dark
theme="a11y"
replacer={(v) => (v instanceof Binary ? bytesToString(v) : v)}
customizeCopy={(v) =>
JSON.stringify(
v,
(_, v) =>
typeof v === "bigint"
? `${v}n`
: v instanceof Binary
? bytesToString(v)
: v,
2,
)
}
/>
)
}> = ({ src }) => {
const theme = useTheme()
return (
<ReactJson
src={src}
dark={theme === "dark"}
theme="a11y"
replacer={(v) => (v instanceof Binary ? bytesToString(v) : v)}
customizeCopy={(v) =>
JSON.stringify(
v,
(_, v) =>
typeof v === "bigint"
? `${v}n`
: v instanceof Binary
? bytesToString(v)
: v,
2,
)
}
/>
)
}

View File

@@ -9,16 +9,19 @@ import { TooltipProvider } from "./components/Tooltip.tsx"
import "./index.css"
import { explorer$ } from "./pages/Explorer"
import { transactions$ } from "./pages/Transactions"
import { ThemeProvider } from "./ThemeProvider.tsx"
createRoot(document.getElementById("root")!).render(
<Subscribe source$={merge(dynamicBuilder$, explorer$, transactions$)}>
<RemoveSubscribe>
<StrictMode>
<BrowserRouter>
<TooltipProvider>
<App />
</TooltipProvider>
</BrowserRouter>
<ThemeProvider>
<BrowserRouter>
<TooltipProvider>
<App />
</TooltipProvider>
</BrowserRouter>
</ThemeProvider>
</StrictMode>
</RemoveSubscribe>
</Subscribe>,

View File

@@ -57,7 +57,7 @@ export const BlockPopover: FC<{ hash: string }> = ({ hash }) => {
Block
<Link
to={hash}
className="font-mono font-normal text-primary/70 hover:text-primary"
className="font-mono font-normal text-primary/70 hover:text-primary underline"
>
{hash.slice(0, 18)}
</Link>

View File

@@ -266,7 +266,7 @@ const BlockLink: FC<{ hash: string }> = ({ hash }) => {
return (
<Link
className="text-primary/70 hover:text-primary align-middle inline-flex items-center gap-1"
className="text-primary/70 hover:text-primary align-middle inline-flex items-center gap-1 underline"
to={`../${hash}`}
>
{<BlockStatusIcon state={block.status} size={20} />}

View File

@@ -13,7 +13,7 @@ export const EventPopover: FC<{ event: EventInfo }> = ({ event }) => {
Event{" "}
<Link
to={`${event.hash}#event=${event.index}`}
className="text-primary/70 hover:text-primary"
className="text-primary/70 hover:text-primary underline"
>
{eventKey(event)}
</Link>

View File

@@ -2,7 +2,7 @@ import { groupBy } from "@/lib/groupBy"
import type { SystemEvent } from "@polkadot-api/observable-client"
import { state } from "@react-rxjs/core"
import { combineKeys } from "@react-rxjs/utils"
import { filter, map, takeWhile, tap } from "rxjs"
import { filter, map, takeWhile } from "rxjs"
import { blockInfo$, BlockState, recordedBlocks$ } from "./block.state"
import { MAX_LENGTH } from "./BlockTable"