[site/components][f]: tooltip animation
This commit is contained in:
parent
5589b2244d
commit
1a13aed153
|
|
@ -1,115 +1,36 @@
|
|||
import ReactDOM from 'react-dom'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState, useEffect, useRef, Fragment } from 'react'
|
||||
import {
|
||||
arrow,
|
||||
autoPlacement,
|
||||
autoUpdate,
|
||||
FloatingPortal,
|
||||
offset,
|
||||
shift,
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useHover,
|
||||
useInteractions,
|
||||
useRole,
|
||||
} from '@floating-ui/react-dom-interactions'
|
||||
|
||||
import { Tooltip } from './Tooltip';
|
||||
import siteConfig from '../config/siteConfig.js'
|
||||
import documentExtract from '../utils/documentExtract'
|
||||
import { Tooltip } from './Tooltip'
|
||||
|
||||
|
||||
// TODO cancel request on mouseleave when it hasn't been fulfilled yet
|
||||
|
||||
export const Anchor = (props) => {
|
||||
const { href } = props;
|
||||
const router = useRouter();
|
||||
const arrowRef = useRef(null);
|
||||
|
||||
const [ showTooltip, setShowTooltip ] = useState(false);
|
||||
const [ preview, setPreview ] = useState("");
|
||||
const [ previewLoaded, setPreviewLoaded ] = useState(false);
|
||||
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
reference,
|
||||
floating,
|
||||
placement,
|
||||
strategy,
|
||||
context,
|
||||
middlewareData: { arrow: { x: arrowX, y: arrowY } = {}}
|
||||
} = useFloating({
|
||||
open: showTooltip,
|
||||
onOpenChange: setShowTooltip,
|
||||
whileElementsMounted: autoUpdate,
|
||||
middleware: [
|
||||
offset(5),
|
||||
autoPlacement({ padding: 5 }),
|
||||
shift({ padding: 5 }),
|
||||
arrow({ element: arrowRef, padding: 4 })
|
||||
]
|
||||
});
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([
|
||||
useHover(context, { delay: 100 }),
|
||||
useRole(context, { role: 'tooltip' }),
|
||||
useDismiss(context, { ancestorScroll: true })
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (showTooltip) {
|
||||
fetchPreview();
|
||||
const absoluteContentPath = (href) => {
|
||||
// return content path only if it points to a local file (href path is relative)
|
||||
if (
|
||||
href &&
|
||||
href.indexOf("http:") !== 0 &&
|
||||
href.indexOf("https:") !== 0
|
||||
) {
|
||||
const currentPageContentPath = [siteConfig.rawContentBaseUrl, router.asPath].join("");
|
||||
const hrefContentPath = new URL(href, currentPageContentPath).href;
|
||||
// excluding notes and claims
|
||||
if (!hrefContentPath.includes("notes") && !hrefContentPath.includes("claims")) {
|
||||
return hrefContentPath;
|
||||
}
|
||||
}
|
||||
}, [showTooltip])
|
||||
|
||||
const fetchPreview = async () => {
|
||||
setPreviewLoaded(false);
|
||||
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 md = await response.text();
|
||||
const extract = documentExtract(md);
|
||||
|
||||
setPreview(extract);
|
||||
setPreviewLoaded(true);
|
||||
}
|
||||
|
||||
if (
|
||||
href &&
|
||||
href.indexOf("http:") !== 0 &&
|
||||
href.indexOf("https:") !== 0 &&
|
||||
href.includes(".md")
|
||||
) {
|
||||
return <Fragment>
|
||||
<a {...props} {...getReferenceProps({ref: reference})} />
|
||||
<FloatingPortal>
|
||||
{ showTooltip && previewLoaded &&
|
||||
<Tooltip
|
||||
{...getFloatingProps({
|
||||
ref: floating,
|
||||
theme: 'light',
|
||||
arrowRef,
|
||||
arrowX,
|
||||
arrowY,
|
||||
placement,
|
||||
style: {
|
||||
position: strategy,
|
||||
left: x ?? '',
|
||||
top: y ?? '',
|
||||
},
|
||||
})}
|
||||
>
|
||||
{ preview }
|
||||
</Tooltip>
|
||||
}
|
||||
</FloatingPortal>
|
||||
</Fragment>;
|
||||
if (absoluteContentPath(props.href)) {
|
||||
return (
|
||||
<Tooltip {...props} absolutePath={absoluteContentPath(props.href)} render={ tooltipTriggerProps => (
|
||||
<a {...tooltipTriggerProps} />
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return <a {...props} />;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
import React from 'react';
|
||||
import { useState, useEffect, useRef, Fragment } from 'react'
|
||||
import {
|
||||
arrow,
|
||||
autoPlacement,
|
||||
FloatingPortal,
|
||||
inline,
|
||||
offset,
|
||||
shift,
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useHover,
|
||||
useFocus,
|
||||
useInteractions,
|
||||
useRole,
|
||||
} from '@floating-ui/react-dom-interactions'
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
import documentExtract from '../utils/documentExtract'
|
||||
|
||||
|
||||
const tooltipBoxStyle = (theme) => ({
|
||||
|
|
@ -11,7 +28,7 @@ const tooltipBoxStyle = (theme) => ({
|
|||
boxShadow: 'rgba(0, 0, 0, 0.55) 0px 0px 16px -3px',
|
||||
})
|
||||
|
||||
const tooltipBodyStyle = () => ({
|
||||
const tooltipBodyStyle = (theme) => ({
|
||||
maxHeight: '3.6rem',
|
||||
position: 'relative',
|
||||
lineHeight: '1.2rem',
|
||||
|
|
@ -31,8 +48,51 @@ const tooltipArrowStyle = ({ theme, x, y, side }) => ({
|
|||
transform: "rotate(45deg)"
|
||||
})
|
||||
|
||||
export const Tooltip = React.forwardRef((props, ref) => {
|
||||
const { theme, children, arrowRef, arrowX, arrowY, placement, ...tooltipProps } = props;
|
||||
export const Tooltip = (props) => {
|
||||
const theme = 'light'; // temporarily hard-coded; light theme tbd in next PR
|
||||
|
||||
const arrowRef = useRef(null);
|
||||
const [ showTooltip, setShowTooltip ] = useState(false);
|
||||
const [ tooltipContent, setTooltipContent ] = useState("");
|
||||
const [ tooltipContentLoaded, setTooltipContentLoaded ] = useState(false);
|
||||
// floating-ui dom hook
|
||||
const {
|
||||
x,
|
||||
y,
|
||||
reference, // trigger element back ref
|
||||
floating, // tooltip back ref
|
||||
placement, // default: 'bottom'
|
||||
strategy, // default: 'absolute'
|
||||
context,
|
||||
middlewareData: { arrow: { x: arrowX, y: arrowY } = {}} // data for arrow positioning
|
||||
} = useFloating({
|
||||
open: showTooltip, // state value binding
|
||||
onOpenChange: setShowTooltip, // state value setter
|
||||
middleware: [
|
||||
offset(5), // offset from container border
|
||||
autoPlacement({ padding: 5 }), // auto place vertically
|
||||
shift({ padding: 5 }), // flip horizontally if necessary
|
||||
arrow({ element: arrowRef, padding: 4 }), // add arrow element
|
||||
inline(), // correct position for multiline anchor tags
|
||||
]
|
||||
});
|
||||
// floating-ui interactions hook
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([
|
||||
useHover(context, { delay: 100 }),
|
||||
useFocus(context),
|
||||
useRole(context, { role: 'tooltip' }),
|
||||
useDismiss(context, { ancestorScroll: true }),
|
||||
]);
|
||||
|
||||
const tooltipTriggerProps = getReferenceProps({ ...props, ref: reference});
|
||||
const tooltipProps = getFloatingProps({
|
||||
ref: floating,
|
||||
style: {
|
||||
position: strategy,
|
||||
left: x ?? '',
|
||||
top: y ?? '',
|
||||
},
|
||||
});
|
||||
|
||||
const arrowPlacement = {
|
||||
top: 'bottom',
|
||||
|
|
@ -41,19 +101,56 @@ export const Tooltip = React.forwardRef((props, ref) => {
|
|||
left: 'right',
|
||||
}[placement.split('-')[0]];
|
||||
|
||||
const fetchTooltipContent = async () => {
|
||||
setTooltipContentLoaded(false);
|
||||
|
||||
const response = await fetch(props.absolutePath);
|
||||
if (response.status !== 200) {
|
||||
console.log(`Looks like there was a problem. Status Code: ${response.status}`)
|
||||
return
|
||||
}
|
||||
const md = await response.text();
|
||||
const extract = documentExtract(md);
|
||||
|
||||
setTooltipContent(extract);
|
||||
setTooltipContentLoaded(true);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (showTooltip) {
|
||||
fetchTooltipContent();
|
||||
}
|
||||
}, [showTooltip])
|
||||
|
||||
return (
|
||||
<div className="tooltip" {...tooltipProps} ref={ref}>
|
||||
<div className="tooltip-box" style={ tooltipBoxStyle(theme) }>
|
||||
<div className="tooltip-body" style={ tooltipBodyStyle() }>
|
||||
{ children }
|
||||
</div>
|
||||
</div>
|
||||
<div className="tooltip-arrow" ref={arrowRef} style={ tooltipArrowStyle({
|
||||
theme,
|
||||
x: arrowX,
|
||||
y: arrowY,
|
||||
side: arrowPlacement
|
||||
}) }></div>
|
||||
</div>
|
||||
<Fragment>
|
||||
{ props.render(tooltipTriggerProps) }
|
||||
<FloatingPortal>
|
||||
<AnimatePresence>
|
||||
{ showTooltip && tooltipContentLoaded &&
|
||||
<motion.div
|
||||
{...tooltipProps}
|
||||
initial={{ opacity: 0, scale: 0.85 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ type: "spring", damping: 20, stiffness: 300 }}
|
||||
>
|
||||
<div className="tooltip-box" style={ tooltipBoxStyle(theme) }>
|
||||
<div className="tooltip-body" style={ tooltipBodyStyle(theme) }>
|
||||
{ tooltipContent }
|
||||
</div>
|
||||
</div>
|
||||
<div ref={arrowRef} className="tooltip-arrow" style={ tooltipArrowStyle({
|
||||
theme,
|
||||
x: arrowX,
|
||||
y: arrowY,
|
||||
side: arrowPlacement
|
||||
})}>
|
||||
</div>
|
||||
</motion.div>
|
||||
}
|
||||
</AnimatePresence>
|
||||
</FloatingPortal>
|
||||
</Fragment>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"@silvenon/remark-smartypants": "^1.0.0",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"contentlayer": "^0.1.2",
|
||||
"framer-motion": "^6.3.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-to-string": "^2.0.0",
|
||||
"next": "^12.1.0",
|
||||
|
|
@ -308,6 +309,21 @@
|
|||
"resolved": "https://registry.npmjs.org/@effect-ts/system/-/system-0.55.1.tgz",
|
||||
"integrity": "sha512-OEnwd9JhrV2Q5S7cke/ZgR56Hn75DSr1aIkA0PBE1edoX6GKB6nOdu8u/vPhvqjxLHfMgN8o+EVaWUHPLIC1UQ=="
|
||||
},
|
||||
"node_modules/@emotion/is-prop-valid": {
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
|
||||
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "0.7.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/memoize": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
|
||||
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@esbuild-plugins/node-resolve": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-plugins/node-resolve/-/node-resolve-0.1.4.tgz",
|
||||
|
|
@ -2431,6 +2447,33 @@
|
|||
"url": "https://www.patreon.com/infusion"
|
||||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.3.3.tgz",
|
||||
"integrity": "sha512-wo0dCnoq5vn4L8YVOPO9W54dliH78vDaX0Lj+bSPUys6Nt5QaehrS3uaYa0q5eVeikUgtTjz070UhQ94thI5Sw==",
|
||||
"dependencies": {
|
||||
"framesync": "6.0.1",
|
||||
"hey-listen": "^1.0.8",
|
||||
"popmotion": "11.0.3",
|
||||
"style-value-types": "5.0.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@emotion/is-prop-valid": "^0.8.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": ">=16.8 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/framesync": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
|
||||
"integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
|
@ -2701,6 +2744,11 @@
|
|||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hey-listen": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
|
||||
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
|
||||
},
|
||||
"node_modules/html-void-elements": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
|
||||
|
|
@ -4630,6 +4678,17 @@
|
|||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/popmotion": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz",
|
||||
"integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==",
|
||||
"dependencies": {
|
||||
"framesync": "6.0.1",
|
||||
"hey-listen": "^1.0.8",
|
||||
"style-value-types": "5.0.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.12",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
|
||||
|
|
@ -5571,6 +5630,15 @@
|
|||
"inline-style-parser": "0.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/style-value-types": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz",
|
||||
"integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==",
|
||||
"dependencies": {
|
||||
"hey-listen": "^1.0.8",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/styled-jsx": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz",
|
||||
|
|
@ -6334,6 +6402,21 @@
|
|||
"resolved": "https://registry.npmjs.org/@effect-ts/system/-/system-0.55.1.tgz",
|
||||
"integrity": "sha512-OEnwd9JhrV2Q5S7cke/ZgR56Hn75DSr1aIkA0PBE1edoX6GKB6nOdu8u/vPhvqjxLHfMgN8o+EVaWUHPLIC1UQ=="
|
||||
},
|
||||
"@emotion/is-prop-valid": {
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
|
||||
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@emotion/memoize": "0.7.4"
|
||||
}
|
||||
},
|
||||
"@emotion/memoize": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
|
||||
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild-plugins/node-resolve": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-plugins/node-resolve/-/node-resolve-0.1.4.tgz",
|
||||
|
|
@ -7722,6 +7805,27 @@
|
|||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA=="
|
||||
},
|
||||
"framer-motion": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.3.3.tgz",
|
||||
"integrity": "sha512-wo0dCnoq5vn4L8YVOPO9W54dliH78vDaX0Lj+bSPUys6Nt5QaehrS3uaYa0q5eVeikUgtTjz070UhQ94thI5Sw==",
|
||||
"requires": {
|
||||
"@emotion/is-prop-valid": "^0.8.2",
|
||||
"framesync": "6.0.1",
|
||||
"hey-listen": "^1.0.8",
|
||||
"popmotion": "11.0.3",
|
||||
"style-value-types": "5.0.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"framesync": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz",
|
||||
"integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==",
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
|
@ -7914,6 +8018,11 @@
|
|||
"space-separated-tokens": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"hey-listen": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
|
||||
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
|
||||
},
|
||||
"html-void-elements": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
|
||||
|
|
@ -9196,6 +9305,17 @@
|
|||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
},
|
||||
"popmotion": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz",
|
||||
"integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==",
|
||||
"requires": {
|
||||
"framesync": "6.0.1",
|
||||
"hey-listen": "^1.0.8",
|
||||
"style-value-types": "5.0.0",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.12",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
|
||||
|
|
@ -9840,6 +9960,15 @@
|
|||
"inline-style-parser": "0.1.1"
|
||||
}
|
||||
},
|
||||
"style-value-types": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz",
|
||||
"integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==",
|
||||
"requires": {
|
||||
"hey-listen": "^1.0.8",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"styled-jsx": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"@silvenon/remark-smartypants": "^1.0.0",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"contentlayer": "^0.1.2",
|
||||
"framer-motion": "^6.3.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast-util-to-string": "^2.0.0",
|
||||
"next": "^12.1.0",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ body {
|
|||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 10%;
|
||||
width: 30%;
|
||||
height: 1.2em;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 100%);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue