a programming education platform www.hypercommit.com
education
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 135 lines 4.1 kB view raw
1import type { MDXComponents } from "mdx/types" 2import * as React from "react" 3import { CodeBlock } from "@workspace/ui/components/code-block" 4import { slugifyHeading } from "@/lib/headings" 5 6function HeadingAnchor({ id }: { id: string }) { 7 return ( 8 <a 9 href={`#${id}`} 10 aria-label="Link to this section" 11 className="ml-2 font-normal text-foreground/30 opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100" 12 > 13 # 14 </a> 15 ) 16} 17 18function extractFigcaptionText(node: React.ReactNode): string | undefined { 19 let title: string | undefined 20 React.Children.forEach(node, (child) => { 21 if (!React.isValidElement(child)) return 22 const props = child.props as Record<string, unknown> & { 23 children?: React.ReactNode 24 } 25 if (props["data-rehype-pretty-code-title"] !== undefined) { 26 if (typeof props.children === "string") title = props.children 27 } 28 }) 29 return title 30} 31 32function extractPre(node: React.ReactNode): React.ReactNode { 33 let pre: React.ReactNode = null 34 React.Children.forEach(node, (child) => { 35 if (!React.isValidElement(child)) return 36 const props = child.props as Record<string, unknown> 37 if (props["data-rehype-pretty-code-title"] === undefined) { 38 pre = child 39 } 40 }) 41 return pre 42} 43 44export function useMDXComponents(components: MDXComponents): MDXComponents { 45 return { 46 h1: ({ children }) => ( 47 <h1 className="text-lg font-semibold sm:text-xl">{children}</h1> 48 ), 49 h2: ({ children }) => { 50 const id = slugifyHeading(children) 51 return ( 52 <h2 id={id} className="group mt-6 scroll-mt-6 text-base font-medium"> 53 {children} 54 <HeadingAnchor id={id} /> 55 </h2> 56 ) 57 }, 58 h3: ({ children }) => { 59 const id = slugifyHeading(children) 60 return ( 61 <h3 id={id} className="group mt-4 scroll-mt-6 text-base font-medium"> 62 {children} 63 <HeadingAnchor id={id} /> 64 </h3> 65 ) 66 }, 67 p: ({ children }) => ( 68 <p className="text-base leading-7 text-foreground/80">{children}</p> 69 ), 70 a: ({ children, href }) => ( 71 <a 72 href={href} 73 className="text-primary underline-offset-4 hover:underline" 74 > 75 {children} 76 </a> 77 ), 78 ul: ({ children }) => ( 79 <ul className="ms-5 list-disc space-y-1 text-base leading-7 text-foreground/80"> 80 {children} 81 </ul> 82 ), 83 ol: ({ children }) => ( 84 <ol className="ms-5 list-decimal space-y-1 text-base leading-7 text-foreground/80"> 85 {children} 86 </ol> 87 ), 88 code: ({ children, ...props }) => ( 89 <code 90 className="rounded border bg-muted px-1 py-0.5 font-mono text-sm text-foreground" 91 {...props} 92 > 93 {children} 94 </code> 95 ), 96 table: ({ children }) => ( 97 <div className="my-4 overflow-hidden rounded-lg border border-border"> 98 <table className="w-full border-collapse text-sm">{children}</table> 99 </div> 100 ), 101 thead: ({ children }) => ( 102 <thead className="bg-muted [&_tr]:border-b [&_tr]:border-border"> 103 {children} 104 </thead> 105 ), 106 tbody: ({ children }) => ( 107 <tbody className="[&_tr]:border-border [&_tr:not(:last-child)]:border-b"> 108 {children} 109 </tbody> 110 ), 111 tr: ({ children }) => <tr>{children}</tr>, 112 th: ({ children }) => ( 113 <th className="px-4 py-2 text-left text-base font-medium tracking-wide text-muted-foreground uppercase not-last:border-r not-last:border-border"> 114 {children} 115 </th> 116 ), 117 td: ({ children }) => ( 118 <td className="px-4 py-2 text-sm leading-6 text-foreground/80 not-last:border-r not-last:border-border"> 119 {children} 120 </td> 121 ), 122 figure: (props) => { 123 const dataAttr = (props as Record<string, unknown>)[ 124 "data-rehype-pretty-code-figure" 125 ] 126 if (dataAttr === undefined) { 127 return <figure {...props} /> 128 } 129 const filename = extractFigcaptionText(props.children) 130 const pre = extractPre(props.children) 131 return <CodeBlock filename={filename}>{pre}</CodeBlock> 132 }, 133 ...components, 134 } 135}