import { useInView } from 'react-intersection-observer' import { FC, PropsWithChildren } from 'react' import { highlightSelectedNavItem } from 'ui/src/components/CustomHTMLElements/CustomHTMLElements.utils' import { useRouter } from 'next/compat/router' import { useNavigationMenuContext } from '~/components/Navigation/NavigationMenu/NavigationMenu.Context' import { menuState } from '~/hooks/useMenuState' import Image from 'next/legacy/image' import { cn } from 'ui' import { safeHistoryReplaceState } from '~/lib/historyUtils' interface ISectionContainer { id: string title?: string monoFont?: boolean slug: string scrollSpyHeader?: boolean singleColumn?: boolean icon?: string } type RefSubLayoutSubComponents = { Section: FC> EducationSection: FC> EducationRow: FC> Details: FC Examples: FC } type StickyHeader = { id: string slug?: string title?: string monoFont?: boolean scrollSpyHeader?: boolean // whether or not the header updates the url on scroll icon?: string } type RefSubLayoutType = {} interface IEducationRow { className?: string } interface IEducationSection { id: string title?: string monoFont?: boolean slug: string scrollSpyHeader?: boolean hideTitle?: boolean icon?: string } interface ISectionDetails {} interface ISectionExamples {} const RefSubLayout: FC> & RefSubLayoutSubComponents = ( props ) => { return (
{props.children}
) } const Section: FC> = (props) => { return (
{props.children}
) } const StickyHeader: FC = ({ icon, ...props }) => { const router = useRouter() const { setActiveRefItem } = useNavigationMenuContext() // we're serving search bots a different file (/crawlers/[...slug]) // and need to modify content to suit that const isCrawlerPage = router?.route.includes('/crawlers/[...slug]') || false const { ref } = useInView({ threshold: 1, rootMargin: '30% 0% -35% 0px', onChange: (inView, entry) => { if (inView && window) highlightSelectedNavItem(entry.target.attributes['data-ref-id'].value) if (inView && props.scrollSpyHeader) { safeHistoryReplaceState(entry.target.id) // if (setActiveRefItem) setActiveRefItem(entry.target.attributes['data-ref-id'].value) menuState.setMenuActiveRefId(entry.target.attributes['data-ref-id'].value) // router.push(`/reference/javascript/${entry.target.attributes['data-ref-id'].value}`, null, { // shallow: true, // }) } }, }) return (
{icon && (
{icon}
)} {isCrawlerPage ? (

{props.title}

) : (

{props.title && {props.title}}

)}
) } const Details: FC> = (props) => { /** * `min-w` is necessary because these are used as grid children, which have * default `min-w-auto` */ return
{props.children}
} const Examples: FC> = (props) => { /** * `min-w` is necessary because these are used as grid children, which have * default `min-w-auto` */ return (
{props.children}
) } const EducationRow: FC> = (props) => { return (
{props.children}
) } const EducationSection: FC> = ({ icon, hideTitle = false, ...props }) => { return (
{!hideTitle && } {props.children}
) } // function based layout RefSubLayout.Section = Section // education based layout RefSubLayout.EducationSection = EducationSection RefSubLayout.EducationRow = EducationRow // common columns RefSubLayout.Details = Details RefSubLayout.Examples = Examples export default RefSubLayout