2
2
3
3
import React , { useEffect , useState } from "react"
4
4
5
- import { Collapsible , CollapsibleContent , CollapsibleTrigger } from "@radix-ui/react-collapsible"
6
5
import { AnimatePresence , motion } from "framer-motion"
7
- import { IconCheck , IconChevronLgDown , IconCircleInfo , IconDuplicate } from "justd-icons"
6
+ import { IconCheck , IconCircleInfo , IconDuplicate } from "justd-icons"
8
7
import rehypePrettyCode from "rehype-pretty-code"
9
8
import rehypeStringify from "rehype-stringify"
10
9
import remarkParse from "remark-parse"
11
10
import remarkRehype from "remark-rehype"
12
- import { twJoin } from "tailwind-merge"
13
- import { Button , ButtonPrimitive , type ButtonProps , cn } from "ui"
11
+ import { Button , type ButtonProps , cn } from "ui"
14
12
import { unified } from "unified"
15
13
import { copyToClipboard } from "usemods"
16
14
@@ -20,13 +18,22 @@ export const snippetVariants = {
20
18
}
21
19
22
20
export interface CodeProps {
21
+ icon ?: React . ComponentType < React . SVGProps < SVGSVGElement > >
22
+ title ?: string
23
23
lang ?: string
24
24
code : string
25
25
withImportCopy ?: boolean
26
26
className ?: string
27
27
}
28
28
29
- function Code ( { className, lang = "tsx" , code, withImportCopy = true } : CodeProps ) {
29
+ function Code ( {
30
+ title,
31
+ icon : Icon ,
32
+ className,
33
+ lang = "tsx" ,
34
+ code,
35
+ withImportCopy = true
36
+ } : CodeProps ) {
30
37
const [ copied , setCopied ] = React . useState < string > ( "" )
31
38
32
39
function copyImportsToClipboard ( ) : void {
@@ -44,12 +51,21 @@ function Code({ className, lang = "tsx", code, withImportCopy = true }: CodeProp
44
51
return (
45
52
< div
46
53
className = { cn (
47
- "dfakdpxe2941 not-prose group relative max-h-96 overflow-y -auto rounded-lg font-mono text-sm" ,
54
+ "not-prose group relative [&_pre]: max-h-96 [&_pre]: overflow-auto rounded-lg font-mono text-sm" ,
48
55
className
49
56
) }
50
57
>
51
- < div className = "relative -mt-6" >
52
- < div className = "sticky top-3 right-3 mr-3 z-20 flex gap-1.5 justify-end" >
58
+ { title && (
59
+ < figcaption
60
+ className = { cn ( Icon && "flex items-center gap-x-1" ) }
61
+ data-rehype-pretty-code-title = ""
62
+ >
63
+ { Icon && < Icon className = "text-cyan-600 dark:text-cyan-500 size-4" /> }
64
+ < span className = "font-sans" > { title } </ span >
65
+ </ figcaption >
66
+ ) }
67
+ < div className = "relative" >
68
+ < div className = "absolute cpybtn top-3 right-0 mr-3 z-20 flex gap-1.5 justify-end" >
53
69
{ withImportCopy && (
54
70
< CopyButton
55
71
ariaLabel = "Copy imports statement"
@@ -68,78 +84,6 @@ function Code({ className, lang = "tsx", code, withImportCopy = true }: CodeProp
68
84
)
69
85
}
70
86
71
- function CodeContainer ( { children, isOpened } : { children : React . ReactNode ; isOpened : boolean } ) {
72
- return (
73
- < CollapsibleContent forceMount className = { ! isOpened ? "max-h-32" : "" } >
74
- < div
75
- className = { cn (
76
- "[&_pre]:my-0 [&_pre]:!border-0 [&_pre]:max-h-[32rem] [&_pre]:pb-[100px]" ,
77
- ! isOpened ? "[&_pre]:overflow-hidden" : "[&_pre]:overflow-auto"
78
- ) }
79
- >
80
- { children }
81
- </ div >
82
- </ CollapsibleContent >
83
- )
84
- }
85
-
86
- function CodeExpandButton ( { isOpened } : { isOpened : boolean } ) {
87
- return (
88
- < div
89
- className = { cn (
90
- "absolute flex items-center z-10 justify-center bg-gradient-to-b from-[#0e0e10]/50 to-black" ,
91
- isOpened ? "inset-x-0 bottom-0 h-16" : "inset-0"
92
- ) }
93
- >
94
- < CollapsibleTrigger asChild >
95
- < ButtonPrimitive className = "bg-zinc-700 text-white px-4 border border-zinc-600 py-2 rounded-lg flex items-center gap-x-2 text-sm focus:outline-none" >
96
- < IconChevronLgDown
97
- className = { twJoin (
98
- "size-4 -ml-1 duration-200 transition-colors" ,
99
- isOpened && "rotate-180"
100
- ) }
101
- />
102
- { isOpened ? "Collapse" : "Expand" }
103
- </ ButtonPrimitive >
104
- </ CollapsibleTrigger >
105
- </ div >
106
- )
107
- }
108
-
109
- interface CodeCollapsibleProps {
110
- isOpened : boolean
111
- onOpenChange : ( open : boolean ) => void
112
- lang ?: string
113
- withImportCopy ?: boolean
114
- code : string
115
- }
116
-
117
- function CodeCollapsible ( {
118
- isOpened,
119
- onOpenChange,
120
- lang = "tsx" ,
121
- withImportCopy = true ,
122
- code,
123
- ...props
124
- } : React . PropsWithChildren < CodeCollapsibleProps > ) {
125
- return (
126
- < Collapsible open = { isOpened } onOpenChange = { onOpenChange } >
127
- < div className = { "relative overflow-hidden" } { ...props } >
128
- < CodeContainer isOpened = { isOpened } >
129
- < Code code = { code } lang = { lang } withImportCopy = { withImportCopy } />
130
- </ CodeContainer >
131
- < CodeExpandButton isOpened = { isOpened } />
132
- </ div >
133
- </ Collapsible >
134
- )
135
- }
136
-
137
- export function CodeCollapsibleRoot ( { children } : React . PropsWithChildren < object > ) {
138
- return (
139
- < div className = "overflow-hidden border border-zinc-800 bg-[#0e0e10] rounded-lg" > { children } </ div >
140
- )
141
- }
142
-
143
87
export function CopyRawButton ( { code } : { className ?: string ; code : string } ) {
144
88
const [ copied , setCopied ] = React . useState < string > ( "" )
145
89
const copyRaw = ( ) => {
@@ -211,7 +155,7 @@ const CopyButton = ({
211
155
return (
212
156
< Button
213
157
className = { cn (
214
- "size-7 backdrop-blur-lg rounded-md text-white bg-zinc-800 border hover:bg-zinc-700 border-zinc-700" ,
158
+ "size-7 backdrop-blur-lg rounded-md text-white bg-zinc-900 border hover:bg-zinc-800 border-zinc-700" ,
215
159
className
216
160
) }
217
161
aria-label = { ariaLabel }
@@ -246,4 +190,4 @@ const CopyButton = ({
246
190
)
247
191
}
248
192
249
- export { CodeHighlighter , CodeContainer , CodeExpandButton , CodeCollapsible , Code }
193
+ export { CodeHighlighter , Code }
0 commit comments