diff --git a/package.json b/package.json index 13dcb2e..6ae0e77 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@semantic-release/git": "^10.0.1", "@tiptap/core": "^2.0.2", "@tiptap/extension-character-count": "^2.0.2", + "@tiptap/extension-focus": "^2.0.3", "@tiptap/extension-highlight": "^2.0.2", "@tiptap/extension-link": "^2.0.2", "@tiptap/extension-placeholder": "^2.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f36297e..b294686 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,9 @@ devDependencies: '@tiptap/extension-character-count': specifier: ^2.0.2 version: 2.0.2(@tiptap/core@2.0.2)(@tiptap/pm@2.0.2) + '@tiptap/extension-focus': + specifier: ^2.0.3 + version: 2.0.3(@tiptap/core@2.0.2)(@tiptap/pm@2.0.2) '@tiptap/extension-highlight': specifier: ^2.0.2 version: 2.0.2(@tiptap/core@2.0.2) @@ -1116,6 +1119,16 @@ packages: tippy.js: 6.3.7 dev: true + /@tiptap/extension-focus@2.0.3(@tiptap/core@2.0.2)(@tiptap/pm@2.0.2): + resolution: {integrity: sha512-WTJEmbGyHK8F/v1k5/5viLAa7PqtNoWOO4Qt4PBoUPlFDW97QMEh5m8Cvqw/RtbxTiGDHz6T+I5IJsKXGJed/A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.0.2(@tiptap/pm@2.0.2) + '@tiptap/pm': 2.0.2(@tiptap/core@2.0.2) + dev: true + /@tiptap/extension-gapcursor@2.0.2(@tiptap/core@2.0.2)(@tiptap/pm@2.0.2): resolution: {integrity: sha512-NimvDbM8Cc8+l/ZWJW8aqZRH6hzz1iJLOAMyj23UjHQWvKO0yqE1KBLGZI2GU+vizEK3LkZZXhXnh76rnTwgSQ==} peerDependencies: diff --git a/src/extensions.ts b/src/extensions.ts index 7336bd7..0f41d7f 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -3,6 +3,7 @@ import StarterKit from "@tiptap/starter-kit"; import type { CharacterCountOptions } from "@tiptap/extension-character-count"; import type { TextAlignOptions } from "@tiptap/extension-text-align"; import type { PlaceholderOptions } from "@tiptap/extension-placeholder"; +import type { FocusOptions } from "@tiptap/extension-focus"; import type { DeepPartial, Field } from "@directus/shared/types"; import underline from "./extensions/underline"; import textAlign from "./extensions/text-align"; @@ -13,6 +14,7 @@ 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"; interface ExtensionsProps { extensions: string[] | null; @@ -20,6 +22,7 @@ interface ExtensionsProps { characterCountLimit: CharacterCountOptions["limit"]; characterCountMode: CharacterCountOptions["mode"]; textAlignTypes: TextAlignOptions["types"]; + focusMode: FocusOptions["mode"]; } type ExtensionGroup = "mark" | "node" | "editor"; @@ -45,6 +48,7 @@ export const localExtensions: IExtension[] = [ textAlign, // editor placeholder, + focus, typography, characterCount, ]; diff --git a/src/extensions/focus.ts b/src/extensions/focus.ts new file mode 100644 index 0000000..fcafefa --- /dev/null +++ b/src/extensions/focus.ts @@ -0,0 +1,43 @@ +import type { IExtension } from "../extensions"; +import Focus, { type FocusOptions } from "@tiptap/extension-focus"; + +const defaults: Partial = { + mode: "all", +}; + +const extension: IExtension = { + name: "focus", + title: "Focus", + package: "@tiptap/extension-focus", + group: "editor", + defaults, + options: [ + { + field: "focusMode", + name: "Focus mode", + type: "string", + meta: { + interface: "select-dropdown", + width: "half", + note: "Apply the effect to 'all', the 'shallowest' or the 'deepest' node", + options: { + choices: [ + { text: "all", value: "all" }, + { text: "shallowest", value: "shallowest" }, + { text: "deepest", value: "deepest" }, + ], + }, + }, + schema: { + default_value: defaults.mode, + }, + }, + ], + load(props) { + return Focus.configure({ + mode: props.focusMode ?? defaults.mode, + }); + }, +}; + +export default extension; diff --git a/src/tiptap-editor.vue b/src/tiptap-editor.vue index 02bf295..65c7bb7 100644 --- a/src/tiptap-editor.vue +++ b/src/tiptap-editor.vue @@ -533,12 +533,18 @@ height: 0; pointer-events: none; } + + .has-focus { + border-radius: 3px; + //box-shadow: 0 0 6px 2px var(--background-subdued); + box-shadow: var(--card-shadow); + } } }