Skip to content

Commit

Permalink
feat(Html WYSYWIG): add colors and tables
Browse files Browse the repository at this point in the history
Fix #796
  • Loading branch information
sharevb committed Sep 28, 2024
1 parent 318fb6e commit 996a5fd
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 4 deletions.
22 changes: 21 additions & 1 deletion src/tools/html-wysiwyg-editor/editor/editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import { tryOnBeforeUnmount, useVModel } from '@vueuse/core';
import { Editor, EditorContent } from '@tiptap/vue-3';
import StarterKit from '@tiptap/starter-kit';
import { useThemeVars } from 'naive-ui';
import { Color } from '@tiptap/extension-color';

Check failure on line 6 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-color' or its corresponding type declarations.
import TextStyle from '@tiptap/extension-text-style';

Check failure on line 7 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-text-style' or its corresponding type declarations.
import Highlight from '@tiptap/extension-highlight';

Check failure on line 8 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-highlight' or its corresponding type declarations.
import Gapcursor from '@tiptap/extension-gapcursor';

Check failure on line 9 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-gapcursor' or its corresponding type declarations.
import Table from '@tiptap/extension-table';

Check failure on line 10 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-table' or its corresponding type declarations.
import TableCell from '@tiptap/extension-table-cell';

Check failure on line 11 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-table-cell' or its corresponding type declarations.
import TableHeader from '@tiptap/extension-table-header';

Check failure on line 12 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-table-header' or its corresponding type declarations.
import TableRow from '@tiptap/extension-table-row';

Check failure on line 13 in src/tools/html-wysiwyg-editor/editor/editor.vue

View workflow job for this annotation

GitHub Actions / ci

Cannot find module '@tiptap/extension-table-row' or its corresponding type declarations.
import MenuBar from './menu-bar.vue';
const props = defineProps<{ html: string }>();
Expand All @@ -12,7 +20,19 @@ const html = useVModel(props, 'html', emit);
const editor = new Editor({
content: html.value,
extensions: [StarterKit],
extensions: [
StarterKit,
TextStyle,
Color,
Highlight.configure({ multicolor: true }),
Gapcursor,
Table.configure({
resizable: true,
}),
TableRow,
TableHeader,
TableCell,
],
});
editor.on('update', ({ editor }) => emit('update:html', editor.getHTML()));
Expand Down
163 changes: 160 additions & 3 deletions src/tools/html-wysiwyg-editor/editor/menu-bar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,25 @@ import {
ClearFormatting,
Code,
CodePlus,
ColorPicker,
ColumnInsertLeft,
ColumnInsertRight,
Cross,
H1,
H2,
H3,
H4,
Heading,
Italic,
LayersIntersect2,
LayersUnion,
LayoutDistributeHorizontal,
LayoutDistributeVertical,
List,
ListNumbers,
Strikethrough,
TextWrap,
RowInsertBottom,
RowInsertTop,
SeparatorVertical, Strikethrough, Table, TableOff, TextWrap, Tool,
} from '@vicons/tabler';
import type { Component } from 'vue';
import MenuBarItem from './menu-bar-item.vue';
Expand All @@ -29,9 +39,16 @@ type MenuItem =
icon: Component
title: string
action: () => void
value?: () => string
isActive?: () => boolean
type: 'button'
}
| { icon: Component
title: string
action: (color: string) => void
value: () => string
type: 'color'
}
| { type: 'divider' };
const items: MenuItem[] = [
Expand Down Expand Up @@ -141,7 +158,42 @@ const items: MenuItem[] = [
title: 'Clear format',
action: () => editor.value.chain().focus().clearNodes().unsetAllMarks().run(),
},
{
type: 'divider',
},
{
type: 'color',
title: 'Forecolor',
icon: ColorPicker,
action: color => editor.value.chain().focus().setColor(color).run(),

Check failure on line 168 in src/tools/html-wysiwyg-editor/editor/menu-bar.vue

View workflow job for this annotation

GitHub Actions / ci

Property 'setColor' does not exist on type 'ChainedCommands'.
value: () => editor.value.getAttributes('textStyle').color,
},
{
type: 'button',
icon: ClearFormatting,
title: 'Clear Forecolor',
action: () => editor.value.chain().focus().unsetColor().run(),

Check failure on line 175 in src/tools/html-wysiwyg-editor/editor/menu-bar.vue

View workflow job for this annotation

GitHub Actions / ci

Property 'unsetColor' does not exist on type 'ChainedCommands'.
},
{
type: 'divider',
},
{
type: 'color',
title: 'Highlight color',
icon: ColorPicker,
action: color => editor.value.chain().focus().setHighlight({ color }),
value: () => '#FAF594',
},
{
type: 'button',
icon: ClearFormatting,
title: 'Clear Highlight',
action: () => editor.value.chain().focus().unsetHighlight().run(),
isActive: () => editor.value.isActive('highlight'),
},
{
type: 'divider',
},
{
type: 'button',
icon: ArrowBack,
Expand All @@ -154,6 +206,99 @@ const items: MenuItem[] = [
title: 'Redo',
action: () => editor.value.chain().focus().redo().run(),
},
{
type: 'divider',
},
{
type: 'button',
action: () => editor.value.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }),
title: 'Insert table',
icon: Table,
},
{
type: 'button',
action: () => editor.value.chain().focus().addColumnBefore(),
title: 'Add column before',
icon: ColumnInsertLeft,
},
{
type: 'button',
action: () => editor.value.chain().focus().addColumnAfter(),
title: 'Add column after',
icon: ColumnInsertRight,
},
{
type: 'button',
action: () => editor.value.chain().focus().deleteColumn(),
title: 'Delete column',
icon: Cross,
},
{
type: 'button',
action: () => editor.value.chain().focus().addRowBefore(),
title: 'Add row before',
icon: RowInsertTop,
},
{
type: 'button',
action: () => editor.value.chain().focus().addRowAfter(),
title: 'Add row after',
icon: RowInsertBottom,
},
{
type: 'button',
action: () => editor.value.chain().focus().deleteRow(),
title: 'Delete row',
icon: Cross,
},
{
type: 'button',
action: () => editor.value.chain().focus().deleteTable(),
title: 'Delete table',
icon: TableOff,
},
{
type: 'button',
action: () => editor.value.chain().focus().mergeCells(),
title: 'Merge cells',
icon: LayersUnion,
},
{
type: 'button',
action: () => editor.value.chain().focus().splitCell(),
title: 'Split cell',
icon: SeparatorVertical,
},
{
type: 'button',
action: () => editor.value.chain().focus().toggleHeaderColumn(),
title: 'Toggle header column',
icon: LayoutDistributeVertical,
},
{
type: 'button',
action: () => editor.value.chain().focus().toggleHeaderRow(),
title: 'Toggle header row',
icon: LayoutDistributeHorizontal,
},
{
type: 'button',
action: () => editor.value.chain().focus().toggleHeaderCell(),
title: 'Toggle header cell',
icon: Heading,
},
{
type: 'button',
action: () => editor.value.chain().focus().mergeOrSplit(),
title: 'Merge or split',
icon: LayersIntersect2,
},
{
type: 'button',
action: () => editor.value.chain().focus().fixTables(),
title: 'Fix tables',
icon: Tool,
},
];
</script>

Expand All @@ -162,6 +307,18 @@ const items: MenuItem[] = [
<template v-for="(item, index) in items">
<n-divider v-if="item.type === 'divider'" :key="`divider${index}`" vertical />
<MenuBarItem v-else-if="item.type === 'button'" :key="index" v-bind="item" />
<c-tooltip
v-if="item.type === 'color'" :key="`color${index}`"
:tooltip="item.title"
>
<n-icon :component="item.icon" />
<n-color-picker
:show-alpha="false"
:actions="['confirm']"
:value="item.value"
@confirm="item.action"
/>
</c-tooltip>
</template>
</div>
</template>

0 comments on commit 996a5fd

Please sign in to comment.