diff --git a/src/extensions/character-count.ts b/src/extensions/character-count.ts index 575882e..4fd66ec 100644 --- a/src/extensions/character-count.ts +++ b/src/extensions/character-count.ts @@ -1,4 +1,4 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { CharacterCount, type CharacterCountOptions } from "@tiptap/extension-character-count"; const defaults: Partial = { @@ -6,7 +6,7 @@ const defaults: Partial = { mode: "textSize", }; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "characterCount", title: "CharacterCount", package: "@tiptap/extension-character-count", diff --git a/src/extensions/focus.ts b/src/extensions/focus.ts index fcafefa..85399a3 100644 --- a/src/extensions/focus.ts +++ b/src/extensions/focus.ts @@ -1,11 +1,11 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import Focus, { type FocusOptions } from "@tiptap/extension-focus"; const defaults: Partial = { mode: "all", }; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "focus", title: "Focus", package: "@tiptap/extension-focus", diff --git a/src/extensions/highlight.ts b/src/extensions/highlight.ts index 80ebd9a..165003b 100644 --- a/src/extensions/highlight.ts +++ b/src/extensions/highlight.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Highlight } from "@tiptap/extension-highlight"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "highlight", title: "Highlight", package: "@tiptap/extension-highlight", diff --git a/src/extensions/image.ts b/src/extensions/image.ts index 8e44c62..e3d9cfa 100644 --- a/src/extensions/image.ts +++ b/src/extensions/image.ts @@ -1,4 +1,4 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { mergeAttributes, Node } from "@tiptap/core"; import { getPublicURL } from "../utils/get-root-path"; @@ -106,7 +106,7 @@ export const Image = Node.create({ }, }); -const extension: IExtension = { +const extension: ExtensionMeta = { name: "image", title: "Image", package: "File Library", diff --git a/src/extensions.ts b/src/extensions/index.ts similarity index 70% rename from src/extensions.ts rename to src/extensions/index.ts index 6e74618..d9011c8 100644 --- a/src/extensions.ts +++ b/src/extensions/index.ts @@ -7,19 +7,27 @@ import type { FocusOptions } from "@tiptap/extension-focus"; import type { TaskItemOptions } from "@tiptap/extension-task-item"; import type { TableOptions } from "@tiptap/extension-table"; import type { DeepPartial, Field } from "@directus/types"; -import underline from "./extensions/underline"; -import textAlign from "./extensions/text-align"; -import characterCount from "./extensions/character-count"; -import subscript from "./extensions/subscript"; -import superscript from "./extensions/superscript"; -import highlight from "./extensions/highlight"; -import typography from "./extensions/typography"; -import placeholder from "./extensions/placeholder"; -import link from "./extensions/link"; -import focus from "./extensions/focus"; -import task from "./extensions/task"; -import table from "./extensions/table"; -import image from "./extensions/image"; +import underline from "./underline"; +import textAlign from "./text-align"; +import characterCount from "./character-count"; +import subscript from "./subscript"; +import superscript from "./superscript"; +import highlight from "./highlight"; +import typography from "./typography"; +import placeholder from "./placeholder"; +import link from "./link"; +import focus from "./focus"; +import task from "./task"; +import table from "./table"; +import image from "./image"; + +type ExtensionGroup = "mark" | "node" | "editor"; + +export const extensionsGroups: { group: ExtensionGroup; label: string }[] = [ + { group: "mark", label: "Marks" }, + { group: "node", label: "Nodes" }, + { group: "editor", label: "Editor" }, +]; interface ExtensionsProps { extensions: string[] | null; @@ -32,9 +40,7 @@ interface ExtensionsProps { tableResizable: TableOptions["resizable"]; } -type ExtensionGroup = "mark" | "node" | "editor"; - -export interface IExtension { +export interface ExtensionMeta { name: string; title: string; package: string; @@ -44,7 +50,7 @@ export interface IExtension { defaults: Partial; } -export const localExtensions: IExtension[] = [ +export const extensionsMeta: ExtensionMeta[] = [ // marks highlight, link, @@ -63,16 +69,10 @@ export const localExtensions: IExtension[] = [ characterCount, ]; -export const extensionsGroups: { group: ExtensionGroup; label: string }[] = [ - { group: "mark", label: "Marks" }, - { group: "node", label: "Nodes" }, - { group: "editor", label: "Editor" }, -]; - export function loadExtensions(props: ExtensionsProps): Extensions { const extensions: Extensions = [StarterKit]; - for (const ext of localExtensions) { + for (const ext of extensionsMeta) { if (props.extensions?.includes(ext.name)) { extensions.push(ext.load(props)); } diff --git a/src/extensions/link.ts b/src/extensions/link.ts index d3d5255..b97c0c8 100644 --- a/src/extensions/link.ts +++ b/src/extensions/link.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Link } from "@tiptap/extension-link"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "link", title: "Link", package: "@tiptap/extension-link", diff --git a/src/extensions/placeholder.ts b/src/extensions/placeholder.ts index e35fe60..5ddca78 100644 --- a/src/extensions/placeholder.ts +++ b/src/extensions/placeholder.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Placeholder } from "@tiptap/extension-placeholder"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "placeholder", title: "Placeholder", package: "@tiptap/extension-placeholder", diff --git a/src/extensions/subscript.ts b/src/extensions/subscript.ts index 5fdd760..0ba3935 100644 --- a/src/extensions/subscript.ts +++ b/src/extensions/subscript.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Subscript } from "@tiptap/extension-subscript"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "subscript", title: "Subscript", package: "@tiptap/extension-subscript", diff --git a/src/extensions/superscript.ts b/src/extensions/superscript.ts index c9cce63..0f02ac3 100644 --- a/src/extensions/superscript.ts +++ b/src/extensions/superscript.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "../extensions"; import { Superscript } from "@tiptap/extension-superscript"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "superscript", title: "Superscript", package: "@tiptap/extension-superscript", diff --git a/src/extensions/table.ts b/src/extensions/table.ts index 45b518d..bd4bb21 100644 --- a/src/extensions/table.ts +++ b/src/extensions/table.ts @@ -4,7 +4,7 @@ import { TableRow } from "@tiptap/extension-table-row"; import { TableCell } from "@tiptap/extension-table-cell"; import { TableHeader } from "@tiptap/extension-table-header"; import { Extension } from "@tiptap/core"; -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; // Wrapper for all Table extensions const TableKit = Extension.create({ @@ -19,7 +19,7 @@ const defaults: Partial = { resizable: false, }; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "table", title: "Table", package: "@tiptap/extension-table", diff --git a/src/extensions/task.ts b/src/extensions/task.ts index 97fb2eb..0d9aba8 100644 --- a/src/extensions/task.ts +++ b/src/extensions/task.ts @@ -2,7 +2,7 @@ import { TaskList } from "@tiptap/extension-task-list"; import type { TaskItemOptions } from "@tiptap/extension-task-item"; import { TaskItem } from "@tiptap/extension-task-item"; import { Extension } from "@tiptap/core"; -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; // Wrapper for TaskList + TaskItem const TaskKit = Extension.create({ @@ -17,7 +17,7 @@ const defaults: Partial = { nested: false, }; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "task", title: "TaskList", package: "@tiptap/extension-task-(list|item)", diff --git a/src/extensions/text-align.ts b/src/extensions/text-align.ts index 8b7c1a0..3da6985 100644 --- a/src/extensions/text-align.ts +++ b/src/extensions/text-align.ts @@ -1,11 +1,11 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { TextAlign, type TextAlignOptions } from "@tiptap/extension-text-align"; const defaults: Partial = { types: ["heading", "paragraph"], }; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "textAlign", title: "TextAlign", package: "@tiptap/extension-text-align", diff --git a/src/extensions/typography.ts b/src/extensions/typography.ts index 831016f..8bb831b 100644 --- a/src/extensions/typography.ts +++ b/src/extensions/typography.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Typography } from "@tiptap/extension-typography"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "typography", title: "Typography", package: "@tiptap/extension-typography", diff --git a/src/extensions/underline.ts b/src/extensions/underline.ts index f468850..7104103 100644 --- a/src/extensions/underline.ts +++ b/src/extensions/underline.ts @@ -1,7 +1,7 @@ -import type { IExtension } from "../extensions"; +import type { ExtensionMeta } from "./index"; import { Underline } from "@tiptap/extension-underline"; -const extension: IExtension = { +const extension: ExtensionMeta = { name: "underline", title: "Underline", package: "@tiptap/extension-underline", diff --git a/src/icons/index.ts b/src/icons/index.ts new file mode 100644 index 0000000..65a962e --- /dev/null +++ b/src/icons/index.ts @@ -0,0 +1,97 @@ +import AlignCenter from "./align-center.vue"; +import AlignJustify from "./align-justify.vue"; +import AlignLeft from "./align-left.vue"; +import AlignRight from "./align-right.vue"; +import ArrowGoBackLine from "./arrow-go-back-line.vue"; +import ArrowGoForwardLine from "./arrow-go-forward-line.vue"; +import Bold from "./bold.vue"; +import CodeBoxLine from "./code-box-line.vue"; +import CodeLine from "./code-line.vue"; +import DeleteBin from "./delete-bin.vue"; +import DeleteColumn from "./delete-column.vue"; +import DeleteRow from "./delete-row.vue"; +import FormatClear from "./format-clear.vue"; +import H1 from "./h1.vue"; +import H2 from "./h2.vue"; +import H3 from "./h3.vue"; +import H4 from "./h4.vue"; +import H5 from "./h5.vue"; +import H6 from "./h6.vue"; +import Heading from "./heading.vue"; +import Image from "./image.vue"; +import InsertColumnLeft from "./insert-column-left.vue"; +import InsertColumnRight from "./insert-column-right.vue"; +import InsertRowBottom from "./insert-row-bottom.vue"; +import InsertRowTop from "./insert-row-top.vue"; +import Italic from "./italic.vue"; +import LayoutGrid from "./layout-grid.vue"; +import LayoutLeft from "./layout-left.vue"; +import LayoutTop from "./layout-top.vue"; +import Link from "./link.vue"; +import ListCheck from "./list-check.vue"; +import ListOrdered from "./list-ordered.vue"; +import ListUnordered from "./list-unordered.vue"; +import MarkPenLine from "./mark-pen-line.vue"; +import MergeCells from "./merge-cells.vue"; +import Paragraph from "./paragraph.vue"; +import QuoteText from "./quote-text.vue"; +import Separator from "./separator.vue"; +import SplitCell from "./split-cell.vue"; +import Strikethrough from "./strikethrough.vue"; +import Subscript from "./subscript.vue"; +import Superscript from "./superscript.vue"; +import Table from "./table.vue"; +import TextWrap from "./text-wrap.vue"; +import Underline from "./underline.vue"; +import Unlink from "./unlink.vue"; + +const icons = { + AlignCenter, + AlignJustify, + AlignLeft, + AlignRight, + ArrowGoBackLine, + ArrowGoForwardLine, + Bold, + CodeBoxLine, + CodeLine, + DeleteBin, + DeleteColumn, + DeleteRow, + FormatClear, + H1, + H2, + H3, + H4, + H5, + H6, + Heading, + Image, + InsertColumnLeft, + InsertColumnRight, + InsertRowBottom, + InsertRowTop, + Italic, + LayoutGrid, + LayoutLeft, + LayoutTop, + Link, + ListCheck, + ListOrdered, + ListUnordered, + MarkPenLine, + MergeCells, + Paragraph, + QuoteText, + Separator, + SplitCell, + Strikethrough, + Subscript, + Superscript, + Table, + TextWrap, + Underline, + Unlink, +}; + +export default icons; diff --git a/src/interface.ts b/src/interface.ts index 87c1594..ff11000 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,12 +1,12 @@ import { defineInterface } from "@directus/extensions-sdk"; import type { Field, DeepPartial } from "@directus/types"; import TiptapEditor from "./tiptap-editor.vue"; -import { extensionsGroups, localExtensions } from "./extensions"; +import { extensionsMeta, extensionsGroups } from "./extensions"; const extensionsChoices = extensionsGroups.map((group) => ({ text: group.label, value: group.group, - children: localExtensions + children: extensionsMeta .filter((extension) => extension.group === group.group) .map((extension) => ({ value: extension.name, @@ -45,7 +45,7 @@ export default defineInterface({ if (field.meta?.options) { // append options of selected extensions - for (const extension of localExtensions) { + for (const extension of extensionsMeta) { if (field.meta.options.extensions?.includes(extension.name)) { options.push(...extension.options); } diff --git a/src/tiptap-editor.vue b/src/tiptap-editor.vue index 5ff8b1e..a2704df 100644 --- a/src/tiptap-editor.vue +++ b/src/tiptap-editor.vue @@ -39,7 +39,7 @@ :active="editor.isActive('bold')" @click="editor.chain().focus().toggleBold().run()" > - + - + - + - + - + - + - + - +
@@ -140,13 +140,13 @@ :active="editor.isActive('heading')" @click="toggle" > - - - - - - - + + + + + + + @@ -172,7 +172,7 @@ :active="editor.isActive('paragraph')" @click="editor.chain().focus().setParagraph().run()" > - + - + - + - + - + - +
@@ -252,7 +252,7 @@ - + @@ -295,7 +295,7 @@ :disabled="props.disabled" @click="editor.chain().focus().setHorizontalRule().run()" > - + - + - + - + @@ -342,13 +342,13 @@ :active="editor.isActive('table')" @click="toggle" > - + - + @@ -358,7 +358,7 @@ @click="editor.chain().focus().addColumnBefore().run()" > - + @@ -368,7 +368,7 @@ @click="editor.chain().focus().addColumnAfter().run()" > - + @@ -378,7 +378,7 @@ @click="editor.chain().focus().deleteColumn().run()" > - + @@ -389,7 +389,7 @@ @click="editor.chain().focus().addRowBefore().run()" > - + @@ -399,7 +399,7 @@ @click="editor.chain().focus().addRowAfter().run()" > - + @@ -409,7 +409,7 @@ @click="editor.chain().focus().deleteRow().run()" > - + @@ -419,7 +419,7 @@ @click="editor.chain().focus().mergeCells().run()" > - + @@ -429,7 +429,7 @@ @click="editor.chain().focus().splitCell().run()" > - + @@ -439,7 +439,7 @@ @click="editor.chain().focus().toggleHeaderRow().run()" > - + @@ -449,7 +449,7 @@ @click="editor.chain().focus().toggleHeaderColumn().run()" > - + - + @@ -471,7 +471,7 @@ @click="editor.chain().focus().deleteTable().run()" > - + @@ -486,7 +486,7 @@ :disabled="props.disabled || !editor.can().setHardBreak()" @click="editor.chain().focus().setHardBreak().run()" > - + - +
@@ -511,7 +511,7 @@ :disabled="props.disabled || !editor.can().undo()" @click="editor.chain().focus().undo().run()" > - + - +
@@ -897,39 +897,6 @@ import { translateShortcut } from "./utils/translate-shortcut"; import type { TypeType, ValueType } from "./types"; import { loadExtensions } from "./extensions"; import messages from "./messages.json"; -import IconArrowGoBackLine from "./icons/arrow-go-back-line.vue"; -import IconParagraph from "./icons/paragraph.vue"; -import IconListUnordered from "./icons/list-unordered.vue"; -import IconListOrdered from "./icons/list-ordered.vue"; -import IconBold from "./icons/bold.vue"; -import IconItalic from "./icons/italic.vue"; -import IconStrikethrough from "./icons/strikethrough.vue"; -import IconUnderline from "./icons/underline.vue"; -import IconHeading from "./icons/heading.vue"; -import IconH1 from "./icons/h1.vue"; -import IconH2 from "./icons/h2.vue"; -import IconH3 from "./icons/h3.vue"; -import IconH4 from "./icons/h4.vue"; -import IconH5 from "./icons/h5.vue"; -import IconH6 from "./icons/h6.vue"; -import IconSeparator from "./icons/separator.vue"; -import IconArrowGoForwardLine from "./icons/arrow-go-forward-line.vue"; -import IconCodeLine from "./icons/code-line.vue"; -import IconQuoteText from "./icons/quote-text.vue"; -import IconTextWrap from "./icons/text-wrap.vue"; -import IconFormatClear from "./icons/format-clear.vue"; -import IconMarkPenLine from "./icons/mark-pen-line.vue"; -import IconSubscript from "./icons/subscript.vue"; -import IconSuperscript from "./icons/superscript.vue"; -import IconCodeBoxLine from "./icons/code-box-line.vue"; -import IconAlignLeft from "./icons/align-left.vue"; -import IconAlignCenter from "./icons/align-center.vue"; -import IconAlignRight from "./icons/align-right.vue"; -import IconAlignJustify from "./icons/align-justify.vue"; -import IconLink from "./icons/link.vue"; -import IconUnlink from "./icons/unlink.vue"; -import IconListCheck from "./icons/list-check.vue"; -import IconTable from "./icons/table.vue"; import type { CharacterCountOptions } from "@tiptap/extension-character-count"; import type { TextAlignOptions } from "@tiptap/extension-text-align"; import textAlign from "./extensions/text-align"; @@ -943,19 +910,7 @@ import type { TaskItemOptions } from "@tiptap/extension-task-item"; import task from "./extensions/task"; import type { TableOptions } from "@tiptap/extension-table"; import table from "./extensions/table"; -import IconInsertColumnLeft from "./icons/insert-column-left.vue"; -import IconInsertColumnRight from "./icons/insert-column-right.vue"; -import IconDeleteColumn from "./icons/delete-column.vue"; -import IconInsertRowTop from "./icons/insert-row-top.vue"; -import IconInsertRowBottom from "./icons/insert-row-bottom.vue"; -import IconDeleteRow from "./icons/delete-row.vue"; -import IconDeleteBin from "./icons/delete-bin.vue"; -import IconMergeCells from "./icons/merge-cells.vue"; -import IconSplitCell from "./icons/split-cell.vue"; -import IconLayoutTop from "./icons/layout-top.vue"; -import IconLayoutLeft from "./icons/layout-left.vue"; -import IconLayoutGrid from "./icons/layout-grid.vue"; -import IconImage from "./icons/image.vue"; +import icons from "./icons"; import { useImage } from "./composables/image"; const { t } = useI18n({ messages }); @@ -997,25 +952,25 @@ const emit = defineEmits<{ const alignOptions = [ { align: "left", - icon: IconAlignLeft, + icon: icons.AlignLeft, text: t("wysiwyg_options.alignleft"), shortcut: translateShortcut(["meta", "shift", "l"]), }, { align: "center", - icon: IconAlignCenter, + icon: icons.AlignCenter, text: t("wysiwyg_options.aligncenter"), shortcut: translateShortcut(["meta", "shift", "e"]), }, { align: "right", - icon: IconAlignRight, + icon: icons.AlignRight, text: t("wysiwyg_options.alignright"), shortcut: translateShortcut(["meta", "shift", "r"]), }, { align: "justify", - icon: IconAlignJustify, + icon: icons.AlignJustify, text: t("wysiwyg_options.alignjustify"), shortcut: translateShortcut(["meta", "shift", "j"]), },