diff --git a/components/CaseTOC.tsx b/components/CaseTOC.tsx new file mode 100644 index 00000000000..3f73134251b --- /dev/null +++ b/components/CaseTOC.tsx @@ -0,0 +1,197 @@ +import { useMemo, useState } from 'react'; +import { twMerge } from 'tailwind-merge'; + +import { useHeadingsObserver } from './helpers/useHeadingsObserver'; +import ArrowRight from './icons/ArrowRight'; + +interface TocItem { + lvl: number; + content: string; + slug: string; + children?: TocItem[]; +} + +interface TOCItemProps { + item: TocItem; + index: number; + currSelected: string; + closeMenu: () => void; +} + +interface CaseTOCProps { + className: string; + cssBreakingPoint?: 'xl' | 'lg'; + toc: any[]; +} + +/** + * @description Checks if the item is active. + * + * @param {TocItem} item - The TOC item to check. + * @param {string} currSelected - The currently selected TOC item. + * @returns {boolean} - True if the item is active, otherwise false. + */ +const checkIfActive = (item: TocItem, currSelected: string): boolean => { + return item.slug === currSelected || item.children?.some((child) => checkIfActive(child, currSelected)) || false; +}; + +/** + * @description Converts content to TOC items. + * + * @param {any[]} content - The content to convert to TOC items. + * @param {number} level - The level of the TOC item. + * @returns {TocItem[]} - The array of TOC items. + */ +const convertContentToTocItems = (content: any[], level: number = 1): TocItem[] => { + const tocItems = []; + + for (const section of content) { + const item = { + lvl: level, + content: section.title, + slug: section.title + .replace(/<|>|"|\\|\/|=/gi, '') + .replace(/\s/gi, '-') + .toLowerCase() + }; + + if (section.children && section.children.length > 0) { + const children = convertContentToTocItems(section.children, level + 1); + + (item as TocItem).children = children; + } + + tocItems.push(item); + } + + return tocItems; +}; + +/** + * @description Component representing an item in the table of contents (TOC). + * + * @param {TOCItemProps} props - The props for TOCItem. + * @param {TocItem} props.item - The TOC item. + * @param {number} props.index - The index of the TOC item. + * @param {string} props.currSelected - The currently selected TOC item. + * @param {Function} props.closeMenu - A function to close the menu. + */ +function TOCItem({ item, index, currSelected, closeMenu }: TOCItemProps) { + const [open, setOpen] = useState(false); + const handleClick = () => { + closeMenu(); + setOpen(false); + }; + const active = useMemo(() => checkIfActive(item, currSelected), [item, currSelected]); + + return ( + <> + + {item.children && item.children.length > 0 && ( +