You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
185 lines
6.1 KiB
185 lines
6.1 KiB
<script setup> |
|
import { reactive, ref } from 'vue'; |
|
|
|
const props = defineProps({ |
|
editor: { |
|
type: Object, |
|
required: true, |
|
} |
|
}); |
|
const editor = reactive(props.editor); |
|
|
|
const textColor = ref(null); |
|
const highColor = ref(null); |
|
const color = ref("#000000"); |
|
const highlight = ref("#ffff00"); |
|
const setColor = (c) => { |
|
editor.chain().focus().setColor(c).run() |
|
editor.getAttributes("textStyle").color = c; |
|
} |
|
|
|
const setAlign = (alignment) => { |
|
if (editor.isActive('image')) { |
|
editor.chain() |
|
.updateAttributes('image', { alignment }) |
|
.run() |
|
} |
|
editor.chain() |
|
.setTextAlign(alignment) |
|
.run() |
|
} |
|
</script> |
|
|
|
<template> |
|
<div class="flex items-center space-x-2 flex-wrap"> |
|
<button |
|
@click="editor.chain().focus().toggleBold().run()" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive('bold') }" |
|
title="Bold" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<path d="M6 12h8a4 4 0 0 0 0-8H6v8z"></path> |
|
<path d="M6 12h9a4 4 0 0 1 0 8H6v-8z"></path> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="editor.chain().focus().toggleItalic().run()" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive('italic') }" |
|
title="Italic" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<path d="M19 4h-9v2h3.5l-3.5 8h-3v2h9v-2h-3.5l3.5-8h3z"></path> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="editor.chain().focus().toggleUnderline().run()" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive('underline') }" |
|
title="Underline" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<path d="M6 4v6a6 6 0 0 0 6 6 6 6 0 0 0 6-6V4"></path> |
|
<line x1="4" y1="20" x2="20" y2="20"></line> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="editor.chain().focus().toggleStrike().run()" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive('strike') }" |
|
title="Strikethrough" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<path d="M17 9V5H7v4"></path> |
|
<path d="M16 15v4H8v-4"></path> |
|
<line x1="5" y1="12" x2="19" y2="12"></line> |
|
</svg> |
|
</button> |
|
|
|
<div class="flex items-center justify-center"> |
|
<button |
|
@click="!editor.state.selection.empty ? editor.chain().focus().toggleHighlight({color: highlight}).run() : highColor.click()" |
|
class="px-1 rounded" |
|
:style="'background-color:'+highlight" |
|
title="Highlight" |
|
>A</button> |
|
<input |
|
type="color" |
|
@input="(e) => highlight = e.target.value" |
|
ref="highColor" |
|
class="w-8 h-8 p-0 border-none cursor-pointer hidden" |
|
title="Text Color" |
|
/> |
|
</div> |
|
<div class="flex items-center space-x-1"> |
|
<label |
|
@click="!editor.state.selection.empty || editor.state.isFocused ? setColor(color) : textColor.click()" |
|
class="text-lg text-medium" :style="'color: ' + color">A</label> |
|
<input |
|
type="color" |
|
@input="(e) => color = e.target.value" |
|
ref="textColor" |
|
class="w-8 h-8 p-0 border-none cursor-pointer hidden" |
|
title="Text Color" |
|
/> |
|
</div> |
|
|
|
<button |
|
@click="editor.chain().focus().clearNodes().run()" |
|
class="p-1 rounded hover:bg-gray-100" |
|
title="Clear Formatting" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<path d="M12 20h9"></path> |
|
<path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path> |
|
<line x1="2" y1="2" x2="22" y2="22"></line> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="setAlign('left')" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive({ textAlign: 'left' }) }" |
|
title="Align Left" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<line x1="17" y1="10" x2="3" y2="10"></line> |
|
<line x1="21" y1="6" x2="3" y2="6"></line> |
|
<line x1="21" y1="14" x2="3" y2="14"></line> |
|
<line x1="17" y1="18" x2="3" y2="18"></line> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="setAlign('center')" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive({ textAlign: 'center' }) }" |
|
title="Align Center" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<line x1="18" y1="10" x2="6" y2="10"></line> |
|
<line x1="21" y1="6" x2="3" y2="6"></line> |
|
<line x1="21" y1="14" x2="3" y2="14"></line> |
|
<line x1="18" y1="18" x2="6" y2="18"></line> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="setAlign('right')" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive({ textAlign: 'right' }) }" |
|
title="Align Right" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<line x1="21" y1="10" x2="7" y2="10"></line> |
|
<line x1="21" y1="6" x2="3" y2="6"></line> |
|
<line x1="21" y1="14" x2="3" y2="14"></line> |
|
<line x1="21" y1="18" x2="7" y2="18"></line> |
|
</svg> |
|
</button> |
|
|
|
<button |
|
@click="setAlign('justify')" |
|
class="p-1 rounded hover:bg-gray-100" |
|
:class="{ 'bg-gray-200': editor.isActive({ textAlign: 'justify' }) }" |
|
title="Justify" |
|
> |
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor"> |
|
<line x1="21" y1="10" x2="3" y2="10"></line> |
|
<line x1="21" y1="6" x2="3" y2="6"></line> |
|
<line x1="21" y1="14" x2="3" y2="14"></line> |
|
<line x1="21" y1="18" x2="3" y2="18"></line> |
|
</svg> |
|
</button> |
|
|
|
<div class="border-l border-gray-300 h-8 mx-2"></div> |
|
|
|
<p class="text-sm text-gray-600"> |
|
Tip: Select text blocks or images before applying alignment. |
|
</p> |
|
</div> |
|
</template> |