diff --git a/hwe/ts/components/TipTap.vue b/hwe/ts/components/TipTap.vue index c02fbb17..1e7c786e 100644 --- a/hwe/ts/components/TipTap.vue +++ b/hwe/ts/components/TipTap.vue @@ -75,8 +75,32 @@ - - + + + @@ -85,6 +109,12 @@ + @@ -114,6 +144,9 @@ + + + @@ -134,6 +167,8 @@ import StarterKit from "@tiptap/starter-kit"; import Underline from "@tiptap/extension-underline"; import TextStyle from "@tiptap/extension-text-style"; import TextAlign from "@tiptap/extension-text-align"; +import Color from "@tiptap/extension-color"; +import { BackgroundColor } from "@/tiptap-ext/BackgroundColor"; import { BButtonGroup, BButtonToolbar, @@ -153,6 +188,26 @@ const compoment = defineComponent({ BDropdownItem, BDropdownDivider, }, + methods: { + colorConvert(val: string | undefined, defaultVal: string) { + if (!val) { + return defaultVal; + } + if (val.startsWith("rgb")) { + const rgb = val.split("(")[1].split(")")[0].split(","); + const vals: string[] = []; + for (const subColor of rgb) { + const hexSubColor = parseInt(subColor).toString(16); + if (hexSubColor.length == 1) { + vals.push("0"); + } + vals.push(hexSubColor); + } + return `#${vals.join("")}`; + } + return val; + }, + }, props: { modelValue: { @@ -211,6 +266,12 @@ const compoment = defineComponent({ TextAlign.configure({ types: ["heading", "paragraph"], }), + Color.configure({ + types: ["textStyle"], + }), + BackgroundColor.configure({ + types: ["textStyle"], + }), ], editable: this.editable, content: this.modelValue, diff --git a/hwe/ts/tiptap-ext/BackgroundColor.ts b/hwe/ts/tiptap-ext/BackgroundColor.ts new file mode 100644 index 00000000..1b964cb3 --- /dev/null +++ b/hwe/ts/tiptap-ext/BackgroundColor.ts @@ -0,0 +1,70 @@ +import { Extension } from '@tiptap/core' +import '@tiptap/extension-text-style' + +export type BackgroundColorOptions = { + types: string[], +} + +declare module '@tiptap/core' { + interface Commands { + backgroundColor: { + /** + * Set the text color + */ + setBackgroundColor: (color: string) => ReturnType, + /** + * Unset the text color + */ + unsetBackgroundColor: () => ReturnType, + } + } +} + +export const BackgroundColor = Extension.create({ + name: 'backgroundColor', + + addOptions() { + return { + types: ['textStyle'], + } + }, + + addGlobalAttributes() { + return [ + { + types: this.options.types, + attributes: { + backgroundColor: { + default: null, + parseHTML: element => element.style.backgroundColor.replace(/['"]+/g, ''), + renderHTML: attributes => { + if (!attributes.backgroundColor) { + return {} + } + + return { + style: `background-color: ${attributes.backgroundColor}`, + } + }, + }, + }, + }, + ] + }, + + addCommands() { + return { + setBackgroundColor: backgroundColor => ({ chain }) => { + return chain() + .setMark('textStyle', { backgroundColor }) + .run() + }, + unsetBackgroundColor: () => ({ chain }) => { + return chain() + .setMark('textStyle', { backgroundColor: null }) + .removeEmptyTextStyle() + .run() + }, + } + }, +}) diff --git a/package.json b/package.json index eedc7b22..96a4369a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "license": "MIT", "type": "module", "dependencies": { + "@tiptap/extension-color": "^2.0.0-beta.9", "@tiptap/extension-image": "^2.0.0-beta.24", "@tiptap/extension-link": "^2.0.0-beta.33", "@tiptap/extension-text-align": "^2.0.0-beta.29",