diff --git a/templates/content/app/components/editor/BubbleToolbar.test.tsx b/templates/content/app/components/editor/BubbleToolbar.test.tsx index 08ee68c75d..5deaa972d7 100644 --- a/templates/content/app/components/editor/BubbleToolbar.test.tsx +++ b/templates/content/app/components/editor/BubbleToolbar.test.tsx @@ -34,7 +34,15 @@ vi.mock("@/components/ui/tooltip", () => ({ TooltipTrigger: ({ children }: { children: ReactNode }) => children, })); -describe("BubbleToolbar link shortcut", () => { +vi.mock("@/components/ui/popover", () => ({ + Popover: ({ children }: { children: ReactNode }) => children, + PopoverTrigger: ({ children }: { children: ReactNode }) => children, + PopoverContent: ({ children }: { children: ReactNode }) => ( +
Selected heading
"); + expect(editor.getHTML()).not.toContain("Selected heading
"); + expect(editor.getHTML()).not.toContain( + `Selected heading
", + }); + editor.commands.setTextSelection({ from: 1, to: 9 }); + + root = createRoot(toolbarElement); + act(() => root!.render(Stable heading
"); + }); + + it("sets a heading from a pointer click", () => { + editorElement = document.createElement("div"); + toolbarElement = document.createElement("div"); + document.body.append(editorElement, toolbarElement); + editor = new Editor({ + element: editorElement, + extensions: [StarterKit], + content: "Selected paragraph
", + }); + editor.commands.setTextSelection({ from: 1, to: 9 }); + + root = createRoot(toolbarElement); + act(() => root!.render(Selected paragraph
"); + }); }); diff --git a/templates/content/app/components/editor/BubbleToolbar.tsx b/templates/content/app/components/editor/BubbleToolbar.tsx index 2cccf27e0f..2326beb9bd 100644 --- a/templates/content/app/components/editor/BubbleToolbar.tsx +++ b/templates/content/app/components/editor/BubbleToolbar.tsx @@ -1,15 +1,13 @@ import { useT } from "@agent-native/core/client/i18n"; import { IconBold, + IconCheck, + IconChevronDown, IconItalic, IconStrikethrough, IconCode, IconLink, IconMessageCircle, - IconH1, - IconH2, - IconH3, - IconH4, } from "@tabler/icons-react"; import { NodeSelection, @@ -20,8 +18,13 @@ import { import { Decoration, DecorationSet } from "@tiptap/pm/view"; import type { Editor } from "@tiptap/react"; import { BubbleMenu } from "@tiptap/react/menus"; -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; import { Tooltip, TooltipContent, @@ -56,6 +59,15 @@ type SelectionFillRange = { to: number; }; +type TextStyle = "paragraph" | 1 | 2 | 3 | 4 | 5 | 6; + +function activeTextStyle(editor: Editor): TextStyle { + for (const level of [1, 2, 3, 4, 5, 6] as const) { + if (editor.isActive("heading", { level })) return level; + } + return "paragraph"; +} + const selectionFillPluginKey = new PluginKey