refactor: use mdx rsc
This commit is contained in:
7
components/BlogNewsletterForm.tsx
Normal file
7
components/BlogNewsletterForm.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
'use client'
|
||||
|
||||
// dot notation breaks RSC - https://github.com/vercel/next.js/issues/51593
|
||||
// temporarily workaround to re-export
|
||||
import { BlogNewsletterForm } from 'pliny/ui/NewsletterForm'
|
||||
|
||||
export default BlogNewsletterForm
|
13
components/ClientComponent.tsx
Normal file
13
components/ClientComponent.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function ClientComponent() {
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Client Component</h1>
|
||||
<p>Count: {count}</p>
|
||||
<button onClick={() => setCount(count + 1)}>Inc</button>
|
||||
</>
|
||||
)
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
import Link from 'next/link'
|
||||
import { AnchorHTMLAttributes, DetailedHTMLProps } from 'react'
|
||||
|
||||
const CustomLink = ({
|
||||
const CustomLink = async ({
|
||||
href,
|
||||
...rest
|
||||
}: DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>) => {
|
||||
|
@ -1,16 +1,17 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React from 'react'
|
||||
import { MDXLayout, ComponentMap } from 'pliny/mdx-components'
|
||||
import { useMDXComponent } from 'next-contentlayer/hooks'
|
||||
import { ComponentMap } from 'pliny/mdx-components'
|
||||
import { TOCInline } from 'pliny/ui/TOCInline'
|
||||
import { Pre } from 'pliny/ui/Pre'
|
||||
import { BlogNewsletterForm } from 'pliny/ui/NewsletterForm'
|
||||
import Pre from './Pre'
|
||||
import BlogNewsletterForm from './BlogNewsletterForm'
|
||||
// import { BlogNewsletterForm } from 'pliny/ui/NewsletterForm'
|
||||
|
||||
import Image from './Image'
|
||||
import CustomLink from './Link'
|
||||
|
||||
export const Wrapper = ({ layout, content, ...rest }: MDXLayout) => {
|
||||
const Layout = require(`../layouts/${layout}`).default
|
||||
return <Layout content={content} {...rest} />
|
||||
interface MdxProps {
|
||||
code: string
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export const MDXComponents: ComponentMap = {
|
||||
@ -18,6 +19,11 @@ export const MDXComponents: ComponentMap = {
|
||||
TOCInline,
|
||||
a: CustomLink,
|
||||
pre: Pre,
|
||||
wrapper: Wrapper,
|
||||
BlogNewsletterForm,
|
||||
}
|
||||
|
||||
export function Mdx({ code, ...rest }: MdxProps) {
|
||||
const Component = useMDXComponent(code)
|
||||
|
||||
return <Component components={{ ...MDXComponents }} {...rest} />
|
||||
}
|
||||
|
72
components/Pre.tsx
Normal file
72
components/Pre.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
'use client'
|
||||
import { useState, useRef, ReactNode } from 'react'
|
||||
|
||||
const Pre = ({ children }: { children: ReactNode }) => {
|
||||
const textInput = useRef(null)
|
||||
const [hovered, setHovered] = useState(false)
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const onEnter = () => {
|
||||
setHovered(true)
|
||||
}
|
||||
const onExit = () => {
|
||||
setHovered(false)
|
||||
setCopied(false)
|
||||
}
|
||||
const onCopy = () => {
|
||||
setCopied(true)
|
||||
// @ts-ignore
|
||||
navigator.clipboard.writeText(textInput.current.textContent)
|
||||
setTimeout(() => {
|
||||
setCopied(false)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={textInput} onMouseEnter={onEnter} onMouseLeave={onExit} className="relative">
|
||||
{hovered && (
|
||||
<button
|
||||
aria-label="Copy code"
|
||||
className={`absolute right-2 top-2 h-8 w-8 rounded border-2 bg-gray-700 p-1 dark:bg-gray-800 ${
|
||||
copied
|
||||
? 'border-green-400 focus:border-green-400 focus:outline-none'
|
||||
: 'border-gray-300'
|
||||
}`}
|
||||
onClick={onCopy}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
className={copied ? 'text-green-400' : 'text-gray-300'}
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
|
||||
<pre>{children}</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Pre
|
@ -1,3 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
|
Reference in New Issue
Block a user