import { LinkIcon } from "@chakra-ui/icons"; import { Flex, Heading, As } from "@chakra-ui/react"; import { Children, FunctionComponent, ReactNode } from "react"; import ReactDOMServer from "react-dom/server"; import { useLocation } from "react-router-dom"; import { sanitize } from "../../util/sanitize-anchor"; import { NavLink } from "../NavLink"; interface HeadingResolverProps { level: number; children: ReactNode; } /** * Extracts the string leaves from the provided ReactNode. * * @param node the node from which string data should be fetched. * * @returns the visible string content from the node. */ const stringContent = (node: ReactNode): string => { return Children.toArray(node) .reduce((acc: string, child) => { if (typeof child === "string") { return acc + child; } if (typeof child === "object" && "props" in child) { return acc + stringContent(child.props.children); } return acc; }, "") .trim(); }; const HeadingLink: FunctionComponent<{ id: string; level: number; title: string; }> = ({ id, level, title }) => { const { search } = useLocation(); return ( ); }; export const Headings: FunctionComponent = ({ level, children, }) => { const size: string = ["2xl", "xl", "lg", "md", "sm", "xs"][level - 1]; const elem = `h${level}` as As; // Use DOMParser to look for data attribute for link ID const parser = new DOMParser(); const doc = parser.parseFromString( ReactDOMServer.renderToStaticMarkup(children as React.ReactElement), "text/html" ); const dataElement = doc.querySelector( "span[data-heading-title][data-heading-id]" ) as HTMLElement; const title = dataElement?.dataset.headingTitle ?? stringContent(children); const id = dataElement?.dataset.headingId ?? sanitize(title); return ( a": { visibility: "initial", }, }} align="stretch" borderBottom="base" justify="space-between" mb={4} mt={level >= 4 ? "1.5em" : 4} px={level >= 4 ? 2 : undefined} py={2} > code": { fontSize: "inherit" } }} > {children} ); };