dark mode and light mode support
This commit is contained in:
@@ -4,7 +4,7 @@ export const Logo = () => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg166"
|
||||
version="1.1"
|
||||
className="fill-action group-hover:fill-secondary transition-all ease-in duration-100 flex-no-shrink xl:w-12 xl:h-12 w-8 h-8"
|
||||
className="fill-action group-hover:fill-primary dark:group-hover:fill-secondar transition-all ease-in duration-100 flex-no-shrink xl:w-12 xl:h-12 w-8 h-8"
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<g id="167217677994600400">
|
||||
|
||||
@@ -13,14 +13,14 @@ export const Navbar = () => {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
|
||||
return (
|
||||
<nav className="py-4 xl:px-10 px-4 flex flex-row justify-between sticky top-0 bg-gradient-dark z-50 border-b border-gradient-light">
|
||||
<nav className="py-4 xl:px-10 px-4 flex flex-row justify-between sticky top-0 bg-slate-100 dark:bg-gradient-dark z-50 border-b dark:border-gradient-light border-gray-200">
|
||||
<Link
|
||||
href="/"
|
||||
id="logo"
|
||||
className="flex flex-row gap-2 items-center group"
|
||||
>
|
||||
<Logo />
|
||||
<div className="font-bold xl:text-4xl text-xl font-mono transition-all ease-in duration-100 text-action group-hover:text-secondary">
|
||||
<div className="font-bold xl:text-4xl text-xl font-mono transition-all ease-in duration-100 text-action group-hover:text-primary dark:group-hover:text-secondary">
|
||||
peroxy
|
||||
<span className="xl:text-sm text-xs">.dev</span>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@ export const Navbar = () => {
|
||||
exit={{ opacity: 0 }}
|
||||
/>
|
||||
<motion.div
|
||||
className={`z-40 absolute w-1/2 bg-blue-900
|
||||
className={`z-40 absolute w-1/2 bg-blue-900 text-primary-text
|
||||
right-0 top-0 px-10 py-6 h-full`}
|
||||
initial={{ x: "100%" }}
|
||||
animate={{ x: 0 }}
|
||||
|
||||
@@ -22,17 +22,19 @@ export const PostHeader = ({
|
||||
return (
|
||||
<div>
|
||||
<div className="lg:text-5xl text-3xl font-bold mt-2">{title}</div>
|
||||
<div className="mt-2 text-gray-400">{description}</div>
|
||||
<div className="mt-2 mb-10 flex lg:flex-row flex-col gap-2 xl:items-center">
|
||||
<div className="mt-2 text-gray-600dark:text-gray-400">{description}</div>
|
||||
<div className="mt-2 mb-10 flex lg:flex-row flex-col gap-2 items-center">
|
||||
{author && (
|
||||
<div className="font-medium ">
|
||||
By{" "}
|
||||
{authorLink && (
|
||||
<Link href={authorLink} className="text-action">
|
||||
<Link href={authorLink} className="dark:text-action text-primary">
|
||||
@{author}
|
||||
</Link>
|
||||
)}
|
||||
{!authorLink && <span className="text-action">@{author}</span>}
|
||||
{!authorLink && (
|
||||
<span className="dark:text-action text-primary">@{author}</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="text-sm font-medium text-gray-500 lg:before:content-['•'] lg:after:content-['•'] lg:before:pr-2 lg:after:pl-2">
|
||||
|
||||
110
components/StyledMarkdown.tsx
Normal file
110
components/StyledMarkdown.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import rangeParser from "parse-numeric-range";
|
||||
import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||
import tsx from "react-syntax-highlighter/dist/cjs/languages/prism/tsx";
|
||||
import typescript from "react-syntax-highlighter/dist/cjs/languages/prism/typescript";
|
||||
import scss from "react-syntax-highlighter/dist/cjs/languages/prism/scss";
|
||||
import bash from "react-syntax-highlighter/dist/cjs/languages/prism/bash";
|
||||
import markdown from "react-syntax-highlighter/dist/cjs/languages/prism/markdown";
|
||||
import json from "react-syntax-highlighter/dist/cjs/languages/prism/json";
|
||||
import { coldarkDark as defaulttheme } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
||||
import { BiCopy } from "react-icons/bi";
|
||||
import { Components } from "react-markdown";
|
||||
import { generateSlug } from "../utils/general";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
SyntaxHighlighter.registerLanguage("tsx", tsx);
|
||||
SyntaxHighlighter.registerLanguage("typescript", typescript);
|
||||
SyntaxHighlighter.registerLanguage("scss", scss);
|
||||
SyntaxHighlighter.registerLanguage("bash", bash);
|
||||
SyntaxHighlighter.registerLanguage("markdown", markdown);
|
||||
SyntaxHighlighter.registerLanguage("json", json);
|
||||
|
||||
export const StyledMarkdown = ({ html }: { html: string }) => {
|
||||
const MarkdownComponents: Components = {
|
||||
h3: (props: any) => {
|
||||
const arr = props.children;
|
||||
let heading = "";
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i]?.type !== undefined) {
|
||||
for (let j = 0; j < arr[i].props.children.length; j++) {
|
||||
heading += arr[i]?.props?.children[0];
|
||||
}
|
||||
} else heading += arr[i];
|
||||
}
|
||||
|
||||
const slug = generateSlug(heading);
|
||||
return (
|
||||
<h3 id={slug}>
|
||||
<a href={`#${slug}`} {...props}></a>
|
||||
</h3>
|
||||
);
|
||||
},
|
||||
code({ node, inline, className, ...props }: any) {
|
||||
const match = /language-(\w+)/.exec(className || "");
|
||||
const hasMeta = node?.data?.meta;
|
||||
|
||||
const applyHighlights: object = (applyHighlights: number) => {
|
||||
if (hasMeta) {
|
||||
const RE = /{([\d,-]+)}/;
|
||||
const metadata = node.data.meta?.replace(/\s/g, "");
|
||||
const strlineNumbers = RE?.test(metadata)
|
||||
? // @ts-ignore
|
||||
RE?.exec(metadata)[1]
|
||||
: "0";
|
||||
const highlightLines = rangeParser(strlineNumbers);
|
||||
const highlight = highlightLines;
|
||||
const data = highlight.includes(applyHighlights) ? "highlight" : null;
|
||||
return { data };
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
return match ? (
|
||||
<div>
|
||||
<div className="w-full">
|
||||
<button
|
||||
className="w-fit ml-2 important"
|
||||
onClick={() => navigator.clipboard.writeText(props.children)}
|
||||
>
|
||||
<BiCopy />
|
||||
</button>
|
||||
</div>
|
||||
<SyntaxHighlighter
|
||||
style={defaulttheme}
|
||||
language={match[1]}
|
||||
PreTag="div"
|
||||
className="codeStyle"
|
||||
showLineNumbers={true}
|
||||
wrapLines={hasMeta ? true : false}
|
||||
useInlineStyles={true}
|
||||
lineProps={applyHighlights}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<code className={className} {...props} />
|
||||
);
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className="
|
||||
prose
|
||||
prose-code:font-mono prose-code:text-gray-100 prose-code:bg-gray-700 prose-code:p-1 prose-code:m-1 prose-code:rounded-md
|
||||
prose-headings:text-gray-800 dark:prose-headings:text-primary-text prose-p:text-gray-600 dark:prose-p:text-gray-100
|
||||
prose-img:w-full prose-img:h-auto xl:prose-img:max-h-96 prose-img:object-cover
|
||||
prose-li text-gray-600 dark:prose-li:text-gray-300 prose-td:text-gray-600 dark:prose-td:text-gray-400
|
||||
prose-a:text-primary dark:prose-a:text-action prose-strong:text-gray-900 dark:prose-strong:text-gray-50
|
||||
dark:prose-hr:bg-gray-200 prose-hr:bg-gray-400
|
||||
"
|
||||
>
|
||||
<ReactMarkdown
|
||||
components={MarkdownComponents}
|
||||
remarkPlugins={[remarkGfm]}
|
||||
children={html}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user