Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
VCCI-News
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Văn Hoàng
VCCI-News
Commits
c4686167
Commit
c4686167
authored
Sep 08, 2026
by
Phạm Quang Bảo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: color text
parent
3102cf75
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
11 additions
and
13 deletions
+11
-13
rich-text-editor.tsx
src/components/shared/rich-text-editor.tsx
+11
-13
No files found.
src/components/shared/rich-text-editor.tsx
View file @
c4686167
"use client"
;
import
dynamic
from
"next/dynamic"
;
import
*
as
React
from
"react"
;
import
{
useMemo
,
useRef
}
from
"react"
;
import
{
useCallback
,
useEffect
,
useMemo
,
useRef
,
useState
}
from
"react"
;
import
type
{
JoditEditorProps
}
from
"jodit-react"
;
const
JoditEditor
=
dynamic
(()
=>
import
(
"jodit-react"
).
then
((
mod
)
=>
mod
.
default
),
{
...
...
@@ -204,13 +203,13 @@ export function AdminRichTextEditor({
readOnly
=
false
,
}:
AdminRichTextEditorProps
)
{
const
editor
=
useRef
(
null
);
const
[
isFormatting
,
setIsFormatting
]
=
React
.
useState
(
false
);
const
[
localValue
,
setLocalValue
]
=
React
.
useState
(
value
);
const
[
isFormatting
,
setIsFormatting
]
=
useState
(
false
);
const
[
localValue
,
setLocalValue
]
=
useState
(
value
);
const
formatTimeoutRef
=
useRef
<
ReturnType
<
typeof
setTimeout
>
|
null
>
(
null
);
const
lastValueRef
=
useRef
(
value
);
// Sync local value when prop changes
React
.
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
isFormatting
)
{
setLocalValue
(
value
);
lastValueRef
.
current
=
value
;
...
...
@@ -226,7 +225,7 @@ export function AdminRichTextEditor({
// Called by JoditEditor once the IJodit instance is ready. We use this to
// attach a native paste listener to the editor's editable DOM element.
const
handleEditorRef
=
React
.
useCallback
((
jodit
:
{
editor
?:
HTMLElement
})
=>
{
const
handleEditorRef
=
useCallback
((
jodit
:
{
editor
?:
HTMLElement
})
=>
{
// Clean up any previous listener
pasteCleanupRef
.
current
?.();
pasteCleanupRef
.
current
=
null
;
...
...
@@ -244,14 +243,14 @@ export function AdminRichTextEditor({
};
},
[]);
React
.
useEffect
(()
=>
{
useEffect
(()
=>
{
return
()
=>
{
pasteCleanupRef
.
current
?.();
pasteCleanupRef
.
current
=
null
;
};
},
[]);
const
handleFormat
=
React
.
useCallback
((
html
:
string
)
=>
{
const
handleFormat
=
useCallback
((
html
:
string
)
=>
{
setIsFormatting
(
true
);
// Don't update localValue - keep showing previous content during formatting
...
...
@@ -274,7 +273,7 @@ export function AdminRichTextEditor({
},
3500
);
// 3.5s delay to show formatting message
},
[
onChange
]);
const
handleEditorChange
=
React
.
useCallback
((
html
:
string
)
=>
{
const
handleEditorChange
=
useCallback
((
html
:
string
)
=>
{
// Skip paste detection during cooldown after a recent format
if
(
recentlyFormattedRef
.
current
)
{
setLocalValue
(
html
);
...
...
@@ -495,10 +494,9 @@ export function AdminRichTextEditor({
value=
{
localValue
}
config=
{
config
}
onBlur=
{
(
nextContent
)
=>
{
const
cleaned
=
cleanPastedHtml
(
nextContent
);
setLocalValue
(
cleaned
);
onChange
(
cleaned
);
lastValueRef
.
current
=
cleaned
;
setLocalValue
(
nextContent
);
onChange
(
nextContent
);
lastValueRef
.
current
=
nextContent
;
}
}
onChange=
{
handleEditorChange
}
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment