1- import clsx from 'clsx'
2- import React , { useCallback , useEffect , useMemo , useState } from 'react'
1+ import tw , { css } from 'twin.macro'
2+ import { ClassNames } from '@emotion/react'
3+ import React , { useRef , useCallback , useEffect , useMemo , useState } from 'react'
34import Draggable , { DraggableEventHandler } from 'react-draggable'
45import cc from 'chrome-call'
56// @ts -ignore
@@ -19,6 +20,8 @@ import TranslationList from '../TranslationList'
1920const App : React . FC = ( ) => {
2021 const [ config , setConfig ] = useState < ConfigState > ( )
2122 const [ close , setClose ] = useState ( false )
23+ const appRef = useRef < HTMLDivElement > ( null )
24+ const closeButtonRef = useRef < HTMLButtonElement > ( null )
2225 const dispatch = useTranslateJobsDispatch ( )
2326
2427 const appPosition = useMemo ( ( ) => {
@@ -53,9 +56,7 @@ const App: React.FC = () => {
5356 const onDragStart : DraggableEventHandler = ( e ) => {
5457 if (
5558 e . target instanceof Element &&
56- document
57- . querySelector < HTMLButtonElement > ( '.ate_App__close-button' )
58- ?. contains ( e . target )
59+ closeButtonRef . current ?. contains ( e . target )
5960 ) {
6061 return false
6162 }
@@ -81,30 +82,61 @@ const App: React.FC = () => {
8182
8283 return (
8384 < ConfigContext . Provider value = { config } >
84- < Draggable
85- handle = ".ate_App__header"
86- onStart = { onDragStart }
87- defaultPosition = { appPosition } >
88- < div className = { clsx ( [ 'ate_App' , close && 'ate_App--inactive' ] ) } >
89- < SnackbarProvider
90- maxSnack = { 3 }
91- domRoot = { document . querySelector ( '.ate_App' ) as HTMLDivElement } >
92- < div className = "ate_App__header" >
93- < span > A Translator</ span >
94- < span >
95- < IconButton
96- className = "ate_App__close-button"
97- onClick = { ( ) => setClose ( true ) } >
98- < CloseIcon />
99- </ IconButton >
100- </ span >
85+ < ClassNames >
86+ { ( { css, cx } ) => (
87+ < Draggable
88+ handle = ".ate_App__header"
89+ onStart = { onDragStart }
90+ defaultPosition = { appPosition } >
91+ < div
92+ ref = { appRef }
93+ className = { cx (
94+ 'ate_App' ,
95+ css `
96+ position : absolute;
97+ width : 450px ;
98+ height : 600px ;
99+ z-index : 1 ;
100+ will-change : transform;
101+
102+ ${ tw `bg-white shadow-md rounded-lg overflow-hidden flex flex-col ` }
103+ ` ,
104+ close &&
105+ css `
106+ display : none;
107+ ` ,
108+ ) } >
109+ < SnackbarProvider
110+ maxSnack = { 3 }
111+ domRoot = { appRef . current || undefined } >
112+ < div
113+ className = "ate_App__header"
114+ tw = "bg-purple-800 px-5 py-3 text-white font-bold text-lg cursor-move flex justify-between items-center" >
115+ < span > A Translator</ span >
116+ < span >
117+ < IconButton
118+ ref = { closeButtonRef }
119+ css = { [
120+ tw `p-1` ,
121+ css `
122+ svg {
123+ @apply text-gray-800;
124+ }
125+ ` ,
126+ ] }
127+ onClick = { ( ) => setClose ( true ) } >
128+ < CloseIcon />
129+ </ IconButton >
130+ </ span >
131+ </ div >
132+ < ScrollToBottom tw = "flex-1 overflow-auto" debug = { false } >
133+ < TranslationList />
134+ </ ScrollToBottom >
135+ </ SnackbarProvider >
101136 </ div >
102- < ScrollToBottom className = "ate_App__container" debug = { false } >
103- < TranslationList />
104- </ ScrollToBottom >
105- </ SnackbarProvider >
106- </ div >
107- </ Draggable >
137+ </ Draggable >
138+ ) }
139+ </ ClassNames >
108140 </ ConfigContext . Provider >
109141 )
110142}
0 commit comments