Compare commits

...

6 Commits

Author SHA1 Message Date
Jacob Marshall f219ab83f8 lint 2025-01-29 22:47:08 +00:00
Jacob Marshall 88ab0538d9 update id gen 2025-01-29 22:45:15 +00:00
Jacob Marshall 90ee21b577 remove useState, match all special chars 2025-01-29 21:59:52 +00:00
Jacob Marshall 79f4d96742 lint 2025-01-29 20:15:38 +00:00
Jacob Marshall 61707ffb96 implement suggestions 2025-01-29 20:13:57 +00:00
Jacob Marshall 38c1d68ad0 generate headings which only consist of code 2025-01-29 19:42:45 +00:00
@@ -2,40 +2,42 @@ import type { ElementType, JSX, ReactNode } from 'react'
import { Title, type TitleProps } from '@mantine/core' import { Title, type TitleProps } from '@mantine/core'
export default function MdxTitle(props: TitleProps): JSX.Element { export default function MdxTitle(props: TitleProps): JSX.Element {
const headingId = getIdFrom(props.children)
return ( return (
<Title <Title
data-heading={props.children} data-heading={headingId}
data-order={props.order} data-order={props.order}
style={{ scrollMargin: 70 }} style={{ scrollMargin: 70 }}
{...props} {...props}
id={idGen(props.children)} id={headingId}
/> />
) )
} }
function idGen(children: ReactNode): string { function getIdFrom(children: ReactNode): string {
if (Array.isArray(children)) { const getTextContent = (node: ReactNode): string => {
const result = children if (typeof node === 'string') return node
.map((child) => { if (typeof node === 'object' && node !== null && 'props' in node) {
if (typeof child === 'string') { const child = node as { props?: { children?: ReactNode } }
return child return getTextContent(child.props?.children)
}
if (typeof child === 'object' && child !== null && 'props' in child) {
const childWithProps = child as { props?: { children?: ReactNode } }
return typeof childWithProps.props?.children === 'string'
? childWithProps.props.children
: ''
} }
return '' return ''
})
.join('')
return result.toLowerCase().replace(/\s+/g, '-')
} }
return typeof children === 'string' const textContent = Array.isArray(children)
? children.toLowerCase().replace(/\s+/g, '-') ? children.map(getTextContent).join('')
: '' : getTextContent(children)
return textContent
.normalize('NFKD') // separate accented characters into their base form and diacritical marks
.replace(/[\u0300-\u036f]/g, '') // remove all the accents
.trim()
.toLowerCase()
.replace(/\./g, '-') // some titles (configuration) contain keypath, so replace dots with hyphens
.replace(/[^a-z0-9 -]/g, '') // remove non-alphanumeric characters
.replace(/\s+/g, '-') // replace spaces with hyphens
.replace(/-+/g, '-') // remove consecutive hyphens
} }
export const h = (order: 1 | 2 | 3 | 4 | 5 | 6): ElementType<TitleProps> => { export const h = (order: 1 | 2 | 3 | 4 | 5 | 6): ElementType<TitleProps> => {
@@ -43,5 +45,6 @@ export const h = (order: 1 | 2 | 3 | 4 | 5 | 6): ElementType<TitleProps> => {
return <MdxTitle order={order} {...props} /> return <MdxTitle order={order} {...props} />
} }
render.displayName = 'H' render.displayName = 'H'
return render return render
} }