22
33import { Copy , Check , Eye , OpenAiLogo } from "@phosphor-icons/react/dist/ssr" ;
44import { Button } from "@pythnetwork/component-library/Button" ;
5- import { useLogger } from "@pythnetwork/component-library/useLogger" ;
6- import type { ComponentType } from "react" ;
7- import { useState } from "react" ;
5+ import { useCopy } from "@pythnetwork/component-library/useCopy" ;
6+ import type { ReactNode } from "react" ;
87
98import styles from "./index.module.scss" ;
109import { ClaudeIcon } from "../../lib/icons" ;
1110
1211type PageActionOption = {
1312 id : string ;
1413 label : string ;
15- icon : ComponentType < { className ?: string } > ;
14+ icon : ReactNode ;
1615 url ?: string ;
1716 type : "copy" | "markdown" | "llm" ;
1817 ariaLabel ?: string ;
@@ -21,7 +20,7 @@ type PageActionOption = {
2120type PageAction = {
2221 id : string ;
2322 label : string ;
24- icon : ComponentType < { className ?: string } > ;
23+ icon : ReactNode ;
2524 onClick : ( ) => void ;
2625 ariaLabel ?: string ;
2726} ;
@@ -36,52 +35,39 @@ const getPageActionOptions = (): PageActionOption[] => [
3635 {
3736 id : "copy-page" ,
3837 label : "Copy Page" ,
39- icon : Copy ,
38+ icon : < Copy /> ,
4039 type : "copy" ,
4140 ariaLabel : "Copy page content" ,
4241 } ,
4342 {
4443 id : "view-markdown" ,
4544 label : "View Markdown" ,
46- icon : Eye ,
45+ icon : < Eye /> ,
4746 type : "markdown" ,
4847 ariaLabel : "View page as Markdown" ,
4948 } ,
5049 {
5150 id : "ask-chatgpt" ,
5251 label : "Ask in ChatGPT" ,
53- icon : OpenAiLogo ,
52+ icon : < OpenAiLogo /> ,
5453 url : "https://chat.openai.com" ,
5554 type : "llm" ,
5655 ariaLabel : "Ask in ChatGPT" ,
5756 } ,
5857 {
5958 id : "ask-claude" ,
6059 label : "Ask in Claude" ,
61- icon : ClaudeIcon ,
60+ icon : < ClaudeIcon /> ,
6261 url : "https://claude.ai" ,
6362 type : "llm" ,
6463 ariaLabel : "Ask in Claude" ,
6564 } ,
6665] ;
6766
6867export function PageActions ( { content, title, url } : PageActionsProps ) {
69- const [ copiedStates , setCopiedStates ] = useState < Record < string , boolean > > ( { } ) ;
70- const logger = useLogger ( ) ;
68+ const { isCopied, copy } = useCopy ( content ) ;
7169 const pageActionOptions = getPageActionOptions ( ) ;
7270
73- async function handleCopy ( key : string ) {
74- try {
75- await navigator . clipboard . writeText ( content ) ;
76- setCopiedStates ( ( prev ) => ( { ...prev , [ key ] : true } ) ) ;
77- setTimeout ( ( ) => {
78- setCopiedStates ( ( prev ) => ( { ...prev , [ key ] : false } ) ) ;
79- } , 1200 ) ;
80- } catch ( error ) {
81- logger . error ( error ) ;
82- }
83- }
84-
8571 function handleViewMarkdown ( ) {
8672 const blob = new Blob ( [ content ] , { type : "text/plain" } ) ;
8773 const blobUrl = URL . createObjectURL ( blob ) ;
@@ -118,11 +104,7 @@ export function PageActions({ content, title, url }: PageActionsProps) {
118104 let onClick : ( ) => void ;
119105
120106 if ( option . type === "copy" ) {
121- onClick = ( ) => {
122- handleCopy ( option . id ) . catch ( ( ) => {
123- /* no-op */
124- } ) ;
125- } ;
107+ onClick = copy ;
126108 } else if ( option . type === "markdown" ) {
127109 onClick = handleViewMarkdown ;
128110 } else {
@@ -144,14 +126,13 @@ export function PageActions({ content, title, url }: PageActionsProps) {
144126 < div className = { styles . wrapper } >
145127 < div className = { styles . container } >
146128 { actions . map ( ( action , index ) => {
147- const Icon = action . icon ;
148129 const isLast = index === actions . length - 1 ;
149130
150131 const pageOption = pageActionOptions . find (
151132 ( opt ) => opt . id === action . id ,
152133 ) ;
153134 const isCopyAction = pageOption ?. type === "copy" ;
154- const showCheckIcon = isCopyAction && copiedStates [ action . id ] ;
135+ const showCheckIcon = isCopyAction && isCopied ;
155136
156137 return (
157138 < div key = { action . id } className = { styles . buttonWrapper } >
@@ -165,7 +146,7 @@ export function PageActions({ content, title, url }: PageActionsProps) {
165146 showCheckIcon ? (
166147 < Check className = { styles . icon ?? "" } />
167148 ) : (
168- < Icon className = { styles . icon ?? "" } />
149+ action . icon
169150 )
170151 }
171152 >
0 commit comments