[site/components][s]: contentlayer data in tooltip

This commit is contained in:
olayway 2022-05-22 15:00:04 +02:00
parent 6af3ef9bd2
commit 40a51ac22b
4 changed files with 33 additions and 38 deletions

View File

@ -1,38 +1,21 @@
import { useRouter } from 'next/router'
import { Tooltip } from './Tooltip'; import { Tooltip } from './Tooltip';
import siteConfig from '../config/siteConfig.js' import siteConfig from '../config/siteConfig.js'
/** /**
* Component for adding previews on hover for specific anchor tags. * Component for adding previews on hovering over anchor tags with relative paths
* Note: currently tooltips will be displayed only for anchor tags pointing to concepts.
*/ */
export const Anchor = (props) => { export const Anchor = (props) => {
const { href } = props; /* Check if the path is relative */
const router = useRouter(); const pathIsRelative = (path) => {
return path &&
/* Check if the url is relative */ path.indexOf("http:") !== 0 &&
const urlIsRelative = (url) => { path.indexOf("https:") !== 0 &&
return href && path.indexOf("#") !== 0
href.indexOf("http:") !== 0 &&
href.indexOf("https:") !== 0
} }
/* Return absolute path to raw markdown content if (pathIsRelative(props.href)) {
* Note: currently disabled for guide page due to non-standard relative paths in some anchors (TBD) */
const getRawMdContentUrl = (url, routerPath) => {
if (routerPath === '/guide' || !urlIsRelative(url)) {
return null
}
const currentPageMdUrl = [siteConfig.repoRawContentRoot, routerPath].join("");
return new URL(href, currentPageMdUrl).href;
}
const rawMdUrl = getRawMdContentUrl(href, router.asPath);
if (rawMdUrl && !rawMdUrl.includes("notes") && !rawMdUrl.includes("claims")) {
return ( return (
<Tooltip {...props} absolutePath={rawMdUrl} render={ tooltipTriggerProps => ( <Tooltip {...props} render={ tooltipTriggerProps => (
<a {...tooltipTriggerProps} /> <a {...tooltipTriggerProps} />
)} )}
/> />

View File

@ -14,13 +14,14 @@ import {
useRole, useRole,
} from '@floating-ui/react-dom-interactions' } from '@floating-ui/react-dom-interactions'
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import { allOtherPages } from 'contentlayer/generated';
import documentExtract from '../utils/documentExtract' import documentExtract from '../utils/documentExtract'
const tooltipBoxStyle = (theme) => ({ const tooltipBoxStyle = (theme) => ({
height: 'auto', height: 'auto',
maxWidth: '30rem', maxWidth: '40rem',
padding: '1rem', padding: '1rem',
background: theme === 'light' ? '#fff' : '#000', background: theme === 'light' ? '#fff' : '#000',
color: theme === 'light' ? 'rgb(99, 98, 98)' : '#A8A8A8', color: theme === 'light' ? 'rgb(99, 98, 98)' : '#A8A8A8',
@ -29,7 +30,7 @@ const tooltipBoxStyle = (theme) => ({
}) })
const tooltipBodyStyle = (theme) => ({ const tooltipBodyStyle = (theme) => ({
maxHeight: '3.6rem', maxHeight: '4.8rem',
position: 'relative', position: 'relative',
lineHeight: '1.2rem', lineHeight: '1.2rem',
overflow: 'hidden', overflow: 'hidden',
@ -48,7 +49,8 @@ const tooltipArrowStyle = ({ theme, x, y, side }) => ({
transform: "rotate(45deg)" transform: "rotate(45deg)"
}) })
export const Tooltip = ({ absolutePath, render, ...props }) => { // export const Tooltip = ({ absolutePath, render, ...props }) => {
export const Tooltip = ({ render, ...props }) => {
const theme = 'light'; // temporarily hard-coded; light theme tbd in next PR const theme = 'light'; // temporarily hard-coded; light theme tbd in next PR
const arrowRef = useRef(null); const arrowRef = useRef(null);
@ -104,15 +106,25 @@ export const Tooltip = ({ absolutePath, render, ...props }) => {
const fetchTooltipContent = async () => { const fetchTooltipContent = async () => {
setTooltipContentLoaded(false); setTooltipContentLoaded(false);
const response = await fetch(absolutePath); let content;
if (response.status !== 200) { // get tooltip content
console.log(`Looks like there was a problem. Status Code: ${response.status}`) try {
return // create a temporary anchor tag to convert relative href to absolute path
const tempLink = document.createElement("a");
tempLink.href = props.href;
// not all notes documents are structured so that the first paragraph will be the content summary
// TBD check if the docs can be adjusted and if previews for notes are even required
if (tempLink.pathname.includes('notes')) {
return
}
const filePath = tempLink.pathname.slice(1) // remove slash from the beginning
const page = allOtherPages.find(p => p._raw.sourceFilePath === filePath)
content = documentExtract(page.body.raw);
} catch {
content = 'An error occured...'
} }
const md = await response.text();
const extract = documentExtract(md);
setTooltipContent(extract); setTooltipContent(content);
setTooltipContentLoaded(true); setTooltipContentLoaded(true);
} }

View File

@ -33,7 +33,7 @@ body {
content: ""; content: "";
position: absolute; position: absolute;
right: 0; right: 0;
top: 2.4rem; /* multiple of $line-height used on the tooltip body */ top: 3.6rem; /* multiple of $line-height used on the tooltip body (defined in tooltipBodyStyle) */
height: 1.2rem; /* ($top + $height)/$line-height is the number of lines we want to clip tooltip text at*/ height: 1.2rem; /* ($top + $height)/$line-height is the number of lines we want to clip tooltip text at*/
width: 10rem; width: 10rem;
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 100%); background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 100%);

View File

@ -4,7 +4,7 @@ import find from 'unist-util-find'
import { toString } from 'mdast-util-to-string' import { toString } from 'mdast-util-to-string'
// get first paragraph // get first paragraph found in the document
const documentExtract = (md) => { const documentExtract = (md) => {
const mdast = unified().use(remarkParse).parse(md); const mdast = unified().use(remarkParse).parse(md);
let paragraph = find(mdast, (node) => node.type === "paragraph"); let paragraph = find(mdast, (node) => node.type === "paragraph");