152 lines
4.1 KiB
TypeScript
152 lines
4.1 KiB
TypeScript
"use client"
|
|
|
|
import { type Editor } from "@tiptap/react"
|
|
import {
|
|
Bold,
|
|
Italic,
|
|
Underline as UnderlineIcon,
|
|
List,
|
|
ListOrdered,
|
|
Undo,
|
|
Redo,
|
|
Indent,
|
|
Outdent,
|
|
RemoveFormatting,
|
|
} from "lucide-react"
|
|
import { cn } from "@/lib/utils"
|
|
import {
|
|
MAIL_COMPOSE_TOOLBAR_BTN,
|
|
MAIL_COMPOSE_TOOLBAR_BTN_ACTIVE,
|
|
MAIL_COMPOSE_TOOLBAR_SEP,
|
|
} from "@/lib/mail-chrome-classes"
|
|
import {
|
|
AlignmentDropdown,
|
|
FontDropdown,
|
|
FontSizeDropdown,
|
|
ColorDropdown,
|
|
} from "./compose-formatting-dropdowns"
|
|
|
|
export function FormattingToolbar({
|
|
editor,
|
|
}: {
|
|
editor: Editor | null
|
|
}) {
|
|
if (!editor) return null
|
|
|
|
const btnClass = MAIL_COMPOSE_TOOLBAR_BTN
|
|
const activeClass = MAIL_COMPOSE_TOOLBAR_BTN_ACTIVE
|
|
const sep = <span className={MAIL_COMPOSE_TOOLBAR_SEP} aria-hidden />
|
|
|
|
return (
|
|
<div className="compose-toolbar flex flex-wrap items-center border-t border-border bg-muted px-1 py-1">
|
|
{/* Undo / Redo */}
|
|
<button
|
|
type="button"
|
|
className={btnClass}
|
|
onClick={() => editor.chain().focus().undo().run()}
|
|
disabled={!editor.can().undo()}
|
|
title="Annuler"
|
|
>
|
|
<Undo className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={btnClass}
|
|
onClick={() => editor.chain().focus().redo().run()}
|
|
disabled={!editor.can().redo()}
|
|
title="Rétablir"
|
|
>
|
|
<Redo className="h-4 w-4" />
|
|
</button>
|
|
|
|
{sep}
|
|
|
|
{/* Font */}
|
|
<FontDropdown editor={editor} btnClass={btnClass} />
|
|
|
|
{sep}
|
|
|
|
{/* Font size */}
|
|
<FontSizeDropdown editor={editor} btnClass={btnClass} />
|
|
|
|
{sep}
|
|
|
|
{/* Bold, Italic, Underline, Colors */}
|
|
<button
|
|
type="button"
|
|
className={cn(btnClass, editor.isActive("bold") && activeClass)}
|
|
onClick={() => editor.chain().focus().toggleMark("bold").run()}
|
|
title="Gras"
|
|
>
|
|
<Bold className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={cn(btnClass, editor.isActive("italic") && activeClass)}
|
|
onClick={() => editor.chain().focus().toggleMark("italic").run()}
|
|
title="Italique"
|
|
>
|
|
<Italic className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={cn(btnClass, editor.isActive("underline") && activeClass)}
|
|
onClick={() => editor.chain().focus().toggleUnderline().run()}
|
|
title="Souligné"
|
|
>
|
|
<UnderlineIcon className="h-4 w-4" />
|
|
</button>
|
|
<ColorDropdown editor={editor} btnClass={btnClass} />
|
|
|
|
{sep}
|
|
|
|
{/* Alignment dropdown, lists, indent/outdent, remove formatting */}
|
|
<AlignmentDropdown editor={editor} btnClass={btnClass} activeClass={activeClass} />
|
|
<button
|
|
type="button"
|
|
className={cn(btnClass, editor.isActive("orderedList") && activeClass)}
|
|
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
|
title="Liste numérotée"
|
|
>
|
|
<ListOrdered className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={cn(btnClass, editor.isActive("bulletList") && activeClass)}
|
|
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
|
title="Liste à puces"
|
|
>
|
|
<List className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={btnClass}
|
|
onClick={() => {
|
|
try { editor.chain().focus().liftListItem("listItem").run() } catch { /* not in list */ }
|
|
}}
|
|
title="Désindenter"
|
|
>
|
|
<Outdent className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={btnClass}
|
|
onClick={() => {
|
|
try { editor.chain().focus().sinkListItem("listItem").run() } catch { /* not in list */ }
|
|
}}
|
|
title="Indenter"
|
|
>
|
|
<Indent className="h-4 w-4" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className={btnClass}
|
|
onClick={() => editor.chain().focus().clearNodes().unsetAllMarks().run()}
|
|
title="Supprimer la mise en forme"
|
|
>
|
|
<RemoveFormatting className="h-4 w-4" />
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|