@@ -237,14 +237,19 @@ interface CommentEditorProps {
237237 onGetImageSrc ?: ( bkey : string ) => string
238238 maxAttachments ?: number
239239 maxImageSizeKB ?: number
240+ maxLength ?: number
240241}
241242
243+ const DEFAULT_MAX_LENGTH = 4000
244+
242245const Tiptap : React . FunctionComponent < CommentEditorProps > = ( props ) => {
246+ const maxLength = props . maxLength ?? DEFAULT_MAX_LENGTH
243247 const [ isRawMarkdownMode , setIsRawMarkdownMode ] = useState ( false )
244248 const [ imageUploads , setImageUploads ] = useState < ImageUpload [ ] > ( [ ] )
245249 const [ isLinkModalOpen , setIsLinkModalOpen ] = useState ( false )
246250 const [ selectedText , setSelectedText ] = useState ( "" )
247251 const [ markdownText , setMarkdownText ] = useState ( props . initialValue ?? "" )
252+ const [ contentLength , setContentLength ] = useState ( ( props . initialValue ?? "" ) . length )
248253 const allowedProtocols = useAllowedProtocols ( )
249254
250255 // Use a ref instead of state for tracking document images
@@ -326,6 +331,8 @@ const Tiptap: React.FunctionComponent<CommentEditorProps> = (props) => {
326331 // Get the current markdown content
327332 const markdown = isRawMarkdownMode ? editor . getText ( ) : editor . storage . markdown . getMarkdown ( )
328333
334+ setContentLength ( markdown . length )
335+
329336 // Pass markdown to parent (plain text will be generated in ShareFeedback if needed)
330337 props . onChange && props . onChange ( markdown )
331338
@@ -604,6 +611,7 @@ const Tiptap: React.FunctionComponent<CommentEditorProps> = (props) => {
604611 const handleTextareaChange = ( e : React . ChangeEvent < HTMLTextAreaElement > ) => {
605612 const newValue = e . target . value
606613 setMarkdownText ( newValue )
614+ setContentLength ( newValue . length )
607615
608616 // Notify parent component
609617 if ( props . onChange ) {
@@ -639,13 +647,25 @@ const Tiptap: React.FunctionComponent<CommentEditorProps> = (props) => {
639647 onChange = { handleTextareaChange }
640648 onFocus = { props . onFocus }
641649 disabled = { props . disabled }
650+ maxLength = { maxLength }
642651 placeholder = { props . placeholder ?? "Write your comment here..." }
643652 data-testid = "markdown-textarea"
644653 />
645654 ) : (
646655 < EditorContent editor = { editor } data-testid = "tiptap-editor" />
647656 ) }
648657 </ div >
658+ { contentLength >= maxLength * 0.8 && (
659+ < div
660+ className = { classSet ( {
661+ "c-comment-editor-counter" : true ,
662+ "c-comment-editor-counter--over" : contentLength > maxLength ,
663+ } ) }
664+ data-testid = "comment-editor-counter"
665+ >
666+ { contentLength } / { maxLength }
667+ </ div >
668+ ) }
649669 < DisplayError fields = { [ props . field ] } error = { ctx . error } />
650670 < LinkInsertModal isOpen = { isLinkModalOpen } onClose = { ( ) => setIsLinkModalOpen ( false ) } onInsertLink = { handleInsertLink } selectedText = { selectedText } />
651671 </ div >
0 commit comments