@@ -11,7 +11,8 @@ interface TextEditorProps {
1111 onValidationChange ?: ( isValid : boolean ) => void ;
1212}
1313
14- const MAX_LENGTH = 200 ;
14+ const MAX_LENGTH = 2000 ;
15+ const IMAGE_WEIGHT = 200 ;
1516
1617const formats = [
1718 'font' , 'header' , 'bold' , 'italic' , 'underline' , 'strike' , 'blockquote' ,
@@ -48,6 +49,15 @@ const TextEditor = ({ value = '', onChange, setEventState, onValidationChange }:
4849 }
4950 } ;
5051 } ;
52+ const getImageCount = ( htmlContent : string ) : number => {
53+ const matches = htmlContent . match ( / < i m g [ ^ > ] * s r c = " [ ^ " ] * " [ ^ > ] * > / g) ;
54+ return matches ? matches . length : 0 ;
55+ } ;
56+ const getTotalContentLength = ( htmlContent : string ) : number => {
57+ const textLength = getPlainText ( htmlContent ) . length ;
58+ const imageCount = getImageCount ( htmlContent ) ;
59+ return textLength + imageCount * IMAGE_WEIGHT ;
60+ } ;
5161
5262 const modules = useMemo (
5363 ( ) => ( {
@@ -72,18 +82,18 @@ const TextEditor = ({ value = '', onChange, setEventState, onValidationChange }:
7282 const getPlainText = ( htmlContent : string ) : string => {
7383 return htmlContent . replace ( / < [ ^ > ] * > / g, '' ) . trim ( ) ;
7484 } ;
75-
85+
7686 const handleChange = ( value : string ) => {
77- const editorInstance = quillRef . current ?. getEditor ( ) ;
78- const plainTextLength = editorInstance ? editorInstance . getText ( ) . trim ( ) . length : getPlainText ( value ) . length ;
87+ const totalLength = getTotalContentLength ( value ) ;
7988
80- if ( plainTextLength <= MAX_LENGTH ) {
89+ if ( totalLength <= MAX_LENGTH ) {
8190 setContent ( value ) ;
8291 onChange ?.( value ) ;
8392 setEventState ?.( prev => ( { ...prev , description : value } ) ) ;
84- onValidationChange ?.( plainTextLength > 0 ) ;
93+ onValidationChange ?.( getPlainText ( value ) . length > 0 ) ;
8594 setIsOverLimit ( false ) ;
8695 } else {
96+ const editorInstance = quillRef . current ?. getEditor ( ) ;
8797 if ( editorInstance ) {
8898 editorInstance . setContents ( editorInstance . clipboard . convert ( content ) ) ;
8999 }
@@ -97,7 +107,8 @@ const TextEditor = ({ value = '', onChange, setEventState, onValidationChange }:
97107 onValidationChange ?.( plainText . length > 0 ) ;
98108 } , [ value ] ) ;
99109
100- const plainTextLength = getPlainText ( content ) . length ;
110+ const totalLength = getTotalContentLength ( content ) ;
111+ const imageCount = getImageCount ( content ) ;
101112
102113
103114 return (
@@ -114,11 +125,12 @@ const TextEditor = ({ value = '', onChange, setEventState, onValidationChange }:
114125 />
115126 < div className = "flex justify-between items-center mt-1" >
116127 < p className = { `text-sm ${ isOverLimit ? 'text-red-500' : 'text-gray-500' } ` } >
117- { plainTextLength } / { MAX_LENGTH } 자
128+ { totalLength } / { MAX_LENGTH } 자
129+ { imageCount > 0 && ` (이미지 ${ imageCount } 개 포함)` }
118130 </ p >
119131 { isOverLimit && (
120132 < p className = "text-sm text-red-500 font-medium" >
121- 200자를 초과할 수 없습니다.
133+ { MAX_LENGTH } 자를 초과할 수 없습니다.
122134 </ p >
123135 ) }
124136 </ div >
0 commit comments