import React, { HTMLAttributes, useState } from "react"; import snarkdown from "snarkdown"; import useBaseUrl from "@docusaurus/useBaseUrl"; // @ts-expect-error no types import { useDoc } from "@docusaurus/theme-common/internal"; import { useHistory, useLocation } from "@docusaurus/router"; import clsx from "clsx"; import { useCurrentTutorial } from "../../hooks/use-current-tutorial"; import { UnitCircle } from "../unit-circle"; import { TutorialCircle } from "../tutorial-circle"; import { useTutorialUIPackage } from "../../hooks/use-tutorial-ui-package"; import { PreferredUIPackage } from "../../context/TutorialUIPackageContext"; const uiNames: Record = { headless: "Headless", antd: "Ant Design", mui: "Material UI", mantine: "Mantine", "chakra-ui": "Chakra UI", }; const baseIconUrl = "https://refine.ams3.cdn.digitaloceanspaces.com/website/static/icons/colored/ui-framework-"; type LinkWithIdProps = HTMLAttributes & { id: string; isCurrent?: boolean; dangerouslySetInnerHTML?: { __html: string }; }; const LinkWithId = ({ id, isCurrent, className, dangerouslySetInnerHTML, ...rest }: LinkWithIdProps) => { const toUrl = useBaseUrl(`/docs/${id}`, { forcePrependBaseUrl: true }); return ( ); }; const markdownConverter = (text: string) => { const numericStartRegexp = /^\d+\.\s?/g; // use this to get the numeric start const _numericStart = text.match(numericStartRegexp)?.[0] || ""; const numericStartIgnore = text.replace(numericStartRegexp, ""); const marked = snarkdown(numericStartIgnore); return `${marked}`; }; const TutorialUIStatus = () => { const { preferred: preferredUIPackage } = useTutorialUIPackage(); return (
Current Framework
{uiNames[preferredUIPackage]}
Change
); }; type TocLinkProps = { item: any; activeId?: string; setActiveId?: React.Dispatch>; }; const TocLink: React.FC = ({ item, activeId, setActiveId }) => { const location = useLocation(); const history = useHistory(); const { hash: locationHash } = location; React.useEffect(() => { const targetElement = document.getElementById(item.id); if (targetElement) { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const hash = `#${item.id}`; if (hash !== locationHash) { setActiveId(item.id); window.history.replaceState({}, "", hash); } } }); }, { rootMargin: "0px 0px -80% 0px", }, ); observer.observe(targetElement); return () => { observer.unobserve(targetElement); }; } }, [item.id]); return (
); }; export const TutorialTOC = () => { const { toc, metadata: { id: currentDocId }, } = useDoc(); const currentTutorial = useCurrentTutorial(); const { hash } = useLocation(); const baseActiveId = `${hash}`.replace("#", ""); const [selectedUnit, setSelectedUnit] = useState(currentTutorial.unit); const [activeId, setActiveId] = React.useState( baseActiveId, ); React.useEffect(() => { setActiveId(baseActiveId); }, [baseActiveId]); const renderTocItem = (item: (typeof toc)[number]) => { return (
  • ); }; const renderTOC = () => { if (toc.length === 0) return null; return (
      {toc.map(renderTocItem)}
    ); }; const renderUnitItem = ( doc: NonNullable< typeof currentTutorial >["units"][number]["docs"][number], ) => { const formattedTitle = markdownConverter(doc.title); const unitNo = doc.title.split(".")[0]; return (
  • {doc.current && renderTOC()}
  • ); }; const renderUnitDocs = ( unit?: NonNullable["units"][number], ) => { return (
      {unit?.docs .sort((a, b) => `${a.title}`?.localeCompare(`${b.title}`), ) .map(renderUnitItem)}
    ); }; const renderUnitTab = (unit: (typeof currentTutorial)["units"][number]) => { return ( ); }; const currentUnit: | NonNullable["units"][number] | undefined = currentTutorial?.units.find( (unit) => unit.unit === selectedUnit, ); const isFirstUnit = currentTutorial?.units?.find((el) => el?.unit === currentTutorial?.unit) ?.no === 1; return (
    {currentTutorial?.units.map(renderUnitTab)}
    {/*
    {currentUnit?.title ?? currentUnit?.unit ?? "-"}
    */}
    {renderUnitDocs(currentUnit)}
    {!isFirstUnit && currentDocId !== "tutorial/introduction/select-framework" && ( )}
    ); }; export const useDocTOCwithTutorial = () => { const tutorial = useCurrentTutorial(); const { frontMatter, toc } = useDoc(); const hidden = frontMatter.hide_table_of_contents; const canRender = (!hidden && toc.length > 0) || tutorial?.isTutorial; const tutorialTOC = canRender ? : undefined; return { hidden, tutorialTOC, }; };