feat: add custom body link component
This commit is contained in:
parent
f22f380b96
commit
47abc44506
8 changed files with 314 additions and 247 deletions
42
package-lock.json
generated
42
package-lock.json
generated
|
|
@ -10,7 +10,7 @@
|
|||
"dependencies": {
|
||||
"@radix-ui/react-collapsible": "^1.1.7",
|
||||
"@radix-ui/react-dialog": "^1.1.10",
|
||||
"@radix-ui/react-hover-card": "^1.1.14",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-separator": "^1.1.4",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
|
|
@ -1300,18 +1300,18 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.14.tgz",
|
||||
"integrity": "sha512-CPYZ24Mhirm+g6D8jArmLzjYu4Eyg3TTUHswR26QgzXBHBe64BO/RHOJKzmF/Dxb4y4f9PKyJdwm/O/AhNkb+Q==",
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz",
|
||||
"integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.2",
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-context": "1.1.2",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.10",
|
||||
"@radix-ui/react-popper": "1.2.7",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.11",
|
||||
"@radix-ui/react-popper": "1.2.8",
|
||||
"@radix-ui/react-portal": "1.1.9",
|
||||
"@radix-ui/react-presence": "1.1.4",
|
||||
"@radix-ui/react-presence": "1.1.5",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.2.2"
|
||||
},
|
||||
|
|
@ -1330,6 +1330,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/primitive": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
|
||||
"integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-arrow": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
|
||||
|
|
@ -1354,12 +1360,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-dismissable-layer": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz",
|
||||
"integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==",
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
|
||||
"integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.2",
|
||||
"@radix-ui/primitive": "1.1.3",
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.1.3",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.1",
|
||||
|
|
@ -1381,9 +1387,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz",
|
||||
"integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==",
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
|
||||
"integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom": "^2.0.0",
|
||||
|
|
@ -1437,9 +1443,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-hover-card/node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz",
|
||||
"integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==",
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
|
||||
"integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.2",
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
"dependencies": {
|
||||
"@radix-ui/react-collapsible": "^1.1.7",
|
||||
"@radix-ui/react-dialog": "^1.1.10",
|
||||
"@radix-ui/react-hover-card": "^1.1.14",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-label": "^2.1.7",
|
||||
"@radix-ui/react-separator": "^1.1.4",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
|
|
|
|||
13
src/App.css
13
src/App.css
|
|
@ -4,12 +4,12 @@ code {
|
|||
font-family: "JetBrains Mono";
|
||||
}
|
||||
|
||||
pre > code {
|
||||
pre>code {
|
||||
padding: 0.5rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
h2 > code {
|
||||
h2>code {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
|
|
@ -23,3 +23,12 @@ button[data-state="active"] {
|
|||
box-shadow:
|
||||
var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
/* .HoverCardContent { */
|
||||
/* width: 300px; */
|
||||
/* max-height: 500px; */
|
||||
/* } */
|
||||
|
||||
/* .HoverCardContent { */
|
||||
/* transform-origin: 10px; */
|
||||
/* } */
|
||||
|
|
|
|||
50
src/components/BodyLink.tsx
Normal file
50
src/components/BodyLink.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { useEffect, useState } from "react"
|
||||
import { useQueryClient } from "@tanstack/react-query"
|
||||
import api from "@/api/eolas-api"
|
||||
|
||||
export default function BodyLink({ link, children }) {
|
||||
const [entryExists, setEntryExists] = useState(false)
|
||||
const path = link.split("/").pop().split(".")[0]
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
useEffect(() => {
|
||||
const fetchEntryPreview = async () => {
|
||||
const cachedEntry = queryClient.getQueryData([`entry_${path}`])
|
||||
if (cachedEntry) {
|
||||
setEntryExists(true)
|
||||
console.info("INFO: Entry exists in cache.")
|
||||
} else {
|
||||
try {
|
||||
const remoteEntry = await queryClient.fetchQuery({
|
||||
queryKey: [`entry_${path}`],
|
||||
queryFn: () => api.get(`/entries/${path}`).then((res) => res.data),
|
||||
})
|
||||
|
||||
setEntryExists(true)
|
||||
console.info("INFO: Entry exists on remote.")
|
||||
} catch (error) {
|
||||
console.log(`INFO: Could not fetch entry ${path} ${error}`)
|
||||
setEntryExists(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchEntryPreview()
|
||||
}, [path, queryClient])
|
||||
|
||||
if (entryExists) {
|
||||
return (
|
||||
<a
|
||||
className="text-foreground underline-offset-4 underline hover:text-gray-700 dark:hover:text-green-300"
|
||||
href={`/entries/${path}`}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
} else
|
||||
return (
|
||||
<a className="text-red-500 line-through" href={`/entries/${path}`}>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import remarkMath from "remark-math"
|
|||
import rehypeKatex from "rehype-katex"
|
||||
import "katex/dist/katex.min.css"
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
import BodyLink from "./BodyLink"
|
||||
|
||||
const EntryLoadingSkeleton = () => {
|
||||
return (
|
||||
|
|
@ -59,11 +60,6 @@ export default function EntryBody({ body, isLoading }) {
|
|||
ol: ({ children }) => (
|
||||
<ol className="list-decimal ml-10 mb-4 space-y-1">{children}</ol>
|
||||
),
|
||||
a: ({ href, children }) => (
|
||||
<a href={href} target="_blank" rel="noopener noreferrer">
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
table: ({ children }) => (
|
||||
<table className="w-full mb-4 text-sm">{children}</table>
|
||||
),
|
||||
|
|
@ -94,7 +90,10 @@ export default function EntryBody({ body, isLoading }) {
|
|||
{children}
|
||||
</code>
|
||||
),
|
||||
img: ({ children, src }) => <ImagePreprocessor src={src} />,
|
||||
img: ({ src }) => <ImagePreprocessor src={src} />,
|
||||
a: ({ href, children }) => {
|
||||
return <BodyLink link={href} children={children} />
|
||||
},
|
||||
}}
|
||||
>
|
||||
{body}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ export default function EntryReferences({ entryTitle }) {
|
|||
queryFn: () => api.get(`/entries/outlinks/${entryTitle}`).then((res) => res.data),
|
||||
})
|
||||
|
||||
console.log(backlinks)
|
||||
return (
|
||||
<div className="w-full flex flex-row justify-between gap-3">
|
||||
<div className="w-full">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
html {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue