Skip to content

Commit 1eb5f56

Browse files
committed
refact: 이벤트 상세 설명 글자 수 이미지 길이 포함
1 parent 08528d3 commit 1eb5f56

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/features/event/ui/TextEditor.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1617
const 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(/<img [^>]*src="[^"]*"[^>]*>/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

Comments
 (0)