From 217250f6b6fcb5c61c625f393164d2a6d1e8c05a Mon Sep 17 00:00:00 2001 From: Dan Kimberley <10367135+dankimberley@users.noreply.github.com> Date: Thu, 18 Jul 2024 12:57:11 +0100 Subject: [PATCH] Heading anchor links (#247) * created separate heading component * changed to heading props * added generate URL function * functional copy heading link button * added copied notification * remove default param for tag --- components/content/Content.tsx | 13 +++++++++- components/content/Heading.tsx | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 components/content/Heading.tsx diff --git a/components/content/Content.tsx b/components/content/Content.tsx index 22db640b..679b6753 100644 --- a/components/content/Content.tsx +++ b/components/content/Content.tsx @@ -20,10 +20,11 @@ import Solution from "./Solution" import { first } from "cypress/types/lodash" import remarkDirective from "remark-directive" import remarkDirectiveRehype from "remark-directive-rehype" -import { CodeComponent, CodeProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" +import { CodeComponent, CodeProps, HeadingProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" import Callout from "../Callout" import { Course, Section, Theme } from "lib/material" import Paragraph from "./Paragraph" +import Heading from "./Heading" function reactMarkdownRemarkDirective() { return (tree: any) => { @@ -56,6 +57,13 @@ const list = (sectionStr: string) => { return list } +const h = (sectionStr: string, tag: string) => { + function h({ node, children, ...props }: HeadingProps) { + return + } + return h +} + let solutionCount = 0 function solution({ node, children, ...props }: ReactMarkdownProps) { solutionCount++ @@ -161,6 +169,9 @@ const Content: React.FC = ({ markdown, theme, course, section }) => { code, p: p(sectionStr), li: list(sectionStr), + h2: h(sectionStr, "h2"), + h3: h(sectionStr, "h3"), + h4: h(sectionStr, "h4"), }} > {markdown} diff --git a/components/content/Heading.tsx b/components/content/Heading.tsx new file mode 100644 index 00000000..cc1e2583 --- /dev/null +++ b/components/content/Heading.tsx @@ -0,0 +1,43 @@ +import React, { useState } from "react" +import CopyToClipboard from "react-copy-to-clipboard" +import { FaLink } from "react-icons/fa" + +interface HeadingProps { + content: React.ReactNode + section: string + tag: string +} + +const Heading: React.FC = ({ content, section, tag }) => { + const Tag = tag as keyof JSX.IntrinsicElements + const headingContent = content?.toString().replaceAll(" ", "-") + const [isCopied, setIsCopied] = useState(false) + + const generateHeadingURL = () => { + const href: string = typeof window !== "undefined" ? window.location.href.split("#")[0] : "" + return href + "#" + headingContent ?? "" + } + + const onCopyHandler = () => { + setIsCopied(true) + setTimeout(() => { + setIsCopied(false) + }, 1500) + } + + return ( + <> + + {content} + + + + {isCopied && Copied to clipboard!} + + + ) +} + +export default Heading