import { useScroll, useSize } from 'ahooks'; import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useExternalTextareaObserver } from '@/hooks/useExternalTextareaObserver'; import SyntaxHighlighter from './SyntaxHighlighter'; import grammar from './prompt.tmLanguage.json'; import { themeConfig } from './promptTheme'; import { useStyles } from './style'; const options: any = { langs: [ { aliases: ['prompt'], grammar, id: 'prompt', scopeName: 'source.prompt', }, ], themes: [themeConfig(true), themeConfig(false)], }; interface AppProps { parentId: string; } const App = memo(({ parentId }) => { const ref: any = useRef(null); const [prompt, setPrompt] = useState(''); const { styles, theme } = useStyles(); const nativeTextareaValue = useExternalTextareaObserver(`${parentId} label textarea`); const nativeTextarea = useMemo( () => gradioApp().querySelector(`${parentId} label textarea`) as HTMLTextAreaElement, [parentId], ); const size = useSize(nativeTextarea); const scroll = useScroll(nativeTextarea); const handlePromptChange = useCallback((event: any) => { setPrompt(event.target.value); }, []); useEffect(() => { ref.current.scroll(0, scroll?.top || 0); }, [scroll?.top]); useEffect(() => { nativeTextarea.addEventListener('change', handlePromptChange); return () => { nativeTextarea.removeEventListener('change', handlePromptChange); }; }, []); useEffect(() => { if (theme) { nativeTextarea.style.color = 'transparent'; nativeTextarea.style.caretColor = theme.colorSuccess; } }, [theme]); useEffect(() => { setPrompt(nativeTextareaValue); }, [nativeTextareaValue]); return (
{prompt.trim()}
); }); export default App;