import { createContext, createElement, useContext, useMemo } from 'react' import { useLocation } from 'react-router-dom' import PrefetchLink from '@/components/PrefetchLink' import { localiseUIChildren } from '@/components/LocalisedText' import { cn } from '@/lib/utils' import type { MDXComponents } from 'mdx/types' import type { ComponentProps, HTMLAttributes, ReactNode } from 'react' const DocumentLanguageContext = createContext ('ja') export const LocalisedDocument = ( { language, children, className }: { language: string children: ReactNode className?: string }, ) => (
{children}
) const MDXLink = ( { href, children, ...props }: ComponentProps<'a'>, ) => { const location = useLocation () const url = useMemo (() => { try { const base = new URL (location.pathname + location.search, window.location.origin) return href ? new URL (href, base) : null } catch { return null } }, [href, location.pathname, location.search]) const internal = url != null && url.origin === window.location.origin && (url.protocol === 'http:' || url.protocol === 'https:') const anchor = href?.startsWith ('#') || (url?.pathname === location.pathname && url.search === location.search && Boolean (url.hash)) const external = url != null && !(internal) && (url.protocol === 'http:' || url.protocol === 'https:') if (internal && !(anchor) && props.download == null) { return ( {children} ) } return ( {children} ) } export const useMDXComponents = (): MDXComponents => { const language = useContext (DocumentLanguageContext) return { a: MDXLink, ...((language === 'ain' || language === 'ain-Kana') ? ainuMDXComponents : { }) } } const ainuElement = (element: string) => { const AinuElement = ( { children, className, ...props }: HTMLAttributes & { node?: unknown }, ) => { const documentLanguage = useContext (DocumentLanguageContext) const language = props.lang ?? documentLanguage // ReactMarkdown supplies its syntax node; it is not a DOM attribute. delete props.node return ( {createElement (element, { ...props, lang: language === 'ain' ? 'ain-Kana' : language, className: cn ( (language === 'ain' || language === 'ain-Kana') && 'ainu-ui-text', className) }, localiseUIChildren (children, language))} ) } return AinuElement } // Opt in using the document's language, independently of the URL locale. export const ainuMDXComponents = { p: ainuElement ('p'), h1: ainuElement ('h1'), h2: ainuElement ('h2'), h3: ainuElement ('h3'), h4: ainuElement ('h4'), h5: ainuElement ('h5'), h6: ainuElement ('h6'), li: ainuElement ('li'), dt: ainuElement ('dt'), dd: ainuElement ('dd'), th: ainuElement ('th'), td: ainuElement ('td'), em: ainuElement ('em'), strong: ainuElement ('strong'), del: ainuElement ('del') }