Files
Momento/memento-note/components/mobile-editor-toolbar.tsx

144 lines
4.1 KiB
TypeScript

'use client'
import React from 'react'
import type { Editor } from '@tiptap/core'
import {
Bold, Italic, Highlighter, Link2, List, CheckSquare,
Heading, Code, Sparkles, MessageSquare, Quote, AlignLeft
} from 'lucide-react'
import { cn } from '@/lib/utils'
export type MobileEditorToolbarProps = {
editor: Editor | null
onOpenActionSheet: () => void
onInsertImage?: () => void
}
export function MobileEditorToolbar({
editor,
onOpenActionSheet,
onInsertImage,
}: MobileEditorToolbarProps) {
if (!editor) return null
// Format states
const isBold = editor.isActive('bold')
const isItalic = editor.isActive('italic')
const isHighlight = editor.isActive('highlight')
const isLink = editor.isActive('link')
const isBulletList = editor.isActive('bulletList')
const isTaskList = editor.isActive('taskList')
const isCodeBlock = editor.isActive('codeBlock')
const isHeading = editor.isActive('heading')
const toggleHeadingCycle = () => {
if (editor.isActive('heading', { level: 1 })) {
editor.chain().focus().toggleHeading({ level: 2 }).run()
} else if (editor.isActive('heading', { level: 2 })) {
editor.chain().focus().toggleHeading({ level: 3 }).run()
} else if (editor.isActive('heading', { level: 3 })) {
editor.chain().focus().setParagraph().run()
} else {
editor.chain().focus().toggleHeading({ level: 1 }).run()
}
}
const handleLinkPress = () => {
if (isLink) {
editor.chain().focus().unsetLink().run()
} else {
const url = window.prompt('URL:')
if (url && url.trim()) {
editor.chain().focus().setLink({ href: url.trim() }).run()
}
}
}
return (
<div className="mobile-editor-toolbar-container">
<div className="mobile-editor-toolbar-scroll">
<button
type="button"
className={cn('mobile-toolbar-btn', isBold && 'active')}
onClick={() => editor.chain().focus().toggleBold().run()}
aria-label="Bold"
>
<Bold size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isItalic && 'active')}
onClick={() => editor.chain().focus().toggleItalic().run()}
aria-label="Italic"
>
<Italic size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isHighlight && 'active')}
onClick={() => editor.chain().focus().toggleHighlight().run()}
aria-label="Highlight"
>
<Highlighter size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isLink && 'active')}
onClick={handleLinkPress}
aria-label="Link"
>
<Link2 size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isBulletList && 'active')}
onClick={() => editor.chain().focus().toggleBulletList().run()}
aria-label="Bullet List"
>
<List size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isTaskList && 'active')}
onClick={() => editor.chain().focus().toggleTaskList().run()}
aria-label="Task List"
>
<CheckSquare size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isHeading && 'active')}
onClick={toggleHeadingCycle}
aria-label="Heading"
>
<Heading size={18} />
</button>
<button
type="button"
className={cn('mobile-toolbar-btn', isCodeBlock && 'active')}
onClick={() => editor.chain().focus().toggleCodeBlock().run()}
aria-label="Code Block"
>
<Code size={18} />
</button>
<button
type="button"
className="mobile-toolbar-btn highlight-btn"
onClick={onOpenActionSheet}
aria-label="Plus"
>
<Sparkles size={18} className="text-amber-500 animate-pulse" />
</button>
</div>
</div>
)
}