[site/components][f]: tooltip with clipped content
This commit is contained in:
parent
28c087e31d
commit
5589b2244d
|
|
@ -15,7 +15,7 @@ import {
|
|||
useRole,
|
||||
} from '@floating-ui/react-dom-interactions'
|
||||
|
||||
import getAbsolutePath from '../utils/absolutePath'
|
||||
import siteConfig from '../config/siteConfig.js'
|
||||
import documentExtract from '../utils/documentExtract'
|
||||
import { Tooltip } from './Tooltip'
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ export const Anchor = (props) => {
|
|||
]
|
||||
});
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([
|
||||
useHover(context, { delay: { open: 100, close: 0 } }),
|
||||
useHover(context, { delay: 100 }),
|
||||
useRole(context, { role: 'tooltip' }),
|
||||
useDismiss(context, { ancestorScroll: true })
|
||||
]);
|
||||
|
|
@ -64,21 +64,17 @@ export const Anchor = (props) => {
|
|||
}, [showTooltip])
|
||||
|
||||
const fetchPreview = async () => {
|
||||
console.log("Fetching...")
|
||||
setPreviewLoaded(false);
|
||||
const basePath = "http://localhost:3000"; // TODO
|
||||
const currentPath = router.asPath;
|
||||
const relativePath = props.href.split(".")[0]; // TBD temp remove .md
|
||||
const absolutePath = getAbsolutePath({ currentPath, basePath, relativePath });
|
||||
|
||||
const response = await fetch(absolutePath);
|
||||
const path = new URL(props.href, document.baseURI).pathname;
|
||||
const rawContentPath = [siteConfig.rawContentBaseUrl, path].join("")
|
||||
const response = await fetch(rawContentPath);
|
||||
if (response.status !== 200) {
|
||||
// TODO
|
||||
console.log(`Looks like there was a problem. Status Code: ${response.status}`)
|
||||
return
|
||||
}
|
||||
const html = await response.text();
|
||||
const extract = documentExtract(html);
|
||||
const md = await response.text();
|
||||
const extract = documentExtract(md);
|
||||
|
||||
setPreview(extract);
|
||||
setPreviewLoaded(true);
|
||||
|
|
@ -93,24 +89,25 @@ export const Anchor = (props) => {
|
|||
return <Fragment>
|
||||
<a {...props} {...getReferenceProps({ref: reference})} />
|
||||
<FloatingPortal>
|
||||
<Tooltip
|
||||
{...getFloatingProps({
|
||||
ref: floating,
|
||||
theme: 'light',
|
||||
arrowRef,
|
||||
arrowX,
|
||||
arrowY,
|
||||
placement,
|
||||
style: {
|
||||
position: strategy,
|
||||
visibility: showTooltip && previewLoaded ? 'visible' : 'hidden',
|
||||
left: x ?? '',
|
||||
top: y ?? '',
|
||||
},
|
||||
})}
|
||||
>
|
||||
{ preview }
|
||||
</Tooltip>
|
||||
{ showTooltip && previewLoaded &&
|
||||
<Tooltip
|
||||
{...getFloatingProps({
|
||||
ref: floating,
|
||||
theme: 'light',
|
||||
arrowRef,
|
||||
arrowX,
|
||||
arrowY,
|
||||
placement,
|
||||
style: {
|
||||
position: strategy,
|
||||
left: x ?? '',
|
||||
top: y ?? '',
|
||||
},
|
||||
})}
|
||||
>
|
||||
{ preview }
|
||||
</Tooltip>
|
||||
}
|
||||
</FloatingPortal>
|
||||
</Fragment>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,24 @@
|
|||
import React from 'react';
|
||||
|
||||
|
||||
const tooltipStyles = (theme) => ({
|
||||
const tooltipBoxStyle = (theme) => ({
|
||||
height: 'auto',
|
||||
maxWidth: '80vw',
|
||||
padding: '1rem 2rem',
|
||||
maxWidth: '60vw',
|
||||
padding: '1rem',
|
||||
background: theme === 'light' ? '#fff' : '#000',
|
||||
color: theme === 'light' ? 'rgb(99, 98, 98)' : '#A8A8A8',
|
||||
borderRadius: '4px',
|
||||
boxShadow: 'rgba(0, 0, 0, 0.55) 0px 0px 16px -3px',
|
||||
fontSize: '0.9em'
|
||||
})
|
||||
|
||||
const tooltipArrowStyles = ({ theme, x, y, side }) => ({
|
||||
const tooltipBodyStyle = () => ({
|
||||
maxHeight: '3.6rem',
|
||||
position: 'relative',
|
||||
lineHeight: '1.2rem',
|
||||
overflow: 'hidden',
|
||||
})
|
||||
|
||||
const tooltipArrowStyle = ({ theme, x, y, side }) => ({
|
||||
position: "absolute",
|
||||
left: x != null ? `${x}px` : '',
|
||||
top: y != null ? `${y}px` : '',
|
||||
|
|
@ -36,11 +42,13 @@ export const Tooltip = React.forwardRef((props, ref) => {
|
|||
}[placement.split('-')[0]];
|
||||
|
||||
return (
|
||||
<div {...tooltipProps} ref={ref}>
|
||||
<div style={ tooltipStyles(theme) }>
|
||||
{ children }
|
||||
<div className="tooltip" {...tooltipProps} ref={ref}>
|
||||
<div className="tooltip-box" style={ tooltipBoxStyle(theme) }>
|
||||
<div className="tooltip-body" style={ tooltipBodyStyle() }>
|
||||
{ children }
|
||||
</div>
|
||||
</div>
|
||||
<div ref={arrowRef} style={ tooltipArrowStyles({
|
||||
<div className="tooltip-arrow" ref={arrowRef} style={ tooltipArrowStyle({
|
||||
theme,
|
||||
x: arrowX,
|
||||
y: arrowY,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const siteConfig = {
|
|||
url: "https://web3.lifeitself.us",
|
||||
repoRoot: "https://github.com/life-itself/web3",
|
||||
repoEditPath: "/edit/main/",
|
||||
rawContentBaseUrl: "https://raw.githubusercontent.com/life-itself/web3/main",
|
||||
tagline: "",
|
||||
description:
|
||||
"Introductions to key concepts and ideas in crypto and web3. Plus in-depth evaluation of its potential impact.",
|
||||
|
|
|
|||
|
|
@ -27,3 +27,15 @@ body {
|
|||
.extra-small {
|
||||
font-size: 0.50rem;
|
||||
}
|
||||
|
||||
/* tooltip fade-out clip */
|
||||
.tooltip-body::after {
|
||||
content: "";
|
||||
text-align: right;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 10%;
|
||||
height: 1.2em;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
const absolutePath = ({ currentPath, basePath, relativePath }) => {
|
||||
const absolutePath = currentPath.slice(1).split("/")
|
||||
absolutePath.pop(); // remove current page name
|
||||
absolutePath.unshift(basePath);
|
||||
absolutePath.push(relativePath);
|
||||
return absolutePath.join("/");
|
||||
};
|
||||
|
||||
export default absolutePath;
|
||||
|
|
@ -1,15 +1,13 @@
|
|||
import { unified } from 'unified'
|
||||
import rehypeParse from 'rehype-parse'
|
||||
import remarkParse from 'remark-parse'
|
||||
import find from 'unist-util-find'
|
||||
import { toString } from 'hast-util-to-string'
|
||||
import { toString } from 'mdast-util-to-string'
|
||||
|
||||
|
||||
// get first paragraph inside article's main tag
|
||||
const documentExtract = (htmlString) => {
|
||||
const hast = unified().use(rehypeParse).parse(htmlString);
|
||||
const article = find(hast, (node) => node.tagName === "article");
|
||||
const main = find(article, (node) => node.tagName === "main");
|
||||
const paragraph = find(main, (node) => node.tagName === "p");
|
||||
// get first paragraph
|
||||
const documentExtract = (md) => {
|
||||
const mdast = unified().use(remarkParse).parse(md);
|
||||
let paragraph = find(mdast, (node) => node.type === "paragraph");
|
||||
return toString(paragraph);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue