mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
118 lines
3.9 KiB
Markdown
118 lines
3.9 KiB
Markdown
# Rich Text Editor - Tab Visibility Fix
|
|
|
|
## Issue
|
|
The rich text editor did not work in the admin blog creation page when placed inside a hidden tab panel. The editor worked correctly in the activity page where it was directly visible in the modal body.
|
|
|
|
## Root Cause
|
|
When Quill editor initializes inside a hidden element (Chakra UI's TabPanel with `display: none`), it cannot:
|
|
1. Properly measure dimensions for the editor container
|
|
2. Render the toolbar correctly
|
|
3. Set up the editor area with proper visibility
|
|
|
|
This is a common issue with WYSIWYG editors in tabbed interfaces.
|
|
|
|
## Solution Applied
|
|
|
|
### File Modified
|
|
`/frontend/src/components/common/CustomRichEditor.tsx`
|
|
|
|
### Changes Made
|
|
|
|
1. **Added Container Ref**
|
|
- Added `containerRef` to track the editor's container element
|
|
- Attached ref to the Box component wrapping ReactQuill
|
|
|
|
2. **Implemented Visibility Detection**
|
|
- Added IntersectionObserver to detect when the editor becomes visible
|
|
- Observer watches for when the container enters the viewport or becomes visible (e.g., tab switch)
|
|
|
|
3. **Forced Refresh on Visibility**
|
|
- When editor becomes visible, force Quill to refresh:
|
|
- Set toolbar display to flex and visibility to visible
|
|
- Set editor container display to block and visibility to visible
|
|
- Trigger after 100ms delay to ensure DOM is ready
|
|
|
|
### Code Details
|
|
|
|
```typescript
|
|
// Added containerRef
|
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
|
|
// Visibility detection effect
|
|
useEffect(() => {
|
|
if (!containerRef.current) return;
|
|
|
|
const observer = new IntersectionObserver(
|
|
(entries) => {
|
|
entries.forEach((entry) => {
|
|
if (entry.isIntersecting && entry.intersectionRatio > 0) {
|
|
// Editor became visible - force Quill to refresh
|
|
setTimeout(() => {
|
|
const editor = quillRef.current?.getEditor();
|
|
if (editor && editor.root) {
|
|
try {
|
|
editor.root.style.display = 'block';
|
|
const toolbar = editor.root.previousSibling as HTMLElement;
|
|
if (toolbar && toolbar.classList.contains('ql-toolbar')) {
|
|
toolbar.style.display = 'flex';
|
|
toolbar.style.visibility = 'visible';
|
|
toolbar.style.opacity = '1';
|
|
}
|
|
if (editor.container) {
|
|
editor.container.style.display = 'block';
|
|
editor.container.style.visibility = 'visible';
|
|
editor.container.style.opacity = '1';
|
|
}
|
|
} catch (err) {
|
|
console.warn('Failed to refresh Quill editor:', err);
|
|
}
|
|
}
|
|
}, 100);
|
|
}
|
|
});
|
|
},
|
|
{
|
|
threshold: 0.1,
|
|
rootMargin: '50px'
|
|
}
|
|
);
|
|
|
|
observer.observe(containerRef.current);
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, []);
|
|
```
|
|
|
|
## Affected Pages
|
|
|
|
### ✅ Now Working
|
|
- **Articles Admin Page** (`/admin/articles`)
|
|
- Editor in "Obsah" tab (3rd tab) now works correctly
|
|
- Toolbar and editor area properly visible when tab is switched
|
|
|
|
### ✅ Still Working
|
|
- **Activity Admin Page** (`/admin/activities`)
|
|
- Editor in direct modal body continues to work
|
|
- No regression introduced
|
|
|
|
## Testing
|
|
1. Open Articles Admin Page
|
|
2. Click "Nový článek" (New Article)
|
|
3. Switch to "Obsah" tab
|
|
4. Verify rich text editor toolbar is visible
|
|
5. Verify editor area is visible and editable
|
|
6. Test image upload, formatting, and other features
|
|
|
|
## Technical Notes
|
|
- IntersectionObserver has 10% threshold and 50px rootMargin for early detection
|
|
- 100ms delay ensures DOM is fully rendered before forcing visibility
|
|
- Solution is non-invasive and doesn't affect editor performance
|
|
- Works with all tab-based layouts (Chakra UI Tabs, Material UI Tabs, etc.)
|
|
|
|
## Status
|
|
✅ **FIXED** - Rich text editor now works correctly in both:
|
|
- Direct modal placements (Activity page)
|
|
- Hidden tab panels (Articles admin page)
|