feat(editor): implement US-EDITOR-MOBILE with fixed premium toolbar (44px), action sheet (bottom sheet) for block and AI actions, select all block text, and performance fallbacks

This commit is contained in:
Antigravity
2026-05-27 21:54:15 +00:00
parent ad8b8b815e
commit da4b5d18be
5 changed files with 592 additions and 2 deletions

View File

@@ -33,6 +33,8 @@ import { EditorBlockDragHandle } from './editor-block-drag-handle'
import { BlockActionMenu } from './block-action-menu'
import { SmartPasteMenu } from './smart-paste-menu'
import { SmartPasteExtendedMenu } from './smart-paste-extended-menu'
import { MobileEditorToolbar } from './mobile-editor-toolbar'
import { MobileActionSheet } from './mobile-action-sheet'
import { globalDragHandleExtensions } from '@/lib/editor/global-drag-handle-extension'
import { resolveBlockAtDragHandle } from '@/lib/editor/block-at-drag-handle'
import { parseBlockReferenceFromText, recallLastBlockReference, type ParsedBlockReference } from '@/lib/editor/parse-block-reference'
@@ -285,6 +287,8 @@ export const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorPro
isImage?: boolean
isVideo?: boolean
} | null>(null)
const [isMobile, setIsMobile] = useState(false)
const [actionSheetOpen, setActionSheetOpen] = useState(false)
const [noteLinkPickerOpen, setNoteLinkPickerOpen] = useState(false)
const [noteLinkQuery, setNoteLinkQuery] = useState('')
const noteLinkRangeRef = useRef<{ from: number; to: number } | null>(null)
@@ -300,6 +304,14 @@ export const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorPro
onChangeRef.current?.(html)
}, [])
useEffect(() => {
if (typeof window === 'undefined') return
const checkMobile = () => setIsMobile(window.innerWidth < 768)
checkMobile()
window.addEventListener('resize', checkMobile)
return () => window.removeEventListener('resize', checkMobile)
}, [])
// Listen to the slash-command event to open the BlockPicker
useEffect(() => {
const openHandler = () => setBlockPickerOpen(true)
@@ -1105,6 +1117,22 @@ export const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorPro
/>
)}
{editor && isMobile && (
<MobileEditorToolbar
editor={editor}
onOpenActionSheet={() => setActionSheetOpen(true)}
onInsertImage={imageInsert.requestInsert}
/>
)}
{editor && actionSheetOpen && (
<MobileActionSheet
editor={editor}
isOpen={actionSheetOpen}
onClose={() => setActionSheetOpen(false)}
/>
)}
{imageInsert.open && (
<ImageModal onConfirm={imageInsert.confirm} onCancel={imageInsert.cancel} />
)}