tiptap toolbar

This commit is contained in:
Baghi330 2026-02-14 13:30:03 +03:30
parent 27c0470e16
commit bb1e24f528

View File

@ -1,124 +1,21 @@
<template> <template>
<div> <div>
<!-- تولبار ادیتور --> <!-- تولبار ادیتور -->
<div v-if="editor" class="editor-toolbar"> <div class="editor-toolbar" v-if="editor">
<div class="toolbar-group"> <div
<button class="toolbar-group"
@click="editor.chain().focus().toggleBold().run()" v-for="(group, gIndex) in toolbarGroups"
:class="{ 'is-active': editor.isActive('bold') }" :key="gIndex"
title="بولد"
> >
<span class="toolbar-icon">𝐁</span>
</button>
<button <button
@click="editor.chain().focus().toggleItalic().run()" v-for="(btn, index) in group"
:class="{ 'is-active': editor.isActive('italic') }" :key="index"
title="ایتالیک" @click="btn.action(editor)"
:class="{ 'is-active': btn.isActive ? btn.isActive(editor) : false }"
:disabled="btn.disabled ? !btn.disabled(editor) : false"
:title="btn.title"
> >
<span class="toolbar-icon">𝐼</span> <span class="toolbar-icon">{{ btn.icon }}</span>
</button>
<button
@click="editor.chain().focus().toggleUnderline().run()"
:class="{ 'is-active': editor.isActive('underline') }"
title="زیرخط"
>
<span class="toolbar-icon">𝑈</span>
</button>
<button
@click="editor.chain().focus().toggleStrike().run()"
:class="{ 'is-active': editor.isActive('strike') }"
title="خط خورده"
>
<span class="toolbar-icon">̶S̶</span>
</button>
</div>
<div class="toolbar-group">
<button
@click="editor.chain().focus().toggleHeading({ level: 1 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 1 }) }"
title="عنوان ۱"
>
H1
</button>
<button
@click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 2 }) }"
title="عنوان ۲"
>
H2
</button>
<button
@click="editor.chain().focus().toggleHeading({ level: 3 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 3 }) }"
title="عنوان ۳"
>
H3
</button>
</div>
<div class="toolbar-group">
<button
@click="editor.chain().focus().toggleBulletList().run()"
:class="{ 'is-active': editor.isActive('bulletList') }"
title="لیست بولت‌دار"
>
<span class="toolbar-icon"></span>
</button>
<button
@click="editor.chain().focus().toggleOrderedList().run()"
:class="{ 'is-active': editor.isActive('orderedList') }"
title="لیست شماره‌دار"
>
<span class="toolbar-icon">1.</span>
</button>
<button
@click="editor.chain().focus().toggleBlockquote().run()"
:class="{ 'is-active': editor.isActive('blockquote') }"
title="نقل قول"
>
<span class="toolbar-icon">"</span>
</button>
<button
@click="editor.chain().focus().toggleCodeBlock().run()"
:class="{ 'is-active': editor.isActive('codeBlock') }"
title="کد"
>
<span class="toolbar-icon">{ }</span>
</button>
</div>
<div class="toolbar-group">
<button
@click="editor.chain().focus().setDetails().run()"
:disabled="!editor.can().setDetails()"
title="افزودن جزییات"
>
<span class="toolbar-icon">📋</span>
</button>
<button
@click="editor.chain().focus().unsetDetails().run()"
:disabled="!editor.can().unsetDetails()"
title="حذف جزییات"
>
<span class="toolbar-icon">🗑</span>
</button>
</div>
<div class="toolbar-group">
<button
@click="editor.chain().focus().undo().run()"
:disabled="!editor.can().undo()"
title="بازگشت"
>
<span class="toolbar-icon"></span>
</button>
<button
@click="editor.chain().focus().redo().run()"
:disabled="!editor.can().redo()"
title="جلو"
>
<span class="toolbar-icon"></span>
</button> </button>
</div> </div>
</div> </div>
@ -158,6 +55,116 @@ function isList(text) {
/^\d+\./.test(line.trim()), /^\d+\./.test(line.trim()),
); );
} }
const toolbarGroups = [
// گروه فرمت متن
[
{
title: "بولد",
icon: "𝐁",
action: (editor) => editor.chain().focus().toggleBold().run(),
isActive: (editor) => editor.isActive("bold"),
},
{
title: "ایتالیک",
icon: "𝐼",
action: (editor) => editor.chain().focus().toggleItalic().run(),
isActive: (editor) => editor.isActive("italic"),
},
{
title: "زیرخط",
icon: "𝑈",
action: (editor) => editor.chain().focus().toggleUnderline().run(),
isActive: (editor) => editor.isActive("underline"),
},
{
title: "خط خورده",
icon: "̶S̶",
action: (editor) => editor.chain().focus().toggleStrike().run(),
isActive: (editor) => editor.isActive("strike"),
},
],
// گروه هدینگها
[
{
title: "عنوان ۱",
icon: "H1",
action: (editor) =>
editor.chain().focus().toggleHeading({ level: 1 }).run(),
isActive: (editor) => editor.isActive("heading", { level: 1 }),
},
{
title: "عنوان ۲",
icon: "H2",
action: (editor) =>
editor.chain().focus().toggleHeading({ level: 2 }).run(),
isActive: (editor) => editor.isActive("heading", { level: 2 }),
},
{
title: "عنوان ۳",
icon: "H3",
action: (editor) =>
editor.chain().focus().toggleHeading({ level: 3 }).run(),
isActive: (editor) => editor.isActive("heading", { level: 3 }),
},
],
// گروه لیست و نقل قول
[
{
title: "لیست بولت‌دار",
icon: "•",
action: (editor) => editor.chain().focus().toggleBulletList().run(),
isActive: (editor) => editor.isActive("bulletList"),
},
{
title: "لیست شماره‌دار",
icon: "1.",
action: (editor) => editor.chain().focus().toggleOrderedList().run(),
isActive: (editor) => editor.isActive("orderedList"),
},
{
title: "نقل قول",
icon: '"',
action: (editor) => editor.chain().focus().toggleBlockquote().run(),
isActive: (editor) => editor.isActive("blockquote"),
},
{
title: "کد",
icon: "{ }",
action: (editor) => editor.chain().focus().toggleCodeBlock().run(),
isActive: (editor) => editor.isActive("codeBlock"),
},
],
// گروه جزییات
[
{
title: "افزودن جزییات",
icon: "📋",
action: (editor) => editor.chain().focus().setDetails().run(),
disabled: (editor) => !editor.can().setDetails(),
},
{
title: "حذف جزییات",
icon: "🗑️",
action: (editor) => editor.chain().focus().unsetDetails().run(),
disabled: (editor) => !editor.can().unsetDetails(),
},
],
// گروه Undo/Redo
[
{
title: "بازگشت",
icon: "↩",
action: (editor) => editor.chain().focus().undo().run(),
disabled: (editor) => !editor.can().undo(),
},
{
title: "جلو",
icon: "↪",
action: (editor) => editor.chain().focus().redo().run(),
disabled: (editor) => !editor.can().redo(),
},
],
];
function formatListToHtml(text) { function formatListToHtml(text) {
const lines = text.split("\n").filter((line) => line.trim() !== ""); const lines = text.split("\n").filter((line) => line.trim() !== "");