From 4d76cd1838bb3cd1a2dbfd2e923f9ca7eba8a8ab Mon Sep 17 00:00:00 2001 From: Aditya Vaishnav Date: Tue, 22 Aug 2023 08:15:36 +0000 Subject: [PATCH] Text Align in bubble menu --- package.json | 1 + pnpm-lock.yaml | 11 +++ ui/editor/components/bubble-menu.tsx | 15 ++++ ui/editor/components/text-align-selector.tsx | 91 ++++++++++++++++++++ ui/editor/extensions/index.tsx | 4 + 5 files changed, 122 insertions(+) create mode 100644 ui/editor/components/text-align-selector.tsx diff --git a/package.json b/package.json index dc394c833..aa5c3c53f 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@tiptap/extension-placeholder": "2.0.3", "@tiptap/extension-task-item": "^2.0.4", "@tiptap/extension-task-list": "^2.0.4", + "@tiptap/extension-text-align": "^2.1.6", "@tiptap/extension-text-style": "^2.0.4", "@tiptap/extension-underline": "^2.0.4", "@tiptap/pm": "^2.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8693c99b8..0437b468d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,9 @@ dependencies: '@tiptap/extension-task-list': specifier: ^2.0.4 version: 2.0.4(@tiptap/core@2.0.4) + '@tiptap/extension-text-align': + specifier: ^2.1.6 + version: 2.1.6(@tiptap/core@2.0.4) '@tiptap/extension-text-style': specifier: ^2.0.4 version: 2.0.4(@tiptap/core@2.0.4) @@ -1316,6 +1319,14 @@ packages: '@tiptap/core': 2.0.4(@tiptap/pm@2.0.4) dev: false + /@tiptap/extension-text-align@2.1.6(@tiptap/core@2.0.4): + resolution: {integrity: sha512-YFgih5eStYlak9NoA6/zwNbWSx2YAdAWRzFwJ5UCrBPbb+ddAX3Ff8ql9PM29Xx2naQCsuM3og9ECek7wbCWpA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.0.4(@tiptap/pm@2.0.4) + dev: false + /@tiptap/extension-text-style@2.0.4(@tiptap/core@2.0.4): resolution: {integrity: sha512-HQk8c7HasDdeAJxlHrztkgprxocZecZVUMlvPvFAhkq8E/5+nfmr/Gm9qudiStEARZrIYBATNA2PbnQuIGMx3A==} peerDependencies: diff --git a/ui/editor/components/bubble-menu.tsx b/ui/editor/components/bubble-menu.tsx index 6e354a6a6..6477c1238 100644 --- a/ui/editor/components/bubble-menu.tsx +++ b/ui/editor/components/bubble-menu.tsx @@ -12,6 +12,7 @@ import { NodeSelector } from "./node-selector"; import { ColorSelector } from "./color-selector"; import { LinkSelector } from "./link-selector"; import { cn } from "@/lib/utils"; +import { TextAlignSelector } from "./text-align-selector"; export interface BubbleMenuItem { name: string; @@ -78,6 +79,7 @@ export const EditorBubbleMenu: FC = (props) => { const [isNodeSelectorOpen, setIsNodeSelectorOpen] = useState(false); const [isColorSelectorOpen, setIsColorSelectorOpen] = useState(false); const [isLinkSelectorOpen, setIsLinkSelectorOpen] = useState(false); + const [isTextAlignSelectorOpen, setIsTextAlignSelectorOpen] = useState(false); return ( = (props) => { setIsNodeSelectorOpen(!isNodeSelectorOpen); setIsColorSelectorOpen(false); setIsLinkSelectorOpen(false); + setIsTextAlignSelectorOpen(false); }} /> = (props) => { /> ))} + { + setIsTextAlignSelectorOpen(!isTextAlignSelectorOpen); + setIsColorSelectorOpen(false); + setIsNodeSelectorOpen(false); + setIsLinkSelectorOpen(false); + }} + /> + = (props) => { setIsColorSelectorOpen(!isColorSelectorOpen); setIsNodeSelectorOpen(false); setIsLinkSelectorOpen(false); + setIsTextAlignSelectorOpen(false); }} /> diff --git a/ui/editor/components/text-align-selector.tsx b/ui/editor/components/text-align-selector.tsx new file mode 100644 index 000000000..623ea86bf --- /dev/null +++ b/ui/editor/components/text-align-selector.tsx @@ -0,0 +1,91 @@ +import { Editor } from "@tiptap/core"; +import { + Check, + ChevronDown, + AlignLeft, + AlignCenter, + AlignRight, + AlignJustify, +} from "lucide-react"; +import { Dispatch, FC, SetStateAction } from "react"; + +import { BubbleMenuItem } from "./bubble-menu"; + +interface TextAlignSelectorProps { + editor: Editor; + isOpen: boolean; + setIsOpen: Dispatch>; +} + +export const TextAlignSelector: FC = ({ + editor, + isOpen, + setIsOpen, +}) => { + const items: BubbleMenuItem[] = [ + { + name: "Align Left", + icon: AlignLeft, + command: () => editor.chain().focus().setTextAlign("left").run(), + isActive: () => editor.isActive({ textAlign: "left" }), + }, + { + name: "Align Center", + icon: AlignCenter, + command: () => editor.chain().focus().setTextAlign("center").run(), + isActive: () => editor.isActive({ textAlign: "center" }), + }, + { + name: "Align Right", + icon: AlignRight, + command: () => editor.chain().focus().setTextAlign("right").run(), + isActive: () => editor.isActive({ textAlign: "right" }), + }, + { + name: "Align Justify", + icon: AlignJustify, + command: () => editor.chain().focus().setTextAlign("justify").run(), + isActive: () => editor.isActive({ textAlign: "justify" }), + }, + ]; + + const activeItem = items.filter((item) => item.isActive()).pop(); + + return ( +
+ + + {isOpen && ( +
+ {items.map((item, index) => ( + + ))} +
+ )} +
+ ); +}; diff --git a/ui/editor/extensions/index.tsx b/ui/editor/extensions/index.tsx index 6b48700a1..9391d0b00 100644 --- a/ui/editor/extensions/index.tsx +++ b/ui/editor/extensions/index.tsx @@ -14,6 +14,7 @@ import SlashCommand from "./slash-command"; import { InputRule } from "@tiptap/core"; import UploadImagesPlugin from "@/ui/editor/plugins/upload-images"; import UpdatedImage from "./updated-image"; +import TextAlign from "@tiptap/extension-text-align"; const CustomImage = TiptapImage.extend({ addProseMirrorPlugins() { @@ -137,4 +138,7 @@ export const TiptapExtensions = [ html: false, transformCopiedText: true, }), + TextAlign.configure({ + types: ["heading", "paragraph"], + }), ];