11import React , { useState , useEffect , useRef , useCallback } from "react"
22
33interface ContentEditableProps {
4+ containerClassName ?: string
5+ contentEditableClassName ?: string
6+ placeholderClassName ?: string
47 placeholder ?: string
8+ disabled ?: boolean
59 onChange : ( content : string ) => void
10+ onKeyUp ?: ( e : React . KeyboardEvent ) => void
11+ onKeyDown ?: ( e : React . KeyboardEvent ) => void
12+ onFocus ?: ( e : React . FocusEvent ) => void
13+ onBlur ?: ( e : React . FocusEvent ) => void
614}
715
816const ContentEditable : React . FC < ContentEditableProps > = ( {
17+ containerClassName,
18+ contentEditableClassName,
19+ placeholderClassName,
920 placeholder,
21+ disabled,
1022 onChange,
23+ onKeyUp,
24+ onKeyDown,
25+ onFocus,
26+ onBlur,
1127} ) => {
1228 const [ content , setContent ] = useState ( "" )
1329 const divRef = useRef < HTMLDivElement | null > ( null )
@@ -189,6 +205,7 @@ const ContentEditable: React.FC<ContentEditableProps> = ({
189205 }
190206
191207 function handleKeyDown ( e : React . KeyboardEvent ) {
208+ if ( onKeyDown ) onKeyDown ( e )
192209 if ( ( e . key === "Delete" || e . key === "Backspace" ) && isAllTextSelected ( ) ) {
193210 console . log ( "delete all" , isAllTextSelected ( ) )
194211 e . preventDefault ( )
@@ -219,6 +236,7 @@ const ContentEditable: React.FC<ContentEditableProps> = ({
219236
220237 return (
221238 < div
239+ className = { containerClassName }
222240 style = { {
223241 display : "flex" ,
224242 justifyContent : "flex-start" ,
@@ -231,9 +249,11 @@ const ContentEditable: React.FC<ContentEditableProps> = ({
231249 ref = { divRef }
232250 contentEditable
233251 defaultValue = { content }
252+ aria-disabled = { disabled }
234253 dir = "auto"
235254 role = "textbox"
236255 aria-label = { placeholder ?? "" }
256+ className = { contentEditableClassName }
237257 style = { {
238258 width : "100%" ,
239259 border : "1px solid #ccc" ,
@@ -248,15 +268,33 @@ const ContentEditable: React.FC<ContentEditableProps> = ({
248268 wordBreak : "break-word" ,
249269 unicodeBidi : "plaintext" ,
250270 } }
251- onInput = { ( e : React . FormEvent < HTMLDivElement > ) =>
271+ onInput = { ( e : React . FormEvent < HTMLDivElement > ) => {
272+ if ( disabled ) return
252273 setContent ( e . currentTarget . innerText )
253- }
254- onPaste = { ( e ) => handlePasteEvent ( e ) }
255- onKeyDown = { handleKeyDown }
274+ } }
275+ onPaste = { ( e ) => {
276+ if ( disabled ) return
277+ handlePasteEvent ( e )
278+ } }
279+ onFocus = { ( e ) => {
280+ if ( onFocus ) onFocus ( e )
281+ } }
282+ onBlur = { ( e ) => {
283+ if ( onBlur ) onBlur ( e )
284+ } }
285+ onKeyUp = { ( e ) => {
286+ if ( disabled ) return
287+ if ( onKeyUp ) onKeyUp ( e )
288+ } }
289+ onKeyDown = { ( e ) => {
290+ if ( disabled ) return
291+ handleKeyDown ( e )
292+ } }
256293 />
257294 { ! content && (
258295 < span
259296 dir = "auto"
297+ className = { placeholderClassName }
260298 style = { {
261299 position : "absolute" ,
262300 color : "#a2acb4" ,
0 commit comments