@firecms/editor 3.0.0-canary.8 → 3.0.0-canary.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/components/editor.tsx","../src/components/editor-bubble.tsx","../src/components/editor-bubble-item.tsx","../src/components/editor-command.tsx","../src/components/editor-command-item.tsx","../src/extensions/slash-command.tsx","../src/extensions/index.ts","../src/selectors/node-selector.tsx","../src/selectors/link-selector.tsx","../src/selectors/text-buttons.tsx","../src/utils/useDebouncedCallback.ts","../src/utils/remove_classes.ts","../src/editor_extensions.tsx","../src/extensions/Image.ts","../src/extensions/custom-keymap.ts","../src/extensions/drag-and-drop.tsx","../src/editor.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { createStore, Provider } from \"jotai\";\n\nexport const editorStore = createStore();\n\nexport const EditorRoot = ({ children }: { children: ReactNode }): JSX.Element => {\n return <Provider store={editorStore}>{children}</Provider>;\n};\n","import { BubbleMenu, type BubbleMenuProps, isNodeSelection, useCurrentEditor } from \"@tiptap/react\";\nimport { type ReactNode, useMemo, useRef, useEffect, forwardRef } from \"react\";\nimport type { Instance, Props } from \"tippy.js\";\n\nexport interface EditorBubbleProps extends Omit<BubbleMenuProps, \"editor\"> {\n children: ReactNode;\n}\n\nexport const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(\n ({ children, tippyOptions, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const instanceRef = useRef<Instance<Props> | null>(null);\n\n useEffect(() => {\n if (!instanceRef.current || !tippyOptions?.placement) return;\n\n instanceRef.current.setProps({ placement: tippyOptions.placement });\n instanceRef.current.popperInstance?.update();\n }, [tippyOptions?.placement]);\n\n const bubbleMenuProps: Omit<BubbleMenuProps, \"children\"> = useMemo(() => {\n const shouldShow: BubbleMenuProps[\"shouldShow\"] = ({ editor, state }) => {\n const { selection } = state;\n const { empty } = selection;\n\n // don't show bubble menu if:\n // - the selected node is an image\n // - the selection is empty\n // - the selection is a node selection (for drag handles)\n if (editor.isActive(\"image\") || empty || isNodeSelection(selection)) {\n return false;\n }\n return true;\n };\n\n return {\n shouldShow,\n tippyOptions: {\n onCreate: (val) => {\n instanceRef.current = val;\n },\n moveTransition: \"transform 0.15s ease-out\",\n ...tippyOptions,\n },\n ...rest,\n };\n }, [rest, tippyOptions]);\n\n if (!editor) return null;\n\n return (\n //We need to add this because of https://github.com/ueberdosis/tiptap/issues/2658\n <div ref={ref}>\n <BubbleMenu editor={editor} {...bubbleMenuProps}>\n {children}\n </BubbleMenu>\n </div>\n );\n }\n);\n\nexport default EditorBubble;\n","import { type ComponentPropsWithoutRef, type ReactNode, forwardRef } from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useCurrentEditor, type Editor } from \"@tiptap/react\";\n\ninterface EditorBubbleItemProps {\n children: ReactNode;\n asChild?: boolean;\n onSelect?: (editor: Editor) => void;\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const Comp = asChild ? Slot : \"div\";\n\n if (!editor) return null;\n\n return (\n <Comp ref={ref} {...rest} onClick={() => onSelect?.(editor)}>\n {children}\n </Comp>\n );\n});\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\";\n\nexport default EditorBubbleItem;\n","import { atom, useAtom, useSetAtom } from \"jotai\";\nimport { useEffect, useRef, type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport tunnel from \"tunnel-rat\";\nimport { editorStore } from \"./editor\";\nimport { Command } from \"cmdk\";\nimport type { Range } from \"@tiptap/core\";\n\nconst t = tunnel();\n\nexport const queryAtom = atom(\"\");\nexport const rangeAtom = atom<Range | null>(null);\n\nexport const EditorCommandOut = ({\n query,\n range,\n}: {\n query: string;\n range: Range;\n}): JSX.Element => {\n const setQuery = useSetAtom(queryAtom, { store: editorStore });\n const setRange = useSetAtom(rangeAtom, { store: editorStore });\n\n useEffect(() => {\n setQuery(query);\n }, [query, setQuery]);\n\n useEffect(() => {\n setRange(range);\n }, [range, setRange]);\n\n useEffect(() => {\n const navigationKeys = [\"ArrowUp\", \"ArrowDown\", \"Enter\"];\n const onKeyDown = (e: KeyboardEvent) => {\n if (navigationKeys.includes(e.key)) {\n e.preventDefault();\n const commandRef = document.querySelector(\"#slash-command\");\n\n if (commandRef)\n commandRef.dispatchEvent(\n new KeyboardEvent(\"keydown\", { key: e.key, cancelable: true, bubbles: true })\n );\n\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, []);\n\n return <t.Out />;\n};\n\nexport const EditorCommand = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<typeof Command>>(\n ({ children, className, ...rest }, ref) => {\n const commandListRef = useRef<HTMLDivElement>(null);\n const [query, setQuery] = useAtom(queryAtom);\n\n return (\n <t.In>\n <Command\n ref={ref}\n onKeyDown={(e) => {\n e.stopPropagation();\n }}\n id='slash-command'\n className={className}\n {...rest}>\n <Command.Input value={query} onValueChange={setQuery} style={{ display: \"none\" }} />\n <Command.List ref={commandListRef}>{children}</Command.List>\n </Command>\n </t.In>\n );\n }\n);\n","import { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { CommandEmpty, CommandItem } from \"cmdk\";\nimport { Editor, type Range } from \"@tiptap/core\";\nimport { useCurrentEditor } from \"@tiptap/react\";\nimport { useAtomValue } from \"jotai\";\nimport { rangeAtom } from \"./editor-command\";\n\ninterface EditorCommandItemProps {\n onCommand: ({ editor, range }: { editor: Editor; range: Range }) => void;\n}\n\nexport const EditorCommandItem = forwardRef<\n HTMLDivElement,\n EditorCommandItemProps & ComponentPropsWithoutRef<typeof CommandItem>\n>(({ children, onCommand, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const range = useAtomValue(rangeAtom);\n\n if (!editor || !range) return null;\n\n return (\n <CommandItem ref={ref} {...rest} onSelect={() => onCommand({ editor, range })}>\n {children}\n </CommandItem>\n );\n});\n\nEditorCommandItem.displayName = \"EditorCommandItem\";\n\nexport const EditorCommandEmpty = CommandEmpty;\n\nexport default EditorCommandItem;\n","import { type Editor, type Range, Extension } from \"@tiptap/core\";\nimport Suggestion from \"@tiptap/suggestion\";\nimport { ReactRenderer } from \"@tiptap/react\";\nimport tippy from \"tippy.js\";\n\nimport { EditorCommandOut } from \"../components/editor-command\";\nimport type { ReactNode } from \"react\";\n\nconst Command = Extension.create({\n name: \"slash-command\",\n addOptions() {\n return {\n suggestion: {\n char: \"/\",\n command: ({ editor, range, props }: { editor: Editor; range: Range; props: any }) => {\n props.command({ editor, range });\n },\n },\n };\n },\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ];\n },\n});\n\nconst renderItems = () => {\n let component: ReactRenderer | null = null;\n let popup: any | null = null;\n\n return {\n onStart: (props: { editor: Editor; clientRect: DOMRect }) => {\n component = new ReactRenderer(EditorCommandOut, {\n props,\n editor: props.editor,\n });\n\n // @ts-ignore\n popup = tippy(\"body\", {\n getReferenceClientRect: props.clientRect,\n appendTo: () => document.body,\n content: component.element,\n showOnCreate: true,\n interactive: true,\n trigger: \"manual\",\n placement: \"bottom-start\",\n });\n },\n onUpdate: (props: { editor: Editor; clientRect: DOMRect }) => {\n component?.updateProps(props);\n\n popup &&\n popup[0].setProps({\n getReferenceClientRect: props.clientRect,\n });\n },\n\n onKeyDown: (props: { event: KeyboardEvent }) => {\n if (props.event.key === \"Escape\") {\n popup?.[0].hide();\n\n return true;\n }\n\n // @ts-ignore\n return component?.ref?.onKeyDown(props);\n },\n onExit: () => {\n popup?.[0].destroy();\n component?.destroy();\n },\n };\n};\n\nexport interface SuggestionItem {\n title: string;\n description: string;\n icon: ReactNode;\n searchTerms?: string[];\n command?: (props: { editor: Editor; range: Range }) => void;\n}\n\nexport const createSuggestionItems = (items: SuggestionItem[]) => items;\n\nexport { Command, renderItems };\n","import StarterKit from \"@tiptap/starter-kit\";\nimport HorizontalRule from \"@tiptap/extension-horizontal-rule\";\nimport TiptapLink from \"@tiptap/extension-link\";\nimport TiptapImage from \"@tiptap/extension-image\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\n\nimport { TaskItem } from \"@tiptap/extension-task-item\";\nimport { TaskList } from \"@tiptap/extension-task-list\";\nimport { InputRule } from \"@tiptap/core\";\n\nconst PlaceholderExtension = Placeholder.configure({\n placeholder: ({ node }) => {\n if (node.type.name === \"heading\") {\n return `Heading ${node.attrs.level}`;\n }\n return \"Press '/' for commands\";\n },\n includeChildren: true,\n});\n\nconst Horizontal = HorizontalRule.extend({\n addInputRules() {\n return [\n new InputRule({\n find: /^(?:---|—-|___\\s|\\*\\*\\*\\s)$/,\n handler: ({ state, range }) => {\n const attributes = {};\n\n const { tr } = state;\n const start = range.from;\n const end = range.to;\n\n tr.insert(start - 1, this.type.create(attributes)).delete(\n tr.mapping.map(start),\n tr.mapping.map(end)\n );\n },\n }),\n ];\n },\n});\n\nexport {\n PlaceholderExtension as Placeholder,\n StarterKit,\n Horizontal as HorizontalRule,\n TiptapLink,\n TiptapImage,\n TaskItem,\n TaskList,\n InputRule,\n};\nexport * from \"./slash-command\";\n\nexport { getPrevText } from \"../utils/utils\";\n","import React from \"react\";\nimport { EditorBubbleItem, useEditor } from \"../components\";\n\nimport {\n Button,\n CheckBoxIcon,\n CheckIcon,\n CodeIcon,\n ExpandMoreIcon,\n FormatListBulletedIcon,\n FormatListNumberedIcon,\n FormatQuoteIcon,\n Looks3Icon,\n LooksOneIcon,\n LooksTwoIcon,\n Popover,\n TextFieldsIcon\n} from \"@firecms/ui\";\n\nexport type SelectorItem = {\n name: string;\n icon: React.ElementType;\n command: (editor: ReturnType<typeof useEditor>[\"editor\"]) => void;\n isActive: (editor: ReturnType<typeof useEditor>[\"editor\"]) => boolean;\n};\n\nconst items: SelectorItem[] = [\n {\n name: \"Text\",\n icon: TextFieldsIcon,\n command: (editor) =>\n editor?.chain().focus().toggleNode(\"paragraph\", \"paragraph\").run(),\n // I feel like there has to be a more efficient way to do this – feel free to PR if you know how!\n isActive: (editor) =>\n (editor?.isActive(\"paragraph\") &&\n !editor?.isActive(\"bulletList\") &&\n !editor?.isActive(\"orderedList\")) ?? false,\n },\n {\n name: \"Heading 1\",\n icon: LooksOneIcon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 1 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 1 }) ?? false,\n },\n {\n name: \"Heading 2\",\n icon: LooksTwoIcon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 2 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 2 }) ?? false,\n },\n {\n name: \"Heading 3\",\n icon: Looks3Icon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 3 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 3 }) ?? false,\n },\n {\n name: \"To-do List\",\n icon: CheckBoxIcon,\n command: (editor) => editor?.chain().focus().toggleTaskList().run(),\n isActive: (editor) => editor?.isActive(\"taskItem\") ?? false,\n },\n {\n name: \"Bullet List\",\n icon: FormatListBulletedIcon,\n command: (editor) => editor?.chain().focus().toggleBulletList().run(),\n isActive: (editor) => editor?.isActive(\"bulletList\") ?? false,\n },\n {\n name: \"Numbered List\",\n icon: FormatListNumberedIcon,\n command: (editor) => editor?.chain().focus().toggleOrderedList().run(),\n isActive: (editor) => editor?.isActive(\"orderedList\") ?? false,\n },\n {\n name: \"Quote\",\n icon: FormatQuoteIcon,\n command: (editor) => editor?.chain()\n .focus()\n .toggleNode(\"paragraph\", \"paragraph\")\n .toggleBlockquote()\n .run(),\n isActive: (editor) => editor?.isActive(\"blockquote\") ?? false,\n },\n {\n name: \"Code\",\n icon: CodeIcon,\n command: (editor) => editor?.chain().focus().toggleCodeBlock().run(),\n isActive: (editor) => editor?.isActive(\"codeBlock\") ?? false,\n },\n];\n\ninterface NodeSelectorProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport const NodeSelector = ({\n open,\n onOpenChange\n }: NodeSelectorProps) => {\n const { editor } = useEditor();\n if (!editor) return null;\n const activeItem = items.filter((item) => item.isActive(editor)).pop() ?? {\n name: \"Multiple\",\n };\n\n return (\n\n <Popover\n sideOffset={5}\n align=\"start\"\n className=\"w-48 p-1\"\n trigger={<Button variant=\"text\"\n className=\"gap-2 rounded-none\"\n color=\"text\">\n <span className=\"whitespace-nowrap text-sm\">{activeItem.name}</span>\n <ExpandMoreIcon size={\"small\"}/>\n </Button>}\n modal={true}\n open={open}\n onOpenChange={onOpenChange}>\n {items.map((item, index) => (\n <EditorBubbleItem\n key={index}\n onSelect={(editor) => {\n item.command(editor);\n onOpenChange(false);\n }}\n className=\"flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-gray-700 text-gray-900 dark:text-white\"\n >\n <div className=\"flex items-center space-x-2\">\n <item.icon size=\"smallest\"/>\n <span>{item.name}</span>\n </div>\n {activeItem.name === item.name && <CheckIcon size=\"smallest\"/>}\n </EditorBubbleItem>\n ))}\n\n </Popover>\n );\n};\n","import { useEditor } from \"../components\";\nimport { useEffect, useRef, } from \"react\";\nimport { Button, CheckIcon, cn, DeleteIcon, Popover } from \"@firecms/ui\";\n\nexport function isValidUrl(url: string) {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch (e) {\n return false;\n }\n}\n\nexport function getUrlFromString(str: string) {\n if (isValidUrl(str)) return str;\n try {\n if (str.includes(\".\") && !str.includes(\" \")) {\n return new URL(`https://${str}`).toString();\n }\n return null;\n } catch (e) {\n return null;\n }\n}\n\ninterface LinkSelectorProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport const LinkSelector = ({\n open,\n onOpenChange\n }: LinkSelectorProps) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const { editor } = useEditor();\n\n // Autofocus on input by default\n useEffect(() => {\n inputRef.current && inputRef.current?.focus();\n });\n\n if (!editor) return null;\n\n return (\n <Popover modal={true}\n open={open}\n onOpenChange={onOpenChange}\n trigger={<Button variant=\"text\"\n className=\"gap-2 rounded-none\"\n color={\"text\"}>\n <p className={cn(\"underline decoration-stone-400 underline-offset-4\", {\n \"text-blue-500\": editor.isActive(\"link\"),\n })}>\n Link\n </p>\n </Button>}>\n <form\n onSubmit={(e) => {\n const target = e.currentTarget as HTMLFormElement;\n e.preventDefault();\n const input = target[0] as HTMLInputElement;\n const url = getUrlFromString(input.value);\n url && editor.chain().focus().setLink({ href: url }).run();\n }}\n className=\"flex p-1\"\n >\n <input\n ref={inputRef}\n autoFocus={open}\n placeholder=\"Paste a link\"\n defaultValue={editor.getAttributes(\"link\").href || \"\"}\n className={\"text-gray-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none\"}/>\n\n {editor.getAttributes(\"link\").href ? (\n <Button\n size={\"small\"}\n variant=\"text\"\n type=\"button\"\n color={\"text\"}\n className=\"flex items-center\"\n onClick={() => {\n editor.chain().focus().unsetLink().run();\n }}\n >\n <DeleteIcon size=\"small\"/>\n </Button>\n ) : (\n <Button size={\"small\"}\n variant={\"text\"}>\n <CheckIcon size=\"small\"/>\n </Button>\n )}\n </form>\n </Popover>\n );\n};\n","import { EditorBubbleItem, useEditor } from \"../components\";\nimport type { SelectorItem } from \"./node-selector\";\nimport {\n Button,\n cn,\n CodeIcon,\n FormatBoldIcon,\n FormatItalicIcon,\n FormatStrikethroughIcon,\n FormatUnderlinedIcon\n} from \"@firecms/ui\";\n\nexport const TextButtons = () => {\n const { editor } = useEditor();\n if (!editor) return null;\n const items: SelectorItem[] = [\n {\n name: \"bold\",\n isActive: (editor) => editor?.isActive(\"bold\") ?? false,\n command: (editor) => editor?.chain().focus().toggleBold().run(),\n icon: FormatBoldIcon,\n },\n {\n name: \"italic\",\n isActive: (editor) => editor?.isActive(\"italic\") ?? false,\n command: (editor) => editor?.chain().focus().toggleItalic().run(),\n icon: FormatItalicIcon,\n },\n {\n name: \"underline\",\n isActive: (editor) => editor?.isActive(\"underline\") ?? false,\n command: (editor) => editor?.chain().focus().toggleUnderline().run(),\n icon: FormatUnderlinedIcon,\n },\n {\n name: \"strike\",\n isActive: (editor) => editor?.isActive(\"strike\") ?? false,\n command: (editor) => editor?.chain().focus().toggleStrike().run(),\n icon: FormatStrikethroughIcon,\n },\n {\n name: \"code\",\n isActive: (editor) => editor?.isActive(\"code\") ?? false,\n command: (editor) => editor?.chain().focus().toggleCode().run(),\n icon: CodeIcon,\n },\n ];\n return (\n <div className=\"flex\">\n {items.map((item, index) => (\n <EditorBubbleItem\n key={index}\n onSelect={(editor) => {\n item.command(editor);\n }}\n >\n <Button size={\"small\"}\n color=\"text\"\n className=\"gap-2 rounded-none h-full\"\n variant=\"text\">\n <item.icon\n className={cn( {\n \"text-inherit\": !item.isActive(editor),\n \"text-blue-500\": item.isActive(editor),\n })}\n />\n </Button>\n </EditorBubbleItem>\n ))}\n </div>\n );\n};\n","import React from \"react\";\n\nexport function useDebouncedCallback<T>(value: T, callback: () => void, immediate: boolean, timeoutMs = 300) {\n\n const pendingUpdate = React.useRef(false);\n const performUpdate = () => {\n callback();\n pendingUpdate.current = false;\n };\n\n const handlerRef = React.useRef<number | undefined>(undefined);\n\n React.useEffect(\n () => {\n pendingUpdate.current = true;\n clearTimeout(handlerRef.current);\n handlerRef.current = setTimeout(performUpdate, timeoutMs) as any;\n return () => {\n if (immediate)\n performUpdate();\n };\n },\n [immediate, value]\n );\n}\n","export function removeClassesFromJson(jsonObj: any): any {\n // If it's an array, apply the function to each element\n if (Array.isArray(jsonObj)) {\n return jsonObj.map(item => removeClassesFromJson(item));\n } else if (typeof jsonObj === \"object\" && jsonObj !== null) { // If it's an object, recurse through its properties\n // If the object has an `attrs` property and `class` field, delete the `class` field\n if (jsonObj.attrs && typeof jsonObj.attrs === \"object\" && \"class\" in jsonObj.attrs) {\n delete jsonObj.attrs.class;\n }\n\n // Apply the function recursively to object properties\n Object.keys(jsonObj).forEach(key => {\n jsonObj[key] = removeClassesFromJson(jsonObj[key]);\n });\n }\n return jsonObj;\n}\n","import { HorizontalRule, Placeholder, StarterKit, TaskItem, TaskList, TiptapImage, TiptapLink, } from \"./extensions\";\n\nimport { cn, defaultBorderMixin } from \"@firecms/ui\";\n\n//You can overwrite the placeholder with your own configuration\nexport const placeholder = Placeholder;\nexport const tiptapLink = TiptapLink.configure({\n HTMLAttributes: {\n class: cn(\n \"text-gray-600 dark:text-slate-300 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer\",\n ),\n },\n});\n\n// export const tiptapImage = TiptapImage.extend({\n// addProseMirrorPlugins() {\n// return [UploadImagesPlugin()];\n// },\n// }).configure({\n// allowBase64: true,\n// HTMLAttributes: {\n// class: cn(\"rounded-lg border\", defaultBorderMixin),\n// },\n// });\n\n// const updatedImage = UpdatedImage.configure({\n// HTMLAttributes: {\n// class: cn(\"rounded-lg border\", defaultBorderMixin),\n// },\n// });\n\nexport const taskList = TaskList.configure({\n HTMLAttributes: {\n class: cn(\"not-prose\"),\n },\n});\nexport const taskItem = TaskItem.configure({\n HTMLAttributes: {\n class: cn(\"flex items-start my-4\"),\n },\n nested: true,\n});\n\nexport const horizontalRule = HorizontalRule.configure({\n HTMLAttributes: {\n class: cn(\"mt-4 mb-6 border-t\", defaultBorderMixin),\n },\n});\n\nexport const starterKit = StarterKit.configure({\n bulletList: {\n HTMLAttributes: {\n class: cn(\"list-disc list-outside leading-3 -mt-2\"),\n },\n },\n orderedList: {\n HTMLAttributes: {\n class: cn(\"list-decimal list-outside leading-3 -mt-2\"),\n },\n },\n listItem: {\n HTMLAttributes: {\n class: cn(\"leading-normal -mb-2\"),\n },\n },\n blockquote: {\n HTMLAttributes: {\n class: cn(\"border-l-4 border-primary\"),\n },\n },\n codeBlock: {\n HTMLAttributes: {\n class: cn(\"rounded bg-blue-50 dark:bg-gray-700 border p-5 font-mono font-medium\", defaultBorderMixin),\n },\n },\n code: {\n HTMLAttributes: {\n class: cn(\"rounded-md bg-slate-50 dark:bg-gray-700 px-1.5 py-1 font-mono font-medium\"),\n spellcheck: \"false\",\n },\n },\n horizontalRule: false,\n dropcursor: {\n color: \"#DBEAFE\",\n width: 4,\n },\n gapcursor: false,\n});\n","import { Plugin, } from \"prosemirror-state\";\nimport { TiptapImage } from \"./index\";\nimport { cn, defaultBorderMixin } from \"@firecms/ui\";\nimport { Decoration, DecorationSet, EditorView } from \"@tiptap/pm/view\";\n\nexport type UploadFn = (image: File) => Promise<string>;\n\nasync function onFileRead(plugin: Plugin, view: EditorView, readerEvent: ProgressEvent<FileReader>, pos: number, upload: UploadFn, image: File) {\n\n const { schema } = view.state;\n let decorationSet = plugin.getState(view.state);\n\n const placeholder = document.createElement(\"div\");\n const imageElement = document.createElement(\"img\");\n imageElement.setAttribute(\"class\", \"opacity-40 rounded-lg border border-stone-200\");\n imageElement.src = readerEvent.target?.result as string;\n placeholder.appendChild(imageElement);\n\n const deco = Decoration.widget(pos, placeholder);\n decorationSet = decorationSet?.add(view.state.doc, [deco]);\n view.dispatch(view.state.tr.setMeta(plugin, { decorationSet }));\n\n // Image Upload Logic\n const src = await upload(image);\n console.log(\"uploaded image\", src);\n\n // Replace placeholder with actual image\n const imageNode = schema.nodes.image.create({ src });\n const tr = view.state.tr.replaceWith(pos, pos, imageNode);\n\n // Remove placeholder decoration\n decorationSet = decorationSet?.remove([deco]);\n tr.setMeta(plugin, { decorationSet });\n view.dispatch(tr);\n}\n\nexport const dropImagePlugin = (upload: UploadFn) => {\n const plugin: Plugin = new Plugin({\n state: {\n // Initialize the plugin state with an empty DecorationSet\n init: () => DecorationSet.empty,\n // Apply transactions to update the state\n apply: (tr, old) => {\n // Handle custom transaction steps that update decorations\n const meta = tr.getMeta(plugin);\n if (meta && meta.decorationSet) {\n return meta.decorationSet;\n }\n // Map decorations to the new document structure\n return old.map(tr.mapping, tr.doc);\n }\n },\n props: {\n handleDOMEvents: {\n drop: (view, event) => {\n console.log(\"drop event\", event)\n if (!event.dataTransfer?.files || event.dataTransfer?.files.length === 0) {\n return false;\n }\n event.preventDefault();\n\n const files = Array.from(event.dataTransfer.files);\n const images = files.filter(file => /image/i.test(file.type));\n\n if (images.length === 0) return false;\n\n images.forEach(image => {\n\n const position = view.posAtCoords({ left: event.clientX, top: event.clientY });\n if (!position) return;\n\n const reader = new FileReader();\n reader.onload = async (readerEvent) => {\n await onFileRead(plugin, view, readerEvent, position.pos, upload, image);\n };\n reader.readAsDataURL(image);\n });\n\n return true;\n }\n },\n handlePaste(view, event, slice) {\n const items = Array.from(event.clipboardData?.items || []);\n const pos = view.state.selection.from;\n console.log(\"pos\", pos)\n let anyImageFound = false;\n\n items.forEach((item) => {\n const image = item.getAsFile();\n console.log(\"image\", image);\n if (image) {\n anyImageFound = true;\n // if (item.type.indexOf(\"image\") === 0) {\n // event.preventDefault();\n //\n // if (upload && image) {\n // upload(image).then((src) => {\n // const node = schema.nodes.image.create({\n // src\n // });\n // const transaction = view.state.tr.replaceSelectionWith(node);\n // view.dispatch(transaction);\n // });\n // }\n // } else {\n const reader = new FileReader();\n\n reader.onload = async (readerEvent) => {\n await onFileRead(plugin, view, readerEvent, pos, upload, image);\n };\n reader.readAsDataURL(image);\n }\n });\n\n return anyImageFound;\n },\n decorations(state) {\n return plugin.getState(state);\n }\n },\n view(editorView) {\n // This is needed to immediately apply the decoration updates\n return {\n update(view, prevState) {\n const prevDecos = plugin.getState(prevState);\n const newDecos = plugin.getState(view.state);\n\n if (prevDecos !== newDecos) {\n view.updateState(view.state);\n }\n }\n };\n }\n });\n return plugin;\n};\n\n/**\n * Matches following attributes in Markdown-typed image: [, alt, src, title]\n *\n * Example:\n * ![Lorem](image.jpg) -> [, \"Lorem\", \"image.jpg\"]\n * ![](image.jpg \"Ipsum\") -> [, \"\", \"image.jpg\", \"Ipsum\"]\n * ![Lorem](image.jpg \"Ipsum\") -> [, \"Lorem\", \"image.jpg\", \"Ipsum\"]\n */\nconst IMAGE_INPUT_REGEX = /!\\[(.+|:?)\\]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\)/;\n\nexport const createImageExtension = (uploadFn: UploadFn) => {\n return TiptapImage.extend({\n addProseMirrorPlugins() {\n return [dropImagePlugin(uploadFn)];\n }\n }).configure({\n allowBase64: true,\n HTMLAttributes: {\n class: cn(\"rounded-lg border\", defaultBorderMixin)\n }\n });\n};\n","import { Extension } from \"@tiptap/core\";\n\ndeclare module \"@tiptap/core\" {\n // eslint-disable-next-line no-unused-vars\n interface Commands<ReturnType> {\n customkeymap: {\n /**\n * Select text between node boundaries\n */\n selectTextWithinNodeBoundaries: () => ReturnType;\n };\n }\n}\n\nexport const CustomKeymap = Extension.create({\n name: \"CustomKeymap\",\n\n addCommands() {\n return {\n selectTextWithinNodeBoundaries:\n () =>\n ({ editor, commands }) => {\n const { state } = editor;\n const { tr } = state;\n const startNodePos = tr.selection.$from.start();\n const endNodePos = tr.selection.$to.end();\n return commands.setTextSelection({\n from: startNodePos,\n to: endNodePos,\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-a\": ({ editor }) => {\n const { state } = editor;\n const { tr } = state;\n const startSelectionPos = tr.selection.from;\n const endSelectionPos = tr.selection.to;\n const startNodePos = tr.selection.$from.start();\n const endNodePos = tr.selection.$to.end();\n const isCurrentTextSelectionNotExtendedToNodeBoundaries =\n startSelectionPos > startNodePos || endSelectionPos < endNodePos;\n if (isCurrentTextSelectionNotExtendedToNodeBoundaries) {\n editor.chain().selectTextWithinNodeBoundaries().run();\n return true;\n }\n return false;\n },\n };\n },\n});\n\n","import { Extension } from \"@tiptap/core\";\n\nimport { NodeSelection, Plugin } from \"@tiptap/pm/state\";\n// @ts-ignore\nimport { __serializeForClipboard, EditorView } from \"@tiptap/pm/view\";\n\nexport interface DragHandleOptions {\n /**\n * The width of the drag handle\n */\n dragHandleWidth: number;\n}\nfunction absoluteRect(node: Element) {\n const data = node.getBoundingClientRect();\n\n return {\n top: data.top,\n left: data.left,\n width: data.width,\n };\n}\n\nfunction nodeDOMAtCoords(coords: { x: number; y: number }) {\n return document\n .elementsFromPoint(coords.x, coords.y)\n .find(\n (elem: Element) =>\n elem.parentElement?.matches?.(\".ProseMirror\") ||\n elem.matches(\n [\"li\", \"p:not(:first-child)\", \"pre\", \"blockquote\", \"h1, h2, h3, h4, h5, h6\"].join(\", \")\n )\n );\n}\n\nfunction nodePosAtDOM(node: Element, view: EditorView, options: DragHandleOptions) {\n const boundingRect = node.getBoundingClientRect();\n\n return view.posAtCoords({\n left: boundingRect.left + 50 + options.dragHandleWidth,\n top: boundingRect.top + 1,\n })?.inside;\n}\n\nfunction DragHandle(options: DragHandleOptions) {\n function handleDragStart(event: DragEvent, view: EditorView) {\n view.focus();\n\n if (!event.dataTransfer) return;\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) return;\n\n const nodePos = nodePosAtDOM(node, view, options);\n if (nodePos == null || nodePos < 0) return;\n\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));\n\n const slice = view.state.selection.content();\n const { dom, text } = __serializeForClipboard(view, slice);\n\n event.dataTransfer.clearData();\n event.dataTransfer.setData(\"text/html\", dom.innerHTML);\n event.dataTransfer.setData(\"text/plain\", text);\n event.dataTransfer.effectAllowed = \"copyMove\";\n\n event.dataTransfer.setDragImage(node, 0, 0);\n\n view.dragging = { slice, move: event.ctrlKey };\n }\n\n function handleClick(event: MouseEvent, view: EditorView) {\n view.focus();\n\n view.dom.classList.remove(\"dragging\");\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) return;\n\n const nodePos = nodePosAtDOM(node, view, options);\n if (!nodePos) return;\n\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));\n }\n\n let dragHandleElement: HTMLElement | null = null;\n\n function hideDragHandle() {\n if (dragHandleElement) {\n dragHandleElement.classList.add(\"hide\");\n }\n }\n\n function showDragHandle() {\n if (dragHandleElement) {\n dragHandleElement.classList.remove(\"hide\");\n }\n }\n\n return new Plugin({\n view: (view) => {\n dragHandleElement = document.createElement(\"div\");\n dragHandleElement.draggable = true;\n dragHandleElement.dataset.dragHandle = \"\";\n dragHandleElement.classList.add(\"drag-handle\");\n dragHandleElement.addEventListener(\"dragstart\", (e) => {\n handleDragStart(e, view);\n });\n dragHandleElement.addEventListener(\"click\", (e) => {\n handleClick(e, view);\n });\n\n hideDragHandle();\n\n view?.dom?.parentElement?.appendChild(dragHandleElement);\n\n return {\n destroy: () => {\n dragHandleElement?.remove?.();\n dragHandleElement = null;\n },\n };\n },\n props: {\n handleDOMEvents: {\n mousemove: (view, event) => {\n if (!view.editable) {\n return;\n }\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) {\n hideDragHandle();\n return;\n }\n\n const compStyle = window.getComputedStyle(node);\n const lineHeight = parseInt(compStyle.lineHeight, 10);\n const paddingTop = parseInt(compStyle.paddingTop, 10);\n\n const rect = absoluteRect(node);\n\n rect.top += (lineHeight - 24) / 2;\n rect.top += paddingTop;\n // Li markers\n if (node.matches(\"ul:not([data-type=taskList]) li, ol li\")) {\n rect.left -= options.dragHandleWidth;\n }\n rect.width = options.dragHandleWidth;\n\n if (!dragHandleElement) return;\n\n dragHandleElement.style.left = `${rect.left - rect.width}px`;\n dragHandleElement.style.top = `${rect.top}px`;\n showDragHandle();\n },\n keydown: () => {\n hideDragHandle();\n },\n mousewheel: () => {\n hideDragHandle();\n },\n // dragging class is used for CSS\n dragstart: (view) => {\n view.dom.classList.add(\"dragging\");\n },\n drop: (view) => {\n view.dom.classList.remove(\"dragging\");\n },\n dragend: (view) => {\n view.dom.classList.remove(\"dragging\");\n },\n },\n },\n });\n}\n\nexport const DragAndDrop = Extension.create({\n name: \"dragAndDrop\",\n\n addProseMirrorPlugins() {\n return [\n DragHandle({\n dragHandleWidth: 24,\n }),\n ];\n },\n});\n\n","\"use client\";\nimport React, { useMemo, useState } from \"react\";\n\nimport TiptapUnderline from \"@tiptap/extension-underline\";\nimport TextStyle from \"@tiptap/extension-text-style\";\nimport { Color } from \"@tiptap/extension-color\";\n\nimport { Markdown } from \"tiptap-markdown\";\nimport Highlight from \"@tiptap/extension-highlight\";\n\nimport {\n EditorBubble,\n EditorCommand,\n EditorCommandEmpty,\n EditorCommandItem,\n EditorRoot,\n type JSONContent\n} from \"./components\";\nimport { Command, createSuggestionItems, renderItems } from \"./extensions\";\n\nimport { NodeSelector } from \"./selectors/node-selector\";\nimport { LinkSelector } from \"./selectors/link-selector\";\nimport { TextButtons } from \"./selectors/text-buttons\";\n\nimport {\n CheckBoxIcon,\n cn,\n CodeIcon,\n defaultBorderMixin,\n FormatListBulletedIcon,\n FormatListNumberedIcon,\n FormatQuoteIcon,\n ImageIcon,\n Looks3Icon,\n LooksOneIcon,\n LooksTwoIcon,\n Separator,\n TextFieldsIcon,\n useInjectStyles\n} from \"@firecms/ui\";\n// import { startImageUpload } from \"./plugins\";\nimport { Editor, EditorProvider, EditorProviderProps } from \"@tiptap/react\";\nimport { useDebouncedCallback } from \"./utils/useDebouncedCallback\";\nimport { removeClassesFromJson } from \"./utils/remove_classes\";\nimport { horizontalRule, placeholder, starterKit, taskItem, taskList, tiptapLink } from \"./editor_extensions\";\nimport { createImageExtension } from \"./extensions/Image\";\nimport { CustomKeymap } from \"./extensions/custom-keymap\";\nimport { DragAndDrop } from \"./extensions/drag-and-drop\";\n\nexport type FireCMSEditorProps = {\n initialContent?: JSONContent | string,\n onMarkdownContentChange?: (content: string) => void,\n onJsonContentChange?: (content: JSONContent | null) => void,\n onHtmlContentChange?: (content: string) => void,\n handleImageUpload: (file: File) => Promise<string>\n};\n\nexport const FireCMSEditor = ({\n handleImageUpload,\n initialContent,\n onJsonContentChange,\n onHtmlContentChange,\n onMarkdownContentChange\n }: FireCMSEditorProps) => {\n\n const defaultEditorProps: EditorProviderProps[\"editorProps\"] = {\n handleDOMEvents: {\n keydown: (_view, event) => {\n // prevent default event listeners from firing when slash command is active\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\");\n if (slashCommand) {\n return true;\n }\n }\n return false;\n }\n },\n // handlePaste: (view, event) => {\n // if (event.clipboardData && event.clipboardData.files && event.clipboardData.files[0]) {\n // event.preventDefault();\n // const file = event.clipboardData.files[0];\n // const pos = view.state.selection.from;\n //\n // // startImageUpload({ file, view, pos, handleImageUpload });\n // return true;\n // }\n // return false;\n // },\n // handleDrop: (view, event, _slice, moved) => {\n // console.log(\"handleDrop\", { event, moved });\n // if (!moved && event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {\n // console.log(\"handleDrop!!!\", { event, moved });\n // event.preventDefault();\n // const file = event.dataTransfer.files[0];\n // const coordinates = view.posAtCoords({\n // left: event.clientX,\n // top: event.clientY\n // });\n // // here we deduct 1 from the pos or else the image will create an extra node\n // startImageUpload({\n // file,\n // view,\n // pos: coordinates?.pos || 0 - 1,\n // handleImageUpload,\n // });\n // return true;\n // }\n // return false;\n // }\n };\n\n const suggestionItems = createSuggestionItems([\n {\n title: \"Text\",\n description: \"Just start typing with plain text.\",\n searchTerms: [\"p\", \"paragraph\"],\n icon: <TextFieldsIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .toggleNode(\"paragraph\", \"paragraph\")\n .run();\n }\n },\n {\n title: \"To-do List\",\n description: \"Track tasks with a to-do list.\",\n searchTerms: [\"todo\", \"task\", \"list\", \"check\", \"checkbox\"],\n icon: <CheckBoxIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleTaskList().run();\n }\n },\n {\n title: \"Heading 1\",\n description: \"Big section heading.\",\n searchTerms: [\"title\", \"big\", \"large\"],\n icon: <LooksOneIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 1 })\n .run();\n }\n },\n {\n title: \"Heading 2\",\n description: \"Medium section heading.\",\n searchTerms: [\"subtitle\", \"medium\"],\n icon: <LooksTwoIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 2 })\n .run();\n }\n },\n {\n title: \"Heading 3\",\n description: \"Small section heading.\",\n searchTerms: [\"subtitle\", \"small\"],\n icon: <Looks3Icon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 3 })\n .run();\n }\n },\n {\n title: \"Bullet List\",\n description: \"Create a simple bullet list.\",\n searchTerms: [\"unordered\", \"point\"],\n icon: <FormatListBulletedIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleBulletList().run();\n }\n },\n {\n title: \"Numbered List\",\n description: \"Create a list with numbering.\",\n searchTerms: [\"ordered\"],\n icon: <FormatListNumberedIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleOrderedList().run();\n }\n },\n {\n title: \"Quote\",\n description: \"Capture a quote.\",\n searchTerms: [\"blockquote\"],\n icon: <FormatQuoteIcon size={18}/>,\n command: ({ editor, range }) =>\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .toggleNode(\"paragraph\", \"paragraph\")\n .toggleBlockquote()\n .run()\n },\n {\n title: \"Code\",\n description: \"Capture a code snippet.\",\n searchTerms: [\"codeblock\"],\n icon: <CodeIcon size={18}/>,\n command: ({ editor, range }) =>\n editor.chain().focus().deleteRange(range).toggleCodeBlock().run()\n },\n {\n title: \"Image\",\n description: \"Upload an image from your computer.\",\n searchTerms: [\"photo\", \"picture\", \"media\"],\n icon: <ImageIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).run();\n // upload image\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*\";\n input.onchange = async () => {\n if (input.files?.length) {\n const file = input.files[0];\n if (!file) return;\n const pos = editor.view.state.selection.from;\n // startImageUpload({\n // file,\n // view: editor.view,\n // pos,\n // handleImageUpload\n // });\n }\n };\n input.click();\n }\n }\n ]);\n\n const slashCommand = Command.configure({\n suggestion: {\n items: () => suggestionItems,\n render: renderItems\n }\n });\n\n const imageExtension = useMemo(() => createImageExtension(handleImageUpload), []);\n\n const extensions = [\n TiptapUnderline,\n TextStyle,\n Color,\n Highlight.configure({\n multicolor: true,\n }),\n Markdown.configure({\n html: false,\n transformCopiedText: true,\n }),\n CustomKeymap,\n DragAndDrop,\n starterKit,\n placeholder,\n tiptapLink,\n // tiptapImage,\n imageExtension,\n // updatedImage,\n taskList,\n taskItem,\n horizontalRule,\n slashCommand];\n const [openNode, setOpenNode] = useState(false);\n const [openLink, setOpenLink] = useState(false);\n\n useInjectStyles(\"Editor\", cssStyles);\n\n const editorRef = React.useRef<Editor | null>(null);\n const [markdownContent, setMarkdownContent] = useState<string | null>(null);\n const [jsonContent, setJsonContent] = useState<JSONContent | null>(null);\n const [htmlContent, setHtmlContent] = useState<string | null>(null);\n\n const onEditorUpdate = (editor: Editor) => {\n editorRef.current = editor;\n if (onMarkdownContentChange) {\n setMarkdownContent(editor.storage.markdown.getMarkdown());\n }\n if (onJsonContentChange) {\n setJsonContent(removeClassesFromJson(editor.getJSON()));\n }\n if (onHtmlContentChange) {\n setHtmlContent(editor.getHTML());\n }\n }\n\n useDebouncedCallback(markdownContent, () => {\n\n if (editorRef.current) {\n const markdown = editorRef.current.storage.markdown.getMarkdown();\n onMarkdownContentChange?.(addLineBreakAfterImages(markdown));\n }\n }, false, 500);\n\n useDebouncedCallback(jsonContent, () => {\n if (jsonContent)\n onJsonContentChange?.(jsonContent);\n }, false, 500);\n\n useDebouncedCallback(htmlContent, () => {\n if (htmlContent)\n onHtmlContentChange?.(htmlContent);\n }, false, 500);\n\n if (!initialContent) return null;\n\n return (\n <div className=\"relative w-full p-8\">\n <EditorRoot>\n <div\n className=\"relative min-h-[500px] w-full bg-white dark:bg-gray-950 rounded-lg\">\n <EditorProvider\n content={initialContent}\n extensions={extensions}\n editorProps={{\n ...defaultEditorProps,\n attributes: {\n class: \"prose-lg prose-headings:font-title font-default focus:outline-none max-w-full p-12\"\n }\n }}\n onUpdate={({ editor }) => {\n console.log(\"editor updated\");\n onEditorUpdate(editor as Editor);\n }}>\n\n <EditorCommand\n className={cn(\"text-gray-900 dark:text-white z-50 h-auto max-h-[330px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-gray-900 px-1 py-2 shadow transition-all\", defaultBorderMixin)}>\n <EditorCommandEmpty className=\"px-2 text-gray-700 dark:text-slate-300\">\n No results\n </EditorCommandEmpty>\n {suggestionItems.map((item) => (\n <EditorCommandItem\n value={item.title}\n onCommand={(val) => item?.command?.(val)}\n className={\"flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-gray-700 aria-selected:bg-blue-50 aria-selected:dark:bg-gray-700\"}\n key={item.title}\n >\n <div\n className={cn(\"flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-gray-900\", defaultBorderMixin)}>\n {item.icon}\n </div>\n <div>\n <p className=\"font-medium\">{item.title}</p>\n <p className=\"text-xs text-gray-700 dark:text-slate-300\">\n {item.description}\n </p>\n </div>\n </EditorCommandItem>\n ))}\n </EditorCommand>\n\n <EditorBubble\n tippyOptions={{\n placement: \"top\"\n }}\n className={cn(\"flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-gray-900 shadow\", defaultBorderMixin)}\n >\n {/*<Separator orientation=\"vertical\"/>*/}\n <NodeSelector open={openNode} onOpenChange={setOpenNode}/>\n <Separator orientation=\"vertical\"/>\n\n <LinkSelector open={openLink} onOpenChange={setOpenLink}/>\n <Separator orientation=\"vertical\"/>\n <TextButtons/>\n {/*<Separator orientation=\"vertical\"/>*/}\n {/*<ColorSelector open={openColor} onOpenChange={setOpenColor}/>*/}\n </EditorBubble>\n\n </EditorProvider>\n </div>\n\n </EditorRoot>\n </div>\n );\n};\n\nfunction addLineBreakAfterImages(markdown: string): string {\n // Regular expression to match markdown image syntax\n const imageRegex = /!\\[.*?\\]\\(.*?\\)/g;\n // Replace image with image followed by a line break\n return markdown.replace(imageRegex, (match) => `${match}\\n`);\n}\n\nconst cssStyles = `\n\n.ProseMirror .is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n float: left;\n color: rgb(100 116 139); //500\n pointer-events: none;\n height: 0;\n}\n.ProseMirror .is-empty::before {\n content: attr(data-placeholder);\n float: left;\n color: rgb(100 116 139); //500\n pointer-events: none;\n height: 0;\n}\n\n[data-theme=\"dark\"] {\n .ProseMirror .is-empty::before {\n color: rgb(100 116 139); //500\n }\n}\n\n.is-empty {\n color: rgb(100 116 139); //500\n}\n\n\n/* Custom image styles */\n\n.ProseMirror img {\n transition: filter 0.1s ease-in-out;\n\n &:hover {\n cursor: pointer;\n filter: brightness(90%);\n }\n\n &.ProseMirror-selectednode {\n outline: 3px solid #5abbf7;\n filter: brightness(90%);\n }\n}\n\n/* Custom TODO list checkboxes – shoutout to this awesome tutorial: https://moderncss.dev/pure-css-custom-checkbox-style/ */\n\nul[data-type=\"taskList\"] li > label {\n margin-right: 0.2rem;\n user-select: none;\n}\n\n@media screen and (max-width: 768px) {\n ul[data-type=\"taskList\"] li > label {\n margin-right: 0.5rem;\n }\n}\n\n\n[data-theme=\"dark\"] {\n ul[data-type=\"taskList\"] li > label input[type=\"checkbox\"] {\n background-color: rgb(30 41 59); // 800\n border: 2px solid #666;\n \n &:hover {\n background-color: rgb(51 65 85); // 700\n }\n \n &:active {\n background-color: rgb(71 85 105);;\n }\n }\n}\n \n\nul[data-type=\"taskList\"] li > label input[type=\"checkbox\"] {\n -webkit-appearance: none;\n appearance: none;\n background-color: white;\n margin: 0;\n cursor: pointer;\n width: 1.2em;\n height: 1.2em;\n position: relative;\n top: 5px;\n border: 2px solid #777;\n border-radius: 0.25em;\n margin-right: 0.3rem;\n display: grid;\n place-content: center;\n\n &:hover {\n background-color: rgb(241 245 249); //100\n }\n\n &:active {\n background-color: rgb(226 232 240); //200\n }\n\n &::before {\n content: \"\";\n width: 0.65em;\n height: 0.65em;\n transform: scale(0);\n transition: 120ms transform ease-in-out;\n box-shadow: inset 1em 1em;\n transform-origin: center;\n clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);\n }\n\n &:checked::before {\n transform: scale(1);\n }\n}\n\n[data-theme=\"dark\"] {\n ul[data-type=\"taskList\"] li[data-checked=\"true\"] > div > p {\n color: rgb(226 232 240);\n text-decoration: line-through;\n text-decoration-thickness: 2px;\n }\n}\n\nul[data-type=\"taskList\"] li[data-checked=\"true\"] > div > p {\n color: rgb(51 65 85); // 700\n text-decoration: line-through;\n text-decoration-thickness: 2px;\n}\n\n/* Overwrite tippy-box original max-width */\n\n.tippy-box {\n max-width: 400px !important;\n}\n\n.ProseMirror:not(.dragging) .ProseMirror-selectednode {\n outline: none !important;\n background-color: rgb(219 234 254); // blue 100\n transition: background-color 0.2s;\n box-shadow: none;\n}\n\n[data-theme=\"dark\"] .ProseMirror:not(.dragging) .ProseMirror-selectednode {\n background-color: rgb(51 65 85); // 700\n}\n\n.drag-handle {\n position: fixed;\n opacity: 1;\n transition: opacity ease-in 0.2s;\n border-radius: 0.25rem;\n\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' style='fill: rgba(128, 128, 128, 0.9)'%3E%3Cpath d='M3,2 C2.44771525,2 2,1.55228475 2,1 C2,0.44771525 2.44771525,0 3,0 C3.55228475,0 4,0.44771525 4,1 C4,1.55228475 3.55228475,2 3,2 Z M3,6 C2.44771525,6 2,5.55228475 2,5 C2,4.44771525 2.44771525,4 3,4 C3.55228475,4 4,4.44771525 4,5 C4,5.55228475 3.55228475,6 3,6 Z M3,10 C2.44771525,10 2,9.55228475 2,9 C2,8.44771525 2.44771525,8 3,8 C3.55228475,8 4,8.44771525 4,9 C4,9.55228475 3.55228475,10 3,10 Z M7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 C7.55228475,0 8,0.44771525 8,1 C8,1.55228475 7.55228475,2 7,2 Z M7,6 C6.44771525,6 6,5.55228475 6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 C8,5.55228475 7.55228475,6 7,6 Z M7,10 C6.44771525,10 6,9.55228475 6,9 C6,8.44771525 6.44771525,8 7,8 C7.55228475,8 8,8.44771525 8,9 C8,9.55228475 7.55228475,10 7,10 Z'%3E%3C/path%3E%3C/svg%3E\");\n background-size: calc(0.5em + 0.375rem) calc(0.5em + 0.375rem);\n background-repeat: no-repeat;\n background-position: center;\n width: 1.2rem;\n height: 1.5rem;\n z-index: 50;\n cursor: grab;\n\n &:hover {\n background-color: rgb(241 245 249); //100\n transition: background-color 0.2s;\n }\n\n &:active {\n background-color: rgb(226 232 240); //200\n transition: background-color 0.2s;\n }\n\n &.hide {\n opacity: 0;\n pointer-events: none;\n }\n\n @media screen and (max-width: 600px) {\n display: none;\n pointer-events: none;\n }\n}\n\n[data-theme=\"dark\"] .drag-handle {\n &:hover {\n background-color: rgb(51 65 85); // 700\n }\n\n &:active {\n background-color: rgb(51 65 85); // 700\n }\n}\n`;\n"],"names":["editorStore","createStore","EditorRoot","children","jsx","Provider","EditorBubble","forwardRef","tippyOptions","rest","ref","editor","useCurrentEditor","instanceRef","useRef","useEffect","bubbleMenuProps","useMemo","state","selection","empty","isNodeSelection","val","BubbleMenu","EditorBubbleItem","asChild","onSelect","Comp","Slot","t","tunnel","queryAtom","atom","rangeAtom","EditorCommandOut","query","range","setQuery","useSetAtom","setRange","navigationKeys","onKeyDown","e","commandRef","EditorCommand","className","commandListRef","useAtom","jsxs","Command","EditorCommandItem","onCommand","useAtomValue","CommandItem","EditorCommandEmpty","CommandEmpty","Extension","props","Suggestion","renderItems","component","popup","ReactRenderer","tippy","createSuggestionItems","items","PlaceholderExtension","Placeholder","node","Horizontal","HorizontalRule","InputRule","attributes","tr","start","end","TextFieldsIcon","LooksOneIcon","LooksTwoIcon","Looks3Icon","CheckBoxIcon","FormatListBulletedIcon","FormatListNumberedIcon","FormatQuoteIcon","CodeIcon","NodeSelector","open","onOpenChange","useEditor","activeItem","item","Popover","Button","ExpandMoreIcon","index","CheckIcon","isValidUrl","url","getUrlFromString","str","LinkSelector","inputRef","cn","target","input","DeleteIcon","TextButtons","FormatBoldIcon","FormatItalicIcon","FormatUnderlinedIcon","FormatStrikethroughIcon","useDebouncedCallback","value","callback","immediate","timeoutMs","pendingUpdate","React","performUpdate","handlerRef","removeClassesFromJson","jsonObj","key","placeholder","tiptapLink","TiptapLink","taskList","TaskList","taskItem","TaskItem","horizontalRule","defaultBorderMixin","starterKit","StarterKit","onFileRead","plugin","view","readerEvent","pos","upload","image","schema","decorationSet","imageElement","deco","Decoration","src","imageNode","dropImagePlugin","Plugin","DecorationSet","old","meta","event","images","file","position","reader","slice","anyImageFound","editorView","prevState","prevDecos","newDecos","createImageExtension","uploadFn","TiptapImage","CustomKeymap","commands","startNodePos","endNodePos","startSelectionPos","endSelectionPos","absoluteRect","data","nodeDOMAtCoords","coords","elem","nodePosAtDOM","options","boundingRect","DragHandle","handleDragStart","nodePos","NodeSelection","dom","text","__serializeForClipboard","handleClick","dragHandleElement","hideDragHandle","showDragHandle","compStyle","lineHeight","paddingTop","rect","DragAndDrop","FireCMSEditor","handleImageUpload","initialContent","onJsonContentChange","onHtmlContentChange","onMarkdownContentChange","defaultEditorProps","_view","suggestionItems","ImageIcon","slashCommand","imageExtension","extensions","TiptapUnderline","TextStyle","Color","Highlight","Markdown","openNode","setOpenNode","useState","openLink","setOpenLink","useInjectStyles","cssStyles","editorRef","markdownContent","setMarkdownContent","jsonContent","setJsonContent","htmlContent","setHtmlContent","onEditorUpdate","markdown","addLineBreakAfterImages","EditorProvider","Separator","imageRegex","match"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/components/editor.tsx","../src/components/editor-bubble.tsx","../src/components/editor-bubble-item.tsx","../src/components/editor-command.tsx","../src/components/editor-command-item.tsx","../src/extensions/slash-command.tsx","../src/extensions/index.ts","../src/selectors/node-selector.tsx","../src/selectors/link-selector.tsx","../src/selectors/text-buttons.tsx","../src/utils/useDebouncedCallback.ts","../src/utils/remove_classes.ts","../src/editor_extensions.tsx","../src/extensions/Image.ts","../src/extensions/custom-keymap.ts","../src/extensions/drag-and-drop.tsx","../src/editor.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { createStore, Provider } from \"jotai\";\n\nexport const editorStore = createStore();\n\nexport const EditorRoot = ({ children }: { children: ReactNode }): JSX.Element => {\n return <Provider store={editorStore}>{children}</Provider>;\n};\n","import { BubbleMenu, type BubbleMenuProps, isNodeSelection, useCurrentEditor } from \"@tiptap/react\";\nimport { type ReactNode, useMemo, useRef, useEffect, forwardRef } from \"react\";\nimport type { Instance, Props } from \"tippy.js\";\n\nexport interface EditorBubbleProps extends Omit<BubbleMenuProps, \"editor\"> {\n children: ReactNode;\n}\n\nexport const EditorBubble = forwardRef<HTMLDivElement, EditorBubbleProps>(\n ({ children, tippyOptions, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const instanceRef = useRef<Instance<Props> | null>(null);\n\n useEffect(() => {\n if (!instanceRef.current || !tippyOptions?.placement) return;\n\n instanceRef.current.setProps({ placement: tippyOptions.placement });\n instanceRef.current.popperInstance?.update();\n }, [tippyOptions?.placement]);\n\n const bubbleMenuProps: Omit<BubbleMenuProps, \"editor\" | \"children\"> = useMemo(() => {\n const shouldShow: BubbleMenuProps[\"shouldShow\"] = ({ editor, state }) => {\n const { selection } = state;\n const { empty } = selection;\n\n // don't show bubble menu if:\n // - the selected node is an image\n // - the selection is empty\n // - the selection is a node selection (for drag handles)\n if (editor.isActive(\"image\") || empty || isNodeSelection(selection)) {\n return false;\n }\n return true;\n };\n\n return {\n shouldShow,\n tippyOptions: {\n onCreate: (val) => {\n instanceRef.current = val;\n },\n moveTransition: \"transform 0.15s ease-out\",\n ...tippyOptions,\n },\n ...rest,\n };\n }, [rest, tippyOptions]);\n\n if (!editor) return null;\n\n return (\n //We need to add this because of https://github.com/ueberdosis/tiptap/issues/2658\n <div ref={ref}>\n <BubbleMenu editor={editor} {...bubbleMenuProps}>\n {children}\n </BubbleMenu>\n </div>\n );\n }\n);\n\nexport default EditorBubble;\n","import { type ComponentPropsWithoutRef, type ReactNode, forwardRef } from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useCurrentEditor, type Editor } from \"@tiptap/react\";\n\ninterface EditorBubbleItemProps {\n children: ReactNode;\n asChild?: boolean;\n onSelect?: (editor: Editor) => void;\n}\n\nexport const EditorBubbleItem = forwardRef<\n HTMLDivElement,\n EditorBubbleItemProps & Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\">\n>(({ children, asChild, onSelect, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const Comp = asChild ? Slot : \"div\";\n\n if (!editor) return null;\n\n return (\n <Comp ref={ref} {...rest} onClick={() => onSelect?.(editor)}>\n {children}\n </Comp>\n );\n});\n\nEditorBubbleItem.displayName = \"EditorBubbleItem\";\n\nexport default EditorBubbleItem;\n","import { atom, useAtom, useSetAtom } from \"jotai\";\nimport { useEffect, useRef, type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport tunnel from \"tunnel-rat\";\nimport { editorStore } from \"./editor\";\nimport { Command } from \"cmdk\";\nimport type { Range } from \"@tiptap/core\";\n\nconst t = tunnel();\n\nexport const queryAtom = atom(\"\");\nexport const rangeAtom = atom<Range | null>(null);\n\nexport const EditorCommandOut = ({\n query,\n range,\n}: {\n query: string;\n range: Range;\n}): JSX.Element => {\n const setQuery = useSetAtom(queryAtom, { store: editorStore });\n const setRange = useSetAtom(rangeAtom, { store: editorStore });\n\n useEffect(() => {\n setQuery(query);\n }, [query, setQuery]);\n\n useEffect(() => {\n setRange(range);\n }, [range, setRange]);\n\n useEffect(() => {\n const navigationKeys = [\"ArrowUp\", \"ArrowDown\", \"Enter\"];\n const onKeyDown = (e: KeyboardEvent) => {\n if (navigationKeys.includes(e.key)) {\n e.preventDefault();\n const commandRef = document.querySelector(\"#slash-command\");\n\n if (commandRef)\n commandRef.dispatchEvent(\n new KeyboardEvent(\"keydown\", { key: e.key, cancelable: true, bubbles: true })\n );\n\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, []);\n\n return <t.Out />;\n};\n\nexport const EditorCommand = forwardRef<HTMLDivElement, ComponentPropsWithoutRef<typeof Command>>(\n ({ children, className, ...rest }, ref) => {\n const commandListRef = useRef<HTMLDivElement>(null);\n const [query, setQuery] = useAtom(queryAtom);\n\n return (\n <t.In>\n <Command\n ref={ref}\n onKeyDown={(e) => {\n e.stopPropagation();\n }}\n id='slash-command'\n className={className}\n {...rest}>\n <Command.Input value={query} onValueChange={setQuery} style={{ display: \"none\" }} />\n <Command.List ref={commandListRef}>{children}</Command.List>\n </Command>\n </t.In>\n );\n }\n);\n","import { type ComponentPropsWithoutRef, forwardRef } from \"react\";\nimport { CommandEmpty, CommandItem } from \"cmdk\";\nimport { Editor, type Range } from \"@tiptap/core\";\nimport { useCurrentEditor } from \"@tiptap/react\";\nimport { useAtomValue } from \"jotai\";\nimport { rangeAtom } from \"./editor-command\";\n\ninterface EditorCommandItemProps {\n onCommand: ({ editor, range }: { editor: Editor; range: Range }) => void;\n}\n\nexport const EditorCommandItem = forwardRef<\n HTMLDivElement,\n EditorCommandItemProps & ComponentPropsWithoutRef<typeof CommandItem>\n>(({ children, onCommand, ...rest }, ref) => {\n const { editor } = useCurrentEditor();\n const range = useAtomValue(rangeAtom);\n\n if (!editor || !range) return null;\n\n return (\n <CommandItem ref={ref} {...rest} onSelect={() => onCommand({ editor, range })}>\n {children}\n </CommandItem>\n );\n});\n\nEditorCommandItem.displayName = \"EditorCommandItem\";\n\nexport const EditorCommandEmpty = CommandEmpty;\n\nexport default EditorCommandItem;\n","import { type Editor, type Range, Extension } from \"@tiptap/core\";\nimport Suggestion from \"@tiptap/suggestion\";\nimport { ReactRenderer } from \"@tiptap/react\";\nimport tippy from \"tippy.js\";\n\nimport { EditorCommandOut } from \"../components/editor-command\";\nimport type { ReactNode } from \"react\";\n\nconst Command = Extension.create({\n name: \"slash-command\",\n addOptions() {\n return {\n suggestion: {\n char: \"/\",\n command: ({ editor, range, props }: { editor: Editor; range: Range; props: any }) => {\n props.command({ editor, range });\n },\n },\n };\n },\n addProseMirrorPlugins() {\n return [\n Suggestion({\n editor: this.editor,\n ...this.options.suggestion,\n }),\n ];\n },\n});\n\nconst renderItems = () => {\n let component: ReactRenderer | null = null;\n let popup: any | null = null;\n\n return {\n onStart: (props: { editor: Editor; clientRect: DOMRect }) => {\n component = new ReactRenderer(EditorCommandOut, {\n props,\n editor: props.editor,\n });\n\n // @ts-ignore\n popup = tippy(\"body\", {\n getReferenceClientRect: props.clientRect,\n appendTo: () => document.body,\n content: component.element,\n showOnCreate: true,\n interactive: true,\n trigger: \"manual\",\n placement: \"bottom-start\",\n });\n },\n onUpdate: (props: { editor: Editor; clientRect: DOMRect }) => {\n component?.updateProps(props);\n\n popup &&\n popup[0].setProps({\n getReferenceClientRect: props.clientRect,\n });\n },\n\n onKeyDown: (props: { event: KeyboardEvent }) => {\n if (props.event.key === \"Escape\") {\n popup?.[0].hide();\n\n return true;\n }\n\n // @ts-ignore\n return component?.ref?.onKeyDown(props);\n },\n onExit: () => {\n popup?.[0].destroy();\n component?.destroy();\n },\n };\n};\n\nexport interface SuggestionItem {\n title: string;\n description: string;\n icon: ReactNode;\n searchTerms?: string[];\n command?: (props: { editor: Editor; range: Range }) => void;\n}\n\nexport const createSuggestionItems = (items: SuggestionItem[]) => items;\n\nexport { Command, renderItems };\n","import StarterKit from \"@tiptap/starter-kit\";\nimport HorizontalRule from \"@tiptap/extension-horizontal-rule\";\nimport TiptapLink from \"@tiptap/extension-link\";\nimport TiptapImage from \"@tiptap/extension-image\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\n\nimport { TaskItem } from \"@tiptap/extension-task-item\";\nimport { TaskList } from \"@tiptap/extension-task-list\";\nimport { InputRule } from \"@tiptap/core\";\n\nconst PlaceholderExtension = Placeholder.configure({\n placeholder: ({ node }) => {\n if (node.type.name === \"heading\") {\n return `Heading ${node.attrs.level}`;\n }\n return \"Press '/' for commands\";\n },\n includeChildren: true,\n});\n\nconst Horizontal = HorizontalRule.extend({\n addInputRules() {\n return [\n new InputRule({\n find: /^(?:---|—-|___\\s|\\*\\*\\*\\s)$/,\n handler: ({ state, range }) => {\n const attributes = {};\n\n const { tr } = state;\n const start = range.from;\n const end = range.to;\n\n tr.insert(start - 1, this.type.create(attributes)).delete(\n tr.mapping.map(start),\n tr.mapping.map(end)\n );\n },\n }),\n ];\n },\n});\n\nexport {\n PlaceholderExtension as Placeholder,\n StarterKit,\n Horizontal as HorizontalRule,\n TiptapLink,\n TiptapImage,\n TaskItem,\n TaskList,\n InputRule,\n};\nexport * from \"./slash-command\";\n\nexport { getPrevText } from \"../utils/utils\";\n","import React from \"react\";\nimport { EditorBubbleItem, useEditor } from \"../components\";\n\nimport {\n Button,\n CheckBoxIcon,\n CheckIcon,\n CodeIcon,\n ExpandMoreIcon,\n FormatListBulletedIcon,\n FormatListNumberedIcon,\n FormatQuoteIcon,\n Looks3Icon,\n LooksOneIcon,\n LooksTwoIcon,\n Popover,\n TextFieldsIcon\n} from \"@firecms/ui\";\n\nexport type SelectorItem = {\n name: string;\n icon: React.ElementType;\n command: (editor: ReturnType<typeof useEditor>[\"editor\"]) => void;\n isActive: (editor: ReturnType<typeof useEditor>[\"editor\"]) => boolean;\n};\n\nconst items: SelectorItem[] = [\n {\n name: \"Text\",\n icon: TextFieldsIcon,\n command: (editor) =>\n editor?.chain().focus().toggleNode(\"paragraph\", \"paragraph\").run(),\n // I feel like there has to be a more efficient way to do this – feel free to PR if you know how!\n isActive: (editor) =>\n (editor?.isActive(\"paragraph\") &&\n !editor?.isActive(\"bulletList\") &&\n !editor?.isActive(\"orderedList\")) ?? false,\n },\n {\n name: \"Heading 1\",\n icon: LooksOneIcon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 1 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 1 }) ?? false,\n },\n {\n name: \"Heading 2\",\n icon: LooksTwoIcon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 2 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 2 }) ?? false,\n },\n {\n name: \"Heading 3\",\n icon: Looks3Icon,\n command: (editor) =>\n editor?.chain().focus().toggleHeading({ level: 3 }).run(),\n isActive: (editor) => editor?.isActive(\"heading\", { level: 3 }) ?? false,\n },\n {\n name: \"To-do List\",\n icon: CheckBoxIcon,\n command: (editor) => editor?.chain().focus().toggleTaskList().run(),\n isActive: (editor) => editor?.isActive(\"taskItem\") ?? false,\n },\n {\n name: \"Bullet List\",\n icon: FormatListBulletedIcon,\n command: (editor) => editor?.chain().focus().toggleBulletList().run(),\n isActive: (editor) => editor?.isActive(\"bulletList\") ?? false,\n },\n {\n name: \"Numbered List\",\n icon: FormatListNumberedIcon,\n command: (editor) => editor?.chain().focus().toggleOrderedList().run(),\n isActive: (editor) => editor?.isActive(\"orderedList\") ?? false,\n },\n {\n name: \"Quote\",\n icon: FormatQuoteIcon,\n command: (editor) => editor?.chain()\n .focus()\n .toggleNode(\"paragraph\", \"paragraph\")\n .toggleBlockquote()\n .run(),\n isActive: (editor) => editor?.isActive(\"blockquote\") ?? false,\n },\n {\n name: \"Code\",\n icon: CodeIcon,\n command: (editor) => editor?.chain().focus().toggleCodeBlock().run(),\n isActive: (editor) => editor?.isActive(\"codeBlock\") ?? false,\n },\n];\n\ninterface NodeSelectorProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport const NodeSelector = ({\n open,\n onOpenChange\n }: NodeSelectorProps) => {\n const { editor } = useEditor();\n if (!editor) return null;\n const activeItem = items.filter((item) => item.isActive(editor)).pop() ?? {\n name: \"Multiple\",\n };\n\n return (\n\n <Popover\n sideOffset={5}\n align=\"start\"\n className=\"w-48 p-1\"\n trigger={<Button variant=\"text\"\n className=\"gap-2 rounded-none\"\n color=\"text\">\n <span className=\"whitespace-nowrap text-sm\">{activeItem.name}</span>\n <ExpandMoreIcon size={\"small\"}/>\n </Button>}\n modal={true}\n open={open}\n onOpenChange={onOpenChange}>\n {items.map((item, index) => (\n <EditorBubbleItem\n key={index}\n onSelect={(editor) => {\n item.command(editor);\n onOpenChange(false);\n }}\n className=\"flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-gray-700 text-gray-900 dark:text-white\"\n >\n <div className=\"flex items-center space-x-2\">\n <item.icon size=\"smallest\"/>\n <span>{item.name}</span>\n </div>\n {activeItem.name === item.name && <CheckIcon size=\"smallest\"/>}\n </EditorBubbleItem>\n ))}\n\n </Popover>\n );\n};\n","import { useEditor } from \"../components\";\nimport { useEffect, useRef, } from \"react\";\nimport { Button, CheckIcon, cls, DeleteIcon, Popover } from \"@firecms/ui\";\n\nexport function isValidUrl(url: string) {\n try {\n // eslint-disable-next-line no-new\n new URL(url);\n return true;\n } catch (e) {\n return false;\n }\n}\n\nexport function getUrlFromString(str: string) {\n if (isValidUrl(str)) return str;\n try {\n if (str.includes(\".\") && !str.includes(\" \")) {\n return new URL(`https://${str}`).toString();\n }\n return null;\n } catch (e) {\n return null;\n }\n}\n\ninterface LinkSelectorProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport const LinkSelector = ({\n open,\n onOpenChange\n }: LinkSelectorProps) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const { editor } = useEditor();\n\n // Autofocus on input by default\n useEffect(() => {\n inputRef.current && inputRef.current?.focus();\n });\n\n if (!editor) return null;\n\n return (\n <Popover modal={true}\n open={open}\n onOpenChange={onOpenChange}\n trigger={<Button variant=\"text\"\n className=\"gap-2 rounded-none\"\n color={\"text\"}>\n <p className={cls(\"underline decoration-stone-400 underline-offset-4\", {\n \"text-blue-500\": editor.isActive(\"link\"),\n })}>\n Link\n </p>\n </Button>}>\n <form\n onSubmit={(e) => {\n const target = e.currentTarget as HTMLFormElement;\n e.preventDefault();\n const input = target[0] as HTMLInputElement;\n const url = getUrlFromString(input.value);\n url && editor.chain().focus().setLink({ href: url }).run();\n }}\n className=\"flex p-1\"\n >\n <input\n ref={inputRef}\n autoFocus={open}\n placeholder=\"Paste a link\"\n defaultValue={editor.getAttributes(\"link\").href || \"\"}\n className={\"text-gray-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none\"}/>\n\n {editor.getAttributes(\"link\").href ? (\n <Button\n size={\"small\"}\n variant=\"text\"\n type=\"button\"\n color={\"text\"}\n className=\"flex items-center\"\n onClick={() => {\n editor.chain().focus().unsetLink().run();\n }}\n >\n <DeleteIcon size=\"small\"/>\n </Button>\n ) : (\n <Button size={\"small\"}\n variant={\"text\"}>\n <CheckIcon size=\"small\"/>\n </Button>\n )}\n </form>\n </Popover>\n );\n};\n","import { EditorBubbleItem, useEditor } from \"../components\";\nimport type { SelectorItem } from \"./node-selector\";\nimport {\n Button,\n cls,\n CodeIcon,\n FormatBoldIcon,\n FormatItalicIcon,\n FormatStrikethroughIcon,\n FormatUnderlinedIcon\n} from \"@firecms/ui\";\n\nexport const TextButtons = () => {\n const { editor } = useEditor();\n if (!editor) return null;\n const items: SelectorItem[] = [\n {\n name: \"bold\",\n isActive: (editor) => editor?.isActive(\"bold\") ?? false,\n command: (editor) => editor?.chain().focus().toggleBold().run(),\n icon: FormatBoldIcon,\n },\n {\n name: \"italic\",\n isActive: (editor) => editor?.isActive(\"italic\") ?? false,\n command: (editor) => editor?.chain().focus().toggleItalic().run(),\n icon: FormatItalicIcon,\n },\n {\n name: \"underline\",\n isActive: (editor) => editor?.isActive(\"underline\") ?? false,\n command: (editor) => editor?.chain().focus().toggleUnderline().run(),\n icon: FormatUnderlinedIcon,\n },\n {\n name: \"strike\",\n isActive: (editor) => editor?.isActive(\"strike\") ?? false,\n command: (editor) => editor?.chain().focus().toggleStrike().run(),\n icon: FormatStrikethroughIcon,\n },\n {\n name: \"code\",\n isActive: (editor) => editor?.isActive(\"code\") ?? false,\n command: (editor) => editor?.chain().focus().toggleCode().run(),\n icon: CodeIcon,\n },\n ];\n return (\n <div className=\"flex\">\n {items.map((item, index) => (\n <EditorBubbleItem\n key={index}\n onSelect={(editor) => {\n item.command(editor);\n }}\n >\n <Button size={\"small\"}\n color=\"text\"\n className=\"gap-2 rounded-none h-full\"\n variant=\"text\">\n <item.icon\n className={cls( {\n \"text-inherit\": !item.isActive(editor),\n \"text-blue-500\": item.isActive(editor),\n })}\n />\n </Button>\n </EditorBubbleItem>\n ))}\n </div>\n );\n};\n","import React from \"react\";\n\nexport function useDebouncedCallback<T>(value: T, callback: () => void, immediate: boolean, timeoutMs = 300) {\n\n const pendingUpdate = React.useRef(false);\n const performUpdate = () => {\n callback();\n pendingUpdate.current = false;\n };\n\n const handlerRef = React.useRef<number | undefined>(undefined);\n\n React.useEffect(\n () => {\n pendingUpdate.current = true;\n clearTimeout(handlerRef.current);\n handlerRef.current = setTimeout(performUpdate, timeoutMs) as any;\n return () => {\n if (immediate)\n performUpdate();\n };\n },\n [immediate, value]\n );\n}\n","export function removeClassesFromJson(jsonObj: any): any {\n // If it's an array, apply the function to each element\n if (Array.isArray(jsonObj)) {\n return jsonObj.map(item => removeClassesFromJson(item));\n } else if (typeof jsonObj === \"object\" && jsonObj !== null) { // If it's an object, recurse through its properties\n // If the object has an `attrs` property and `class` field, delete the `class` field\n if (jsonObj.attrs && typeof jsonObj.attrs === \"object\" && \"class\" in jsonObj.attrs) {\n delete jsonObj.attrs.class;\n }\n\n // Apply the function recursively to object properties\n Object.keys(jsonObj).forEach(key => {\n jsonObj[key] = removeClassesFromJson(jsonObj[key]);\n });\n }\n return jsonObj;\n}\n","import { HorizontalRule, Placeholder, StarterKit, TaskItem, TaskList, TiptapImage, TiptapLink, } from \"./extensions\";\n\nimport { cls, defaultBorderMixin } from \"@firecms/ui\";\n\n//You can overwrite the placeholder with your own configuration\nexport const placeholder = Placeholder;\nexport const tiptapLink = TiptapLink.configure({\n HTMLAttributes: {\n class: cls(\n \"text-gray-600 dark:text-slate-300 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer\",\n ),\n },\n});\n\n// export const tiptapImage = TiptapImage.extend({\n// addProseMirrorPlugins() {\n// return [UploadImagesPlugin()];\n// },\n// }).configure({\n// allowBase64: true,\n// HTMLAttributes: {\n// class: cn(\"rounded-lg border\", defaultBorderMixin),\n// },\n// });\n\n// const updatedImage = UpdatedImage.configure({\n// HTMLAttributes: {\n// class: cn(\"rounded-lg border\", defaultBorderMixin),\n// },\n// });\n\nexport const taskList = TaskList.configure({\n HTMLAttributes: {\n class: cls(\"not-prose\"),\n },\n});\nexport const taskItem = TaskItem.configure({\n HTMLAttributes: {\n class: cls(\"flex items-start my-4\"),\n },\n nested: true,\n});\n\nexport const horizontalRule = HorizontalRule.configure({\n HTMLAttributes: {\n class: cls(\"mt-4 mb-6 border-t\", defaultBorderMixin),\n },\n});\n\nexport const starterKit = StarterKit.configure({\n bulletList: {\n HTMLAttributes: {\n class: cls(\"list-disc list-outside leading-3 -mt-2\"),\n },\n },\n orderedList: {\n HTMLAttributes: {\n class: cls(\"list-decimal list-outside leading-3 -mt-2\"),\n },\n },\n listItem: {\n HTMLAttributes: {\n class: cls(\"leading-normal -mb-2\"),\n },\n },\n blockquote: {\n HTMLAttributes: {\n class: cls(\"border-l-4 border-primary\"),\n },\n },\n codeBlock: {\n HTMLAttributes: {\n class: cls(\"rounded bg-blue-50 dark:bg-gray-700 border p-5 font-mono font-medium\", defaultBorderMixin),\n },\n },\n code: {\n HTMLAttributes: {\n class: cls(\"rounded-md bg-slate-50 dark:bg-gray-700 px-1.5 py-1 font-mono font-medium\"),\n spellcheck: \"false\",\n },\n },\n horizontalRule: false,\n dropcursor: {\n color: \"#DBEAFE\",\n width: 4,\n },\n gapcursor: false,\n});\n","import { Plugin, } from \"prosemirror-state\";\nimport { TiptapImage } from \"./index\";\nimport { cls, defaultBorderMixin } from \"@firecms/ui\";\nimport { Decoration, DecorationSet, EditorView } from \"@tiptap/pm/view\";\n\nexport type UploadFn = (image: File) => Promise<string>;\n\nasync function onFileRead(plugin: Plugin, view: EditorView, readerEvent: ProgressEvent<FileReader>, pos: number, upload: UploadFn, image: File) {\n\n const { schema } = view.state;\n let decorationSet = plugin.getState(view.state);\n\n const placeholder = document.createElement(\"div\");\n const imageElement = document.createElement(\"img\");\n imageElement.setAttribute(\"class\", \"opacity-40 rounded-lg border border-stone-200\");\n imageElement.src = readerEvent.target?.result as string;\n placeholder.appendChild(imageElement);\n\n const deco = Decoration.widget(pos, placeholder);\n decorationSet = decorationSet?.add(view.state.doc, [deco]);\n view.dispatch(view.state.tr.setMeta(plugin, { decorationSet }));\n\n // Image Upload Logic\n const src = await upload(image);\n console.log(\"uploaded image\", src);\n\n // Replace placeholder with actual image\n const imageNode = schema.nodes.image.create({ src });\n const tr = view.state.tr.replaceWith(pos, pos, imageNode);\n\n // Remove placeholder decoration\n decorationSet = decorationSet?.remove([deco]);\n tr.setMeta(plugin, { decorationSet });\n view.dispatch(tr);\n}\n\nexport const dropImagePlugin = (upload: UploadFn) => {\n const plugin: Plugin = new Plugin({\n state: {\n // Initialize the plugin state with an empty DecorationSet\n init: () => DecorationSet.empty,\n // Apply transactions to update the state\n apply: (tr, old) => {\n // Handle custom transaction steps that update decorations\n const meta = tr.getMeta(plugin);\n if (meta && meta.decorationSet) {\n return meta.decorationSet;\n }\n // Map decorations to the new document structure\n return old.map(tr.mapping, tr.doc);\n }\n },\n props: {\n handleDOMEvents: {\n drop: (view, event) => {\n console.log(\"drop event\", event)\n if (!event.dataTransfer?.files || event.dataTransfer?.files.length === 0) {\n return false;\n }\n event.preventDefault();\n\n const files = Array.from(event.dataTransfer.files);\n const images = files.filter(file => /image/i.test(file.type));\n\n if (images.length === 0) return false;\n\n images.forEach(image => {\n\n const position = view.posAtCoords({ left: event.clientX, top: event.clientY });\n if (!position) return;\n\n const reader = new FileReader();\n reader.onload = async (readerEvent) => {\n await onFileRead(plugin, view, readerEvent, position.pos, upload, image);\n };\n reader.readAsDataURL(image);\n });\n\n return true;\n }\n },\n handlePaste(view, event, slice) {\n const items = Array.from(event.clipboardData?.items || []);\n const pos = view.state.selection.from;\n console.log(\"pos\", pos)\n let anyImageFound = false;\n\n items.forEach((item) => {\n const image = item.getAsFile();\n console.log(\"image\", image);\n if (image) {\n anyImageFound = true;\n // if (item.type.indexOf(\"image\") === 0) {\n // event.preventDefault();\n //\n // if (upload && image) {\n // upload(image).then((src) => {\n // const node = schema.nodes.image.create({\n // src\n // });\n // const transaction = view.state.tr.replaceSelectionWith(node);\n // view.dispatch(transaction);\n // });\n // }\n // } else {\n const reader = new FileReader();\n\n reader.onload = async (readerEvent) => {\n await onFileRead(plugin, view, readerEvent, pos, upload, image);\n };\n reader.readAsDataURL(image);\n }\n });\n\n return anyImageFound;\n },\n decorations(state) {\n return plugin.getState(state);\n }\n },\n view(editorView) {\n // This is needed to immediately apply the decoration updates\n return {\n update(view, prevState) {\n const prevDecos = plugin.getState(prevState);\n const newDecos = plugin.getState(view.state);\n\n if (prevDecos !== newDecos) {\n view.updateState(view.state);\n }\n }\n };\n }\n });\n return plugin;\n};\n\n/**\n * Matches following attributes in Markdown-typed image: [, alt, src, title]\n *\n * Example:\n * ![Lorem](image.jpg) -> [, \"Lorem\", \"image.jpg\"]\n * ![](image.jpg \"Ipsum\") -> [, \"\", \"image.jpg\", \"Ipsum\"]\n * ![Lorem](image.jpg \"Ipsum\") -> [, \"Lorem\", \"image.jpg\", \"Ipsum\"]\n */\nconst IMAGE_INPUT_REGEX = /!\\[(.+|:?)\\]\\((\\S+)(?:(?:\\s+)[\"'](\\S+)[\"'])?\\)/;\n\nexport const createImageExtension = (uploadFn: UploadFn) => {\n return TiptapImage.extend({\n addProseMirrorPlugins() {\n return [dropImagePlugin(uploadFn)];\n }\n }).configure({\n allowBase64: true,\n HTMLAttributes: {\n class: cls(\"rounded-lg border\", defaultBorderMixin)\n }\n });\n};\n","import { Extension } from \"@tiptap/core\";\n\ndeclare module \"@tiptap/core\" {\n // eslint-disable-next-line no-unused-vars\n interface Commands<ReturnType> {\n customkeymap: {\n /**\n * Select text between node boundaries\n */\n selectTextWithinNodeBoundaries: () => ReturnType;\n };\n }\n}\n\nexport const CustomKeymap = Extension.create({\n name: \"CustomKeymap\",\n\n addCommands() {\n return {\n selectTextWithinNodeBoundaries:\n () =>\n ({ editor, commands }) => {\n const { state } = editor;\n const { tr } = state;\n const startNodePos = tr.selection.$from.start();\n const endNodePos = tr.selection.$to.end();\n return commands.setTextSelection({\n from: startNodePos,\n to: endNodePos,\n });\n },\n };\n },\n\n addKeyboardShortcuts() {\n return {\n \"Mod-a\": ({ editor }) => {\n const { state } = editor;\n const { tr } = state;\n const startSelectionPos = tr.selection.from;\n const endSelectionPos = tr.selection.to;\n const startNodePos = tr.selection.$from.start();\n const endNodePos = tr.selection.$to.end();\n const isCurrentTextSelectionNotExtendedToNodeBoundaries =\n startSelectionPos > startNodePos || endSelectionPos < endNodePos;\n if (isCurrentTextSelectionNotExtendedToNodeBoundaries) {\n editor.chain().selectTextWithinNodeBoundaries().run();\n return true;\n }\n return false;\n },\n };\n },\n});\n\n","import { Extension } from \"@tiptap/core\";\n\nimport { NodeSelection, Plugin } from \"@tiptap/pm/state\";\n// @ts-ignore\nimport { __serializeForClipboard, EditorView } from \"@tiptap/pm/view\";\n\nexport interface DragHandleOptions {\n /**\n * The width of the drag handle\n */\n dragHandleWidth: number;\n}\nfunction absoluteRect(node: Element) {\n const data = node.getBoundingClientRect();\n\n return {\n top: data.top,\n left: data.left,\n width: data.width,\n };\n}\n\nfunction nodeDOMAtCoords(coords: { x: number; y: number }) {\n return document\n .elementsFromPoint(coords.x, coords.y)\n .find(\n (elem: Element) =>\n elem.parentElement?.matches?.(\".ProseMirror\") ||\n elem.matches(\n [\"li\", \"p:not(:first-child)\", \"pre\", \"blockquote\", \"h1, h2, h3, h4, h5, h6\"].join(\", \")\n )\n );\n}\n\nfunction nodePosAtDOM(node: Element, view: EditorView, options: DragHandleOptions) {\n const boundingRect = node.getBoundingClientRect();\n\n return view.posAtCoords({\n left: boundingRect.left + 50 + options.dragHandleWidth,\n top: boundingRect.top + 1,\n })?.inside;\n}\n\nfunction DragHandle(options: DragHandleOptions) {\n function handleDragStart(event: DragEvent, view: EditorView) {\n view.focus();\n\n if (!event.dataTransfer) return;\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) return;\n\n const nodePos = nodePosAtDOM(node, view, options);\n if (nodePos == null || nodePos < 0) return;\n\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));\n\n const slice = view.state.selection.content();\n const { dom, text } = __serializeForClipboard(view, slice);\n\n event.dataTransfer.clearData();\n event.dataTransfer.setData(\"text/html\", dom.innerHTML);\n event.dataTransfer.setData(\"text/plain\", text);\n event.dataTransfer.effectAllowed = \"copyMove\";\n\n event.dataTransfer.setDragImage(node, 0, 0);\n\n view.dragging = { slice, move: event.ctrlKey };\n }\n\n function handleClick(event: MouseEvent, view: EditorView) {\n view.focus();\n\n view.dom.classList.remove(\"dragging\");\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) return;\n\n const nodePos = nodePosAtDOM(node, view, options);\n if (!nodePos) return;\n\n view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));\n }\n\n let dragHandleElement: HTMLElement | null = null;\n\n function hideDragHandle() {\n if (dragHandleElement) {\n dragHandleElement.classList.add(\"hide\");\n }\n }\n\n function showDragHandle() {\n if (dragHandleElement) {\n dragHandleElement.classList.remove(\"hide\");\n }\n }\n\n return new Plugin({\n view: (view) => {\n dragHandleElement = document.createElement(\"div\");\n dragHandleElement.draggable = true;\n dragHandleElement.dataset.dragHandle = \"\";\n dragHandleElement.classList.add(\"drag-handle\");\n dragHandleElement.addEventListener(\"dragstart\", (e) => {\n handleDragStart(e, view);\n });\n dragHandleElement.addEventListener(\"click\", (e) => {\n handleClick(e, view);\n });\n\n hideDragHandle();\n\n view?.dom?.parentElement?.appendChild(dragHandleElement);\n\n return {\n destroy: () => {\n dragHandleElement?.remove?.();\n dragHandleElement = null;\n },\n };\n },\n props: {\n handleDOMEvents: {\n mousemove: (view, event) => {\n if (!view.editable) {\n return;\n }\n\n const node = nodeDOMAtCoords({\n x: event.clientX + 50 + options.dragHandleWidth,\n y: event.clientY,\n });\n\n if (!(node instanceof Element)) {\n hideDragHandle();\n return;\n }\n\n const compStyle = window.getComputedStyle(node);\n const lineHeight = parseInt(compStyle.lineHeight, 10);\n const paddingTop = parseInt(compStyle.paddingTop, 10);\n\n const rect = absoluteRect(node);\n\n rect.top += (lineHeight - 24) / 2;\n rect.top += paddingTop;\n // Li markers\n if (node.matches(\"ul:not([data-type=taskList]) li, ol li\")) {\n rect.left -= options.dragHandleWidth;\n }\n rect.width = options.dragHandleWidth;\n\n if (!dragHandleElement) return;\n\n dragHandleElement.style.left = `${rect.left - rect.width}px`;\n dragHandleElement.style.top = `${rect.top}px`;\n showDragHandle();\n },\n keydown: () => {\n hideDragHandle();\n },\n mousewheel: () => {\n hideDragHandle();\n },\n // dragging class is used for CSS\n dragstart: (view) => {\n view.dom.classList.add(\"dragging\");\n },\n drop: (view) => {\n view.dom.classList.remove(\"dragging\");\n },\n dragend: (view) => {\n view.dom.classList.remove(\"dragging\");\n },\n },\n },\n });\n}\n\nexport const DragAndDrop = Extension.create({\n name: \"dragAndDrop\",\n\n addProseMirrorPlugins() {\n return [\n DragHandle({\n dragHandleWidth: 24,\n }),\n ];\n },\n});\n\n","\"use client\";\nimport React, { useMemo, useState } from \"react\";\n\nimport TiptapUnderline from \"@tiptap/extension-underline\";\nimport TextStyle from \"@tiptap/extension-text-style\";\nimport { Color } from \"@tiptap/extension-color\";\n\nimport { Markdown } from \"tiptap-markdown\";\nimport Highlight from \"@tiptap/extension-highlight\";\n\nimport {\n EditorBubble,\n EditorCommand,\n EditorCommandEmpty,\n EditorCommandItem,\n EditorRoot,\n type JSONContent\n} from \"./components\";\nimport { Command, createSuggestionItems, renderItems } from \"./extensions\";\n\nimport { NodeSelector } from \"./selectors/node-selector\";\nimport { LinkSelector } from \"./selectors/link-selector\";\nimport { TextButtons } from \"./selectors/text-buttons\";\n\nimport {\n CheckBoxIcon,\n cls,\n CodeIcon,\n defaultBorderMixin,\n FormatListBulletedIcon,\n FormatListNumberedIcon,\n FormatQuoteIcon,\n ImageIcon,\n Looks3Icon,\n LooksOneIcon,\n LooksTwoIcon,\n Separator,\n TextFieldsIcon,\n useInjectStyles\n} from \"@firecms/ui\";\n// import { startImageUpload } from \"./plugins\";\nimport { Editor, EditorProvider, EditorProviderProps } from \"@tiptap/react\";\nimport { useDebouncedCallback } from \"./utils/useDebouncedCallback\";\nimport { removeClassesFromJson } from \"./utils/remove_classes\";\nimport { horizontalRule, placeholder, starterKit, taskItem, taskList, tiptapLink } from \"./editor_extensions\";\nimport { createImageExtension } from \"./extensions/Image\";\nimport { CustomKeymap } from \"./extensions/custom-keymap\";\nimport { DragAndDrop } from \"./extensions/drag-and-drop\";\n\nexport type FireCMSEditorProps = {\n initialContent?: JSONContent | string,\n onMarkdownContentChange?: (content: string) => void,\n onJsonContentChange?: (content: JSONContent | null) => void,\n onHtmlContentChange?: (content: string) => void,\n handleImageUpload: (file: File) => Promise<string>\n};\n\nexport const FireCMSEditor = ({\n handleImageUpload,\n initialContent,\n onJsonContentChange,\n onHtmlContentChange,\n onMarkdownContentChange\n }: FireCMSEditorProps) => {\n\n const defaultEditorProps: EditorProviderProps[\"editorProps\"] = {\n handleDOMEvents: {\n keydown: (_view, event) => {\n // prevent default event listeners from firing when slash command is active\n if ([\"ArrowUp\", \"ArrowDown\", \"Enter\"].includes(event.key)) {\n const slashCommand = document.querySelector(\"#slash-command\");\n if (slashCommand) {\n return true;\n }\n }\n return false;\n }\n },\n // handlePaste: (view, event) => {\n // if (event.clipboardData && event.clipboardData.files && event.clipboardData.files[0]) {\n // event.preventDefault();\n // const file = event.clipboardData.files[0];\n // const pos = view.state.selection.from;\n //\n // // startImageUpload({ file, view, pos, handleImageUpload });\n // return true;\n // }\n // return false;\n // },\n // handleDrop: (view, event, _slice, moved) => {\n // console.log(\"handleDrop\", { event, moved });\n // if (!moved && event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {\n // console.log(\"handleDrop!!!\", { event, moved });\n // event.preventDefault();\n // const file = event.dataTransfer.files[0];\n // const coordinates = view.posAtCoords({\n // left: event.clientX,\n // top: event.clientY\n // });\n // // here we deduct 1 from the pos or else the image will create an extra node\n // startImageUpload({\n // file,\n // view,\n // pos: coordinates?.pos || 0 - 1,\n // handleImageUpload,\n // });\n // return true;\n // }\n // return false;\n // }\n };\n\n const suggestionItems = createSuggestionItems([\n {\n title: \"Text\",\n description: \"Just start typing with plain text.\",\n searchTerms: [\"p\", \"paragraph\"],\n icon: <TextFieldsIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .toggleNode(\"paragraph\", \"paragraph\")\n .run();\n }\n },\n {\n title: \"To-do List\",\n description: \"Track tasks with a to-do list.\",\n searchTerms: [\"todo\", \"task\", \"list\", \"check\", \"checkbox\"],\n icon: <CheckBoxIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleTaskList().run();\n }\n },\n {\n title: \"Heading 1\",\n description: \"Big section heading.\",\n searchTerms: [\"title\", \"big\", \"large\"],\n icon: <LooksOneIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 1 })\n .run();\n }\n },\n {\n title: \"Heading 2\",\n description: \"Medium section heading.\",\n searchTerms: [\"subtitle\", \"medium\"],\n icon: <LooksTwoIcon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 2 })\n .run();\n }\n },\n {\n title: \"Heading 3\",\n description: \"Small section heading.\",\n searchTerms: [\"subtitle\", \"small\"],\n icon: <Looks3Icon size={18}/>,\n command: ({ editor, range }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .setNode(\"heading\", { level: 3 })\n .run();\n }\n },\n {\n title: \"Bullet List\",\n description: \"Create a simple bullet list.\",\n searchTerms: [\"unordered\", \"point\"],\n icon: <FormatListBulletedIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleBulletList().run();\n }\n },\n {\n title: \"Numbered List\",\n description: \"Create a list with numbering.\",\n searchTerms: [\"ordered\"],\n icon: <FormatListNumberedIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).toggleOrderedList().run();\n }\n },\n {\n title: \"Quote\",\n description: \"Capture a quote.\",\n searchTerms: [\"blockquote\"],\n icon: <FormatQuoteIcon size={18}/>,\n command: ({ editor, range }) =>\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .toggleNode(\"paragraph\", \"paragraph\")\n .toggleBlockquote()\n .run()\n },\n {\n title: \"Code\",\n description: \"Capture a code snippet.\",\n searchTerms: [\"codeblock\"],\n icon: <CodeIcon size={18}/>,\n command: ({ editor, range }) =>\n editor.chain().focus().deleteRange(range).toggleCodeBlock().run()\n },\n {\n title: \"Image\",\n description: \"Upload an image from your computer.\",\n searchTerms: [\"photo\", \"picture\", \"media\"],\n icon: <ImageIcon size={18}/>,\n command: ({ editor, range }) => {\n editor.chain().focus().deleteRange(range).run();\n // upload image\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*\";\n input.onchange = async () => {\n if (input.files?.length) {\n const file = input.files[0];\n if (!file) return;\n const pos = editor.view.state.selection.from;\n // startImageUpload({\n // file,\n // view: editor.view,\n // pos,\n // handleImageUpload\n // });\n }\n };\n input.click();\n }\n }\n ]);\n\n const slashCommand = Command.configure({\n suggestion: {\n items: () => suggestionItems,\n render: renderItems\n }\n });\n\n const imageExtension = useMemo(() => createImageExtension(handleImageUpload), []);\n\n const extensions = [\n TiptapUnderline,\n TextStyle,\n Color,\n Highlight.configure({\n multicolor: true,\n }),\n Markdown.configure({\n html: false,\n transformCopiedText: true,\n }),\n CustomKeymap,\n DragAndDrop,\n starterKit,\n placeholder,\n tiptapLink,\n // tiptapImage,\n imageExtension,\n // updatedImage,\n taskList,\n taskItem,\n horizontalRule,\n slashCommand];\n const [openNode, setOpenNode] = useState(false);\n const [openLink, setOpenLink] = useState(false);\n\n useInjectStyles(\"Editor\", cssStyles);\n\n const editorRef = React.useRef<Editor | null>(null);\n const [markdownContent, setMarkdownContent] = useState<string | null>(null);\n const [jsonContent, setJsonContent] = useState<JSONContent | null>(null);\n const [htmlContent, setHtmlContent] = useState<string | null>(null);\n\n const onEditorUpdate = (editor: Editor) => {\n editorRef.current = editor;\n if (onMarkdownContentChange) {\n setMarkdownContent(editor.storage.markdown.getMarkdown());\n }\n if (onJsonContentChange) {\n setJsonContent(removeClassesFromJson(editor.getJSON()));\n }\n if (onHtmlContentChange) {\n setHtmlContent(editor.getHTML());\n }\n }\n\n useDebouncedCallback(markdownContent, () => {\n\n if (editorRef.current) {\n const markdown = editorRef.current.storage.markdown.getMarkdown();\n onMarkdownContentChange?.(addLineBreakAfterImages(markdown));\n }\n }, false, 500);\n\n useDebouncedCallback(jsonContent, () => {\n if (jsonContent)\n onJsonContentChange?.(jsonContent);\n }, false, 500);\n\n useDebouncedCallback(htmlContent, () => {\n if (htmlContent)\n onHtmlContentChange?.(htmlContent);\n }, false, 500);\n\n if (!initialContent) return null;\n\n return (\n <div className=\"relative w-full p-8\">\n <EditorRoot>\n <div\n className=\"relative min-h-[500px] w-full bg-white dark:bg-gray-950 rounded-lg\">\n <EditorProvider\n content={initialContent}\n extensions={extensions}\n editorProps={{\n ...defaultEditorProps,\n attributes: {\n class: \"prose-lg prose-headings:font-title font-default focus:outline-none max-w-full p-12\"\n }\n }}\n onUpdate={({ editor }) => {\n console.debug(\"Editor updated\");\n onEditorUpdate(editor as Editor);\n }}>\n\n <EditorCommand\n className={cls(\"text-gray-900 dark:text-white z-50 h-auto max-h-[330px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-gray-900 px-1 py-2 shadow transition-all\", defaultBorderMixin)}>\n <EditorCommandEmpty className=\"px-2 text-gray-700 dark:text-slate-300\">\n No results\n </EditorCommandEmpty>\n {suggestionItems.map((item) => (\n <EditorCommandItem\n value={item.title}\n onCommand={(val) => item?.command?.(val)}\n className={\"flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-gray-700 aria-selected:bg-blue-50 aria-selected:dark:bg-gray-700\"}\n key={item.title}\n >\n <div\n className={cls(\"flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-gray-900\", defaultBorderMixin)}>\n {item.icon}\n </div>\n <div>\n <p className=\"font-medium\">{item.title}</p>\n <p className=\"text-xs text-gray-700 dark:text-slate-300\">\n {item.description}\n </p>\n </div>\n </EditorCommandItem>\n ))}\n </EditorCommand>\n\n <EditorBubble\n tippyOptions={{\n placement: \"top\"\n }}\n className={cls(\"flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-gray-900 shadow\", defaultBorderMixin)}\n >\n {/*<Separator orientation=\"vertical\"/>*/}\n <NodeSelector open={openNode} onOpenChange={setOpenNode}/>\n <Separator orientation=\"vertical\"/>\n\n <LinkSelector open={openLink} onOpenChange={setOpenLink}/>\n <Separator orientation=\"vertical\"/>\n <TextButtons/>\n {/*<Separator orientation=\"vertical\"/>*/}\n {/*<ColorSelector open={openColor} onOpenChange={setOpenColor}/>*/}\n </EditorBubble>\n\n </EditorProvider>\n </div>\n\n </EditorRoot>\n </div>\n );\n};\n\nfunction addLineBreakAfterImages(markdown: string): string {\n // Regular expression to match markdown image syntax\n const imageRegex = /!\\[.*?\\]\\(.*?\\)/g;\n // Replace image with image followed by a line break\n return markdown.replace(imageRegex, (match) => `${match}\\n`);\n}\n\nconst cssStyles = `\n\n.ProseMirror .is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n float: left;\n color: rgb(100 116 139); //500\n pointer-events: none;\n height: 0;\n}\n.ProseMirror .is-empty::before {\n content: attr(data-placeholder);\n float: left;\n color: rgb(100 116 139); //500\n pointer-events: none;\n height: 0;\n}\n\n[data-theme=\"dark\"] {\n .ProseMirror .is-empty::before {\n color: rgb(100 116 139); //500\n }\n}\n\n.is-empty {\n color: rgb(100 116 139); //500\n}\n\n\n/* Custom image styles */\n\n.ProseMirror img {\n transition: filter 0.1s ease-in-out;\n\n &:hover {\n cursor: pointer;\n filter: brightness(90%);\n }\n\n &.ProseMirror-selectednode {\n outline: 3px solid #5abbf7;\n filter: brightness(90%);\n }\n}\n\n/* Custom TODO list checkboxes – shoutout to this awesome tutorial: https://moderncss.dev/pure-css-custom-checkbox-style/ */\n\nul[data-type=\"taskList\"] li > label {\n margin-right: 0.2rem;\n user-select: none;\n}\n\n@media screen and (max-width: 768px) {\n ul[data-type=\"taskList\"] li > label {\n margin-right: 0.5rem;\n }\n}\n\n\n[data-theme=\"dark\"] {\n ul[data-type=\"taskList\"] li > label input[type=\"checkbox\"] {\n background-color: rgb(30 41 59); // 800\n border: 2px solid #666;\n \n &:hover {\n background-color: rgb(51 65 85); // 700\n }\n \n &:active {\n background-color: rgb(71 85 105);;\n }\n }\n}\n \n\nul[data-type=\"taskList\"] li > label input[type=\"checkbox\"] {\n -webkit-appearance: none;\n appearance: none;\n background-color: white;\n margin: 0;\n cursor: pointer;\n width: 1.2em;\n height: 1.2em;\n position: relative;\n top: 5px;\n border: 2px solid #777;\n border-radius: 0.25em;\n margin-right: 0.3rem;\n display: grid;\n place-content: center;\n\n &:hover {\n background-color: rgb(241 245 249); //100\n }\n\n &:active {\n background-color: rgb(226 232 240); //200\n }\n\n &::before {\n content: \"\";\n width: 0.65em;\n height: 0.65em;\n transform: scale(0);\n transition: 120ms transform ease-in-out;\n box-shadow: inset 1em 1em;\n transform-origin: center;\n clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);\n }\n\n &:checked::before {\n transform: scale(1);\n }\n}\n\n[data-theme=\"dark\"] {\n ul[data-type=\"taskList\"] li[data-checked=\"true\"] > div > p {\n color: rgb(226 232 240);\n text-decoration: line-through;\n text-decoration-thickness: 2px;\n }\n}\n\nul[data-type=\"taskList\"] li[data-checked=\"true\"] > div > p {\n color: rgb(51 65 85); // 700\n text-decoration: line-through;\n text-decoration-thickness: 2px;\n}\n\n/* Overwrite tippy-box original max-width */\n\n.tippy-box {\n max-width: 400px !important;\n}\n\n.ProseMirror:not(.dragging) .ProseMirror-selectednode {\n outline: none !important;\n background-color: rgb(219 234 254); // blue 100\n transition: background-color 0.2s;\n box-shadow: none;\n}\n\n[data-theme=\"dark\"] .ProseMirror:not(.dragging) .ProseMirror-selectednode {\n background-color: rgb(51 65 85); // 700\n}\n\n.drag-handle {\n position: fixed;\n opacity: 1;\n transition: opacity ease-in 0.2s;\n border-radius: 0.25rem;\n\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' style='fill: rgba(128, 128, 128, 0.9)'%3E%3Cpath d='M3,2 C2.44771525,2 2,1.55228475 2,1 C2,0.44771525 2.44771525,0 3,0 C3.55228475,0 4,0.44771525 4,1 C4,1.55228475 3.55228475,2 3,2 Z M3,6 C2.44771525,6 2,5.55228475 2,5 C2,4.44771525 2.44771525,4 3,4 C3.55228475,4 4,4.44771525 4,5 C4,5.55228475 3.55228475,6 3,6 Z M3,10 C2.44771525,10 2,9.55228475 2,9 C2,8.44771525 2.44771525,8 3,8 C3.55228475,8 4,8.44771525 4,9 C4,9.55228475 3.55228475,10 3,10 Z M7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 C7.55228475,0 8,0.44771525 8,1 C8,1.55228475 7.55228475,2 7,2 Z M7,6 C6.44771525,6 6,5.55228475 6,5 C6,4.44771525 6.44771525,4 7,4 C7.55228475,4 8,4.44771525 8,5 C8,5.55228475 7.55228475,6 7,6 Z M7,10 C6.44771525,10 6,9.55228475 6,9 C6,8.44771525 6.44771525,8 7,8 C7.55228475,8 8,8.44771525 8,9 C8,9.55228475 7.55228475,10 7,10 Z'%3E%3C/path%3E%3C/svg%3E\");\n background-size: calc(0.5em + 0.375rem) calc(0.5em + 0.375rem);\n background-repeat: no-repeat;\n background-position: center;\n width: 1.2rem;\n height: 1.5rem;\n z-index: 50;\n cursor: grab;\n\n &:hover {\n background-color: rgb(241 245 249); //100\n transition: background-color 0.2s;\n }\n\n &:active {\n background-color: rgb(226 232 240); //200\n transition: background-color 0.2s;\n }\n\n &.hide {\n opacity: 0;\n pointer-events: none;\n }\n\n @media screen and (max-width: 600px) {\n display: none;\n pointer-events: none;\n }\n}\n\n[data-theme=\"dark\"] .drag-handle {\n &:hover {\n background-color: rgb(51 65 85); // 700\n }\n\n &:active {\n background-color: rgb(51 65 85); // 700\n }\n}\n`;\n"],"names":["editorStore","createStore","EditorRoot","children","jsx","Provider","EditorBubble","forwardRef","tippyOptions","rest","ref","editor","useCurrentEditor","instanceRef","useRef","useEffect","bubbleMenuProps","useMemo","state","selection","empty","isNodeSelection","val","BubbleMenu","EditorBubbleItem","asChild","onSelect","Comp","Slot","t","tunnel","queryAtom","atom","rangeAtom","EditorCommandOut","query","range","setQuery","useSetAtom","setRange","navigationKeys","onKeyDown","e","commandRef","EditorCommand","className","commandListRef","useAtom","jsxs","Command","EditorCommandItem","onCommand","useAtomValue","CommandItem","EditorCommandEmpty","CommandEmpty","Extension","props","Suggestion","renderItems","component","popup","ReactRenderer","tippy","createSuggestionItems","items","PlaceholderExtension","Placeholder","node","Horizontal","HorizontalRule","InputRule","attributes","tr","start","end","TextFieldsIcon","LooksOneIcon","LooksTwoIcon","Looks3Icon","CheckBoxIcon","FormatListBulletedIcon","FormatListNumberedIcon","FormatQuoteIcon","CodeIcon","NodeSelector","open","onOpenChange","useEditor","activeItem","item","Popover","Button","ExpandMoreIcon","index","CheckIcon","isValidUrl","url","getUrlFromString","str","LinkSelector","inputRef","cls","target","input","DeleteIcon","TextButtons","FormatBoldIcon","FormatItalicIcon","FormatUnderlinedIcon","FormatStrikethroughIcon","useDebouncedCallback","value","callback","immediate","timeoutMs","pendingUpdate","React","performUpdate","handlerRef","removeClassesFromJson","jsonObj","key","placeholder","tiptapLink","TiptapLink","taskList","TaskList","taskItem","TaskItem","horizontalRule","defaultBorderMixin","starterKit","StarterKit","onFileRead","plugin","view","readerEvent","pos","upload","image","schema","decorationSet","imageElement","deco","Decoration","src","imageNode","dropImagePlugin","Plugin","DecorationSet","old","meta","event","images","file","position","reader","slice","anyImageFound","editorView","prevState","prevDecos","newDecos","createImageExtension","uploadFn","TiptapImage","CustomKeymap","commands","startNodePos","endNodePos","startSelectionPos","endSelectionPos","absoluteRect","data","nodeDOMAtCoords","coords","elem","nodePosAtDOM","options","boundingRect","DragHandle","handleDragStart","nodePos","NodeSelection","dom","text","__serializeForClipboard","handleClick","dragHandleElement","hideDragHandle","showDragHandle","compStyle","lineHeight","paddingTop","rect","DragAndDrop","FireCMSEditor","handleImageUpload","initialContent","onJsonContentChange","onHtmlContentChange","onMarkdownContentChange","defaultEditorProps","_view","suggestionItems","ImageIcon","slashCommand","imageExtension","extensions","TiptapUnderline","TextStyle","Color","Highlight","Markdown","openNode","setOpenNode","useState","openLink","setOpenLink","useInjectStyles","cssStyles","editorRef","markdownContent","setMarkdownContent","jsonContent","setJsonContent","htmlContent","setHtmlContent","onEditorUpdate","markdown","addLineBreakAfterImages","EditorProvider","Separator","imageRegex","match"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(u,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("react/jsx-runtime"),require("react"),require("@tiptap/extension-underline"),require("@tiptap/extension-text-style"),require("@tiptap/extension-color"),require("tiptap-markdown"),require("@tiptap/extension-highlight"),require("@tiptap/react"),require("jotai"),require("@radix-ui/react-slot"),require("tunnel-rat"),require("cmdk"),require("@tiptap/starter-kit"),require("@tiptap/extension-horizontal-rule"),require("@tiptap/extension-link"),require("@tiptap/extension-image"),require("@tiptap/extension-placeholder"),require("@tiptap/extension-task-item"),require("@tiptap/extension-task-list"),require("@tiptap/core"),require("@tiptap/suggestion"),require("tippy.js"),require("@firecms/ui"),require("prosemirror-state"),require("@tiptap/pm/view"),require("@tiptap/pm/state")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","@tiptap/extension-underline","@tiptap/extension-text-style","@tiptap/extension-color","tiptap-markdown","@tiptap/extension-highlight","@tiptap/react","jotai","@radix-ui/react-slot","tunnel-rat","cmdk","@tiptap/starter-kit","@tiptap/extension-horizontal-rule","@tiptap/extension-link","@tiptap/extension-image","@tiptap/extension-placeholder","@tiptap/extension-task-item","@tiptap/extension-task-list","@tiptap/core","@tiptap/suggestion","tippy.js","@firecms/ui","prosemirror-state","@tiptap/pm/view","@tiptap/pm/state"],o):(u=typeof globalThis<"u"?globalThis:u||self,o(u["FireCMS Editor"]={},u.jsxRuntime,u.React,u.TiptapUnderline,u.TextStyle,u.extensionColor,u.tiptapMarkdown,u.Highlight,u.react,u.jotai,u.reactSlot,u.tunnel,u.cmdk,u.StarterKit,u.HorizontalRule,u.TiptapLink,u.TiptapImage,u.Placeholder,u.extensionTaskItem,u.extensionTaskList,u.core,u.Suggestion,u.tippy,u.ui,u.prosemirrorState,u.view,u.state))})(this,function(u,o,g,W,Q,Z,_,V,b,y,X,Y,C,J,G,$,j,R,ee,te,w,re,ne,s,oe,A,E){"use strict";const T=y.createStore(),se=({children:e})=>o.jsx(y.Provider,{store:T,children:e}),ae=g.forwardRef(({children:e,tippyOptions:r,...t},n)=>{const{editor:i}=b.useCurrentEditor(),d=g.useRef(null);g.useEffect(()=>{!d.current||!r?.placement||(d.current.setProps({placement:r.placement}),d.current.popperInstance?.update())},[r?.placement]);const a=g.useMemo(()=>({shouldShow:({editor:m,state:p})=>{const{selection:h}=p,{empty:k}=h;return!(m.isActive("image")||k||b.isNodeSelection(h))},tippyOptions:{onCreate:m=>{d.current=m},moveTransition:"transform 0.15s ease-out",...r},...t}),[t,r]);return i?o.jsx("div",{ref:n,children:o.jsx(b.BubbleMenu,{editor:i,...a,children:e})}):null}),S=g.forwardRef(({children:e,asChild:r,onSelect:t,...n},i)=>{const{editor:d}=b.useCurrentEditor(),a=r?X.Slot:"div";return d?o.jsx(a,{ref:i,...n,onClick:()=>t?.(d),children:e}):null});S.displayName="EditorBubbleItem";const q=Y(),D=y.atom(""),z=y.atom(null),ie=({query:e,range:r})=>{const t=y.useSetAtom(D,{store:T}),n=y.useSetAtom(z,{store:T});return g.useEffect(()=>{t(e)},[e,t]),g.useEffect(()=>{n(r)},[r,n]),g.useEffect(()=>{const i=["ArrowUp","ArrowDown","Enter"],d=a=>{if(i.includes(a.key)){a.preventDefault();const c=document.querySelector("#slash-command");c&&c.dispatchEvent(new KeyboardEvent("keydown",{key:a.key,cancelable:!0,bubbles:!0}))}};return document.addEventListener("keydown",d),()=>{document.removeEventListener("keydown",d)}},[]),o.jsx(q.Out,{})},ce=g.forwardRef(({children:e,className:r,...t},n)=>{const i=g.useRef(null),[d,a]=y.useAtom(D);return o.jsx(q.In,{children:o.jsxs(C.Command,{ref:n,onKeyDown:c=>{c.stopPropagation()},id:"slash-command",className:r,...t,children:[o.jsx(C.Command.Input,{value:d,onValueChange:a,style:{display:"none"}}),o.jsx(C.Command.List,{ref:i,children:e})]})})}),F=g.forwardRef(({children:e,onCommand:r,...t},n)=>{const{editor:i}=b.useCurrentEditor(),d=y.useAtomValue(z);return!i||!d?null:o.jsx(C.CommandItem,{ref:n,...t,onSelect:()=>r({editor:i,range:d}),children:e})});F.displayName="EditorCommandItem";const de=C.CommandEmpty,le=w.Extension.create({name:"slash-command",addOptions(){return{suggestion:{char:"/",command:({editor:e,range:r,props:t})=>{t.command({editor:e,range:r})}}}},addProseMirrorPlugins(){return[re({editor:this.editor,...this.options.suggestion})]}}),ue=()=>{let e=null,r=null;return{onStart:t=>{e=new b.ReactRenderer(ie,{props:t,editor:t.editor}),r=ne("body",{getReferenceClientRect:t.clientRect,appendTo:()=>document.body,content:e.element,showOnCreate:!0,interactive:!0,trigger:"manual",placement:"bottom-start"})},onUpdate:t=>{e?.updateProps(t),r&&r[0].setProps({getReferenceClientRect:t.clientRect})},onKeyDown:t=>t.event.key==="Escape"?(r?.[0].hide(),!0):e?.ref?.onKeyDown(t),onExit:()=>{r?.[0].destroy(),e?.destroy()}}},me=e=>e,pe=R.configure({placeholder:({node:e})=>e.type.name==="heading"?`Heading ${e.attrs.level}`:"Press '/' for commands",includeChildren:!0}),ge=G.extend({addInputRules(){return[new w.InputRule({find:/^(?:---|—-|___\s|\*\*\*\s)$/,handler:({state:e,range:r})=>{const t={},{tr:n}=e,i=r.from,d=r.to;n.insert(i-1,this.type.create(t)).delete(n.mapping.map(i),n.mapping.map(d))}})]}}),U=[{name:"Text",icon:s.TextFieldsIcon,command:e=>e?.chain().focus().toggleNode("paragraph","paragraph").run(),isActive:e=>(e?.isActive("paragraph")&&!e?.isActive("bulletList")&&!e?.isActive("orderedList"))??!1},{name:"Heading 1",icon:s.LooksOneIcon,command:e=>e?.chain().focus().toggleHeading({level:1}).run(),isActive:e=>e?.isActive("heading",{level:1})??!1},{name:"Heading 2",icon:s.LooksTwoIcon,command:e=>e?.chain().focus().toggleHeading({level:2}).run(),isActive:e=>e?.isActive("heading",{level:2})??!1},{name:"Heading 3",icon:s.Looks3Icon,command:e=>e?.chain().focus().toggleHeading({level:3}).run(),isActive:e=>e?.isActive("heading",{level:3})??!1},{name:"To-do List",icon:s.CheckBoxIcon,command:e=>e?.chain().focus().toggleTaskList().run(),isActive:e=>e?.isActive("taskItem")??!1},{name:"Bullet List",icon:s.FormatListBulletedIcon,command:e=>e?.chain().focus().toggleBulletList().run(),isActive:e=>e?.isActive("bulletList")??!1},{name:"Numbered List",icon:s.FormatListNumberedIcon,command:e=>e?.chain().focus().toggleOrderedList().run(),isActive:e=>e?.isActive("orderedList")??!1},{name:"Quote",icon:s.FormatQuoteIcon,command:e=>e?.chain().focus().toggleNode("paragraph","paragraph").toggleBlockquote().run(),isActive:e=>e?.isActive("blockquote")??!1},{name:"Code",icon:s.CodeIcon,command:e=>e?.chain().focus().toggleCodeBlock().run(),isActive:e=>e?.isActive("codeBlock")??!1}],fe=({open:e,onOpenChange:r})=>{const{editor:t}=b.useCurrentEditor();if(!t)return null;const n=U.filter(i=>i.isActive(t)).pop()??{name:"Multiple"};return o.jsx(s.Popover,{sideOffset:5,align:"start",className:"w-48 p-1",trigger:o.jsxs(s.Button,{variant:"text",className:"gap-2 rounded-none",color:"text",children:[o.jsx("span",{className:"whitespace-nowrap text-sm",children:n.name}),o.jsx(s.ExpandMoreIcon,{size:"small"})]}),modal:!0,open:e,onOpenChange:r,children:U.map((i,d)=>o.jsxs(S,{onSelect:a=>{i.command(a),r(!1)},className:"flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-gray-700 text-gray-900 dark:text-white",children:[o.jsxs("div",{className:"flex items-center space-x-2",children:[o.jsx(i.icon,{size:"smallest"}),o.jsx("span",{children:i.name})]}),n.name===i.name&&o.jsx(s.CheckIcon,{size:"smallest"})]},d))})};function he(e){try{return new URL(e),!0}catch{return!1}}function xe(e){if(he(e))return e;try{return e.includes(".")&&!e.includes(" ")?new URL(`https://${e}`).toString():null}catch{return null}}const ke=({open:e,onOpenChange:r})=>{const t=g.useRef(null),{editor:n}=b.useCurrentEditor();return g.useEffect(()=>{t.current&&t.current?.focus()}),n?o.jsx(s.Popover,{modal:!0,open:e,onOpenChange:r,trigger:o.jsx(s.Button,{variant:"text",className:"gap-2 rounded-none",color:"text",children:o.jsx("p",{className:s.cn("underline decoration-stone-400 underline-offset-4",{"text-blue-500":n.isActive("link")}),children:"Link"})}),children:o.jsxs("form",{onSubmit:i=>{const d=i.currentTarget;i.preventDefault();const a=d[0],c=xe(a.value);c&&n.chain().focus().setLink({href:c}).run()},className:"flex p-1",children:[o.jsx("input",{ref:t,autoFocus:e,placeholder:"Paste a link",defaultValue:n.getAttributes("link").href||"",className:"text-gray-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none"}),n.getAttributes("link").href?o.jsx(s.Button,{size:"small",variant:"text",type:"button",color:"text",className:"flex items-center",onClick:()=>{n.chain().focus().unsetLink().run()},children:o.jsx(s.DeleteIcon,{size:"small"})}):o.jsx(s.Button,{size:"small",variant:"text",children:o.jsx(s.CheckIcon,{size:"small"})})]})}):null},be=()=>{const{editor:e}=b.useCurrentEditor();if(!e)return null;const r=[{name:"bold",isActive:t=>t?.isActive("bold")??!1,command:t=>t?.chain().focus().toggleBold().run(),icon:s.FormatBoldIcon},{name:"italic",isActive:t=>t?.isActive("italic")??!1,command:t=>t?.chain().focus().toggleItalic().run(),icon:s.FormatItalicIcon},{name:"underline",isActive:t=>t?.isActive("underline")??!1,command:t=>t?.chain().focus().toggleUnderline().run(),icon:s.FormatUnderlinedIcon},{name:"strike",isActive:t=>t?.isActive("strike")??!1,command:t=>t?.chain().focus().toggleStrike().run(),icon:s.FormatStrikethroughIcon},{name:"code",isActive:t=>t?.isActive("code")??!1,command:t=>t?.chain().focus().toggleCode().run(),icon:s.CodeIcon}];return o.jsx("div",{className:"flex",children:r.map((t,n)=>o.jsx(S,{onSelect:i=>{t.command(i)},children:o.jsx(s.Button,{size:"small",color:"text",className:"gap-2 rounded-none h-full",variant:"text",children:o.jsx(t.icon,{className:s.cn({"text-inherit":!t.isActive(e),"text-blue-500":t.isActive(e)})})})},n))})};function M(e,r,t,n=300){const i=g.useRef(!1),d=()=>{r(),i.current=!1},a=g.useRef(void 0);g.useEffect(()=>(i.current=!0,clearTimeout(a.current),a.current=setTimeout(d,n),()=>{t&&d()}),[t,e])}function I(e){return Array.isArray(e)?e.map(r=>I(r)):(typeof e=="object"&&e!==null&&(e.attrs&&typeof e.attrs=="object"&&"class"in e.attrs&&delete e.attrs.class,Object.keys(e).forEach(r=>{e[r]=I(e[r])})),e)}const ye=pe,ve=$.configure({HTMLAttributes:{class:s.cn("text-gray-600 dark:text-slate-300 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer")}}),Ce=te.TaskList.configure({HTMLAttributes:{class:s.cn("not-prose")}}),we=ee.TaskItem.configure({HTMLAttributes:{class:s.cn("flex items-start my-4")},nested:!0}),Le=ge.configure({HTMLAttributes:{class:s.cn("mt-4 mb-6 border-t",s.defaultBorderMixin)}}),Ae=J.configure({bulletList:{HTMLAttributes:{class:s.cn("list-disc list-outside leading-3 -mt-2")}},orderedList:{HTMLAttributes:{class:s.cn("list-decimal list-outside leading-3 -mt-2")}},listItem:{HTMLAttributes:{class:s.cn("leading-normal -mb-2")}},blockquote:{HTMLAttributes:{class:s.cn("border-l-4 border-primary")}},codeBlock:{HTMLAttributes:{class:s.cn("rounded bg-blue-50 dark:bg-gray-700 border p-5 font-mono font-medium",s.defaultBorderMixin)}},code:{HTMLAttributes:{class:s.cn("rounded-md bg-slate-50 dark:bg-gray-700 px-1.5 py-1 font-mono font-medium"),spellcheck:"false"}},horizontalRule:!1,dropcursor:{color:"#DBEAFE",width:4},gapcursor:!1});async function K(e,r,t,n,i,d){const{schema:a}=r.state;let c=e.getState(r.state);const m=document.createElement("div"),p=document.createElement("img");p.setAttribute("class","opacity-40 rounded-lg border border-stone-200"),p.src=t.target?.result,m.appendChild(p);const h=A.Decoration.widget(n,m);c=c?.add(r.state.doc,[h]),r.dispatch(r.state.tr.setMeta(e,{decorationSet:c}));const k=await i(d);console.log("uploaded image",k);const x=a.nodes.image.create({src:k}),L=r.state.tr.replaceWith(n,n,x);c=c?.remove([h]),L.setMeta(e,{decorationSet:c}),r.dispatch(L)}const Ee=e=>{const r=new oe.Plugin({state:{init:()=>A.DecorationSet.empty,apply:(t,n)=>{const i=t.getMeta(r);return i&&i.decorationSet?i.decorationSet:n.map(t.mapping,t.doc)}},props:{handleDOMEvents:{drop:(t,n)=>{if(console.log("drop event",n),!n.dataTransfer?.files||n.dataTransfer?.files.length===0)return!1;n.preventDefault();const d=Array.from(n.dataTransfer.files).filter(a=>/image/i.test(a.type));return d.length===0?!1:(d.forEach(a=>{const c=t.posAtCoords({left:n.clientX,top:n.clientY});if(!c)return;const m=new FileReader;m.onload=async p=>{await K(r,t,p,c.pos,e,a)},m.readAsDataURL(a)}),!0)}},handlePaste(t,n,i){const d=Array.from(n.clipboardData?.items||[]),a=t.state.selection.from;console.log("pos",a);let c=!1;return d.forEach(m=>{const p=m.getAsFile();if(console.log("image",p),p){c=!0;const h=new FileReader;h.onload=async k=>{await K(r,t,k,a,e,p)},h.readAsDataURL(p)}}),c},decorations(t){return r.getState(t)}},view(t){return{update(n,i){const d=r.getState(i),a=r.getState(n.state);d!==a&&n.updateState(n.state)}}}});return r},Te=e=>j.extend({addProseMirrorPlugins(){return[Ee(e)]}}).configure({allowBase64:!0,HTMLAttributes:{class:s.cn("rounded-lg border",s.defaultBorderMixin)}}),Se=w.Extension.create({name:"CustomKeymap",addCommands(){return{selectTextWithinNodeBoundaries:()=>({editor:e,commands:r})=>{const{state:t}=e,{tr:n}=t,i=n.selection.$from.start(),d=n.selection.$to.end();return r.setTextSelection({from:i,to:d})}}},addKeyboardShortcuts(){return{"Mod-a":({editor:e})=>{const{state:r}=e,{tr:t}=r,n=t.selection.from,i=t.selection.to,d=t.selection.$from.start(),a=t.selection.$to.end();return n>d||i<a?(e.chain().selectTextWithinNodeBoundaries().run(),!0):!1}}}});function Me(e){const r=e.getBoundingClientRect();return{top:r.top,left:r.left,width:r.width}}function N(e){return document.elementsFromPoint(e.x,e.y).find(r=>r.parentElement?.matches?.(".ProseMirror")||r.matches(["li","p:not(:first-child)","pre","blockquote","h1, h2, h3, h4, h5, h6"].join(", ")))}function O(e,r,t){const n=e.getBoundingClientRect();return r.posAtCoords({left:n.left+50+t.dragHandleWidth,top:n.top+1})?.inside}function Ie(e){function r(a,c){if(c.focus(),!a.dataTransfer)return;const m=N({x:a.clientX+50+e.dragHandleWidth,y:a.clientY});if(!(m instanceof Element))return;const p=O(m,c,e);if(p==null||p<0)return;c.dispatch(c.state.tr.setSelection(E.NodeSelection.create(c.state.doc,p)));const h=c.state.selection.content(),{dom:k,text:x}=A.__serializeForClipboard(c,h);a.dataTransfer.clearData(),a.dataTransfer.setData("text/html",k.innerHTML),a.dataTransfer.setData("text/plain",x),a.dataTransfer.effectAllowed="copyMove",a.dataTransfer.setDragImage(m,0,0),c.dragging={slice:h,move:a.ctrlKey}}function t(a,c){c.focus(),c.dom.classList.remove("dragging");const m=N({x:a.clientX+50+e.dragHandleWidth,y:a.clientY});if(!(m instanceof Element))return;const p=O(m,c,e);p&&c.dispatch(c.state.tr.setSelection(E.NodeSelection.create(c.state.doc,p)))}let n=null;function i(){n&&n.classList.add("hide")}function d(){n&&n.classList.remove("hide")}return new E.Plugin({view:a=>(n=document.createElement("div"),n.draggable=!0,n.dataset.dragHandle="",n.classList.add("drag-handle"),n.addEventListener("dragstart",c=>{r(c,a)}),n.addEventListener("click",c=>{t(c,a)}),i(),a?.dom?.parentElement?.appendChild(n),{destroy:()=>{n?.remove?.(),n=null}}),props:{handleDOMEvents:{mousemove:(a,c)=>{if(!a.editable)return;const m=N({x:c.clientX+50+e.dragHandleWidth,y:c.clientY});if(!(m instanceof Element)){i();return}const p=window.getComputedStyle(m),h=parseInt(p.lineHeight,10),k=parseInt(p.paddingTop,10),x=Me(m);x.top+=(h-24)/2,x.top+=k,m.matches("ul:not([data-type=taskList]) li, ol li")&&(x.left-=e.dragHandleWidth),x.width=e.dragHandleWidth,n&&(n.style.left=`${x.left-x.width}px`,n.style.top=`${x.top}px`,d())},keydown:()=>{i()},mousewheel:()=>{i()},dragstart:a=>{a.dom.classList.add("dragging")},drop:a=>{a.dom.classList.remove("dragging")},dragend:a=>{a.dom.classList.remove("dragging")}}}})}const Ne=w.Extension.create({name:"dragAndDrop",addProseMirrorPlugins(){return[Ie({dragHandleWidth:24})]}}),Pe=({handleImageUpload:e,initialContent:r,onJsonContentChange:t,onHtmlContentChange:n,onMarkdownContentChange:i})=>{const d={handleDOMEvents:{keydown:(l,f)=>!!(["ArrowUp","ArrowDown","Enter"].includes(f.key)&&document.querySelector("#slash-command"))}},a=me([{title:"Text",description:"Just start typing with plain text.",searchTerms:["p","paragraph"],icon:o.jsx(s.TextFieldsIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).toggleNode("paragraph","paragraph").run()}},{title:"To-do List",description:"Track tasks with a to-do list.",searchTerms:["todo","task","list","check","checkbox"],icon:o.jsx(s.CheckBoxIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).toggleTaskList().run()}},{title:"Heading 1",description:"Big section heading.",searchTerms:["title","big","large"],icon:o.jsx(s.LooksOneIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).setNode("heading",{level:1}).run()}},{title:"Heading 2",description:"Medium section heading.",searchTerms:["subtitle","medium"],icon:o.jsx(s.LooksTwoIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).setNode("heading",{level:2}).run()}},{title:"Heading 3",description:"Small section heading.",searchTerms:["subtitle","small"],icon:o.jsx(s.Looks3Icon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).setNode("heading",{level:3}).run()}},{title:"Bullet List",description:"Create a simple bullet list.",searchTerms:["unordered","point"],icon:o.jsx(s.FormatListBulletedIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).toggleBulletList().run()}},{title:"Numbered List",description:"Create a list with numbering.",searchTerms:["ordered"],icon:o.jsx(s.FormatListNumberedIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).toggleOrderedList().run()}},{title:"Quote",description:"Capture a quote.",searchTerms:["blockquote"],icon:o.jsx(s.FormatQuoteIcon,{size:18}),command:({editor:l,range:f})=>l.chain().focus().deleteRange(f).toggleNode("paragraph","paragraph").toggleBlockquote().run()},{title:"Code",description:"Capture a code snippet.",searchTerms:["codeblock"],icon:o.jsx(s.CodeIcon,{size:18}),command:({editor:l,range:f})=>l.chain().focus().deleteRange(f).toggleCodeBlock().run()},{title:"Image",description:"Upload an image from your computer.",searchTerms:["photo","picture","media"],icon:o.jsx(s.ImageIcon,{size:18}),command:({editor:l,range:f})=>{l.chain().focus().deleteRange(f).run();const v=document.createElement("input");v.type="file",v.accept="image/*",v.onchange=async()=>{if(v.files?.length){if(!v.files[0])return;l.view.state.selection.from}},v.click()}}]),c=le.configure({suggestion:{items:()=>a,render:ue}}),m=g.useMemo(()=>Te(e),[]),p=[W,Q,Z.Color,V.configure({multicolor:!0}),_.Markdown.configure({html:!1,transformCopiedText:!0}),Se,Ne,Ae,ye,ve,m,Ce,we,Le,c],[h,k]=g.useState(!1),[x,L]=g.useState(!1);s.useInjectStyles("Editor",He);const P=g.useRef(null),[qe,De]=g.useState(null),[B,ze]=g.useState(null),[H,Fe]=g.useState(null),Ue=l=>{P.current=l,i&&De(l.storage.markdown.getMarkdown()),t&&ze(I(l.getJSON())),n&&Fe(l.getHTML())};return M(qe,()=>{if(P.current){const l=P.current.storage.markdown.getMarkdown();i?.(Be(l))}},!1,500),M(B,()=>{B&&t?.(B)},!1,500),M(H,()=>{H&&n?.(H)},!1,500),r?o.jsx("div",{className:"relative w-full p-8",children:o.jsx(se,{children:o.jsx("div",{className:"relative min-h-[500px] w-full bg-white dark:bg-gray-950 rounded-lg",children:o.jsxs(b.EditorProvider,{content:r,extensions:p,editorProps:{...d,attributes:{class:"prose-lg prose-headings:font-title font-default focus:outline-none max-w-full p-12"}},onUpdate:({editor:l})=>{console.log("editor updated"),Ue(l)},children:[o.jsxs(ce,{className:s.cn("text-gray-900 dark:text-white z-50 h-auto max-h-[330px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-gray-900 px-1 py-2 shadow transition-all",s.defaultBorderMixin),children:[o.jsx(de,{className:"px-2 text-gray-700 dark:text-slate-300",children:"No results"}),a.map(l=>o.jsxs(F,{value:l.title,onCommand:f=>l?.command?.(f),className:"flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-gray-700 aria-selected:bg-blue-50 aria-selected:dark:bg-gray-700",children:[o.jsx("div",{className:s.cn("flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-gray-900",s.defaultBorderMixin),children:l.icon}),o.jsxs("div",{children:[o.jsx("p",{className:"font-medium",children:l.title}),o.jsx("p",{className:"text-xs text-gray-700 dark:text-slate-300",children:l.description})]})]},l.title))]}),o.jsxs(ae,{tippyOptions:{placement:"top"},className:s.cn("flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-gray-900 shadow",s.defaultBorderMixin),children:[o.jsx(fe,{open:h,onOpenChange:k}),o.jsx(s.Separator,{orientation:"vertical"}),o.jsx(ke,{open:x,onOpenChange:L}),o.jsx(s.Separator,{orientation:"vertical"}),o.jsx(be,{})]})]})})})}):null};function Be(e){const r=/!\[.*?\]\(.*?\)/g;return e.replace(r,t=>`${t}
1
+ (function(u,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react/jsx-runtime"),require("react"),require("@tiptap/extension-underline"),require("@tiptap/extension-text-style"),require("@tiptap/extension-color"),require("tiptap-markdown"),require("@tiptap/extension-highlight"),require("@tiptap/react"),require("jotai"),require("@radix-ui/react-slot"),require("tunnel-rat"),require("cmdk"),require("@tiptap/starter-kit"),require("@tiptap/extension-horizontal-rule"),require("@tiptap/extension-link"),require("@tiptap/extension-image"),require("@tiptap/extension-placeholder"),require("@tiptap/extension-task-item"),require("@tiptap/extension-task-list"),require("@tiptap/core"),require("@tiptap/suggestion"),require("tippy.js"),require("@firecms/ui"),require("prosemirror-state"),require("@tiptap/pm/view"),require("@tiptap/pm/state")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","@tiptap/extension-underline","@tiptap/extension-text-style","@tiptap/extension-color","tiptap-markdown","@tiptap/extension-highlight","@tiptap/react","jotai","@radix-ui/react-slot","tunnel-rat","cmdk","@tiptap/starter-kit","@tiptap/extension-horizontal-rule","@tiptap/extension-link","@tiptap/extension-image","@tiptap/extension-placeholder","@tiptap/extension-task-item","@tiptap/extension-task-list","@tiptap/core","@tiptap/suggestion","tippy.js","@firecms/ui","prosemirror-state","@tiptap/pm/view","@tiptap/pm/state"],n):(u=typeof globalThis<"u"?globalThis:u||self,n(u["FireCMS Editor"]={},u.jsxRuntime,u.React,u.TiptapUnderline,u.TextStyle,u.extensionColor,u.tiptapMarkdown,u.Highlight,u.react,u.jotai,u.reactSlot,u.tunnel,u.cmdk,u.StarterKit,u.HorizontalRule,u.TiptapLink,u.TiptapImage,u.Placeholder,u.extensionTaskItem,u.extensionTaskList,u.core,u.Suggestion,u.tippy,u.ui,u.prosemirrorState,u.view,u.state))})(this,function(u,n,g,W,Q,Z,_,V,b,y,X,Y,C,J,G,$,j,R,ee,te,w,re,oe,s,ne,A,E){"use strict";const T=y.createStore(),se=({children:e})=>n.jsx(y.Provider,{store:T,children:e}),ae=g.forwardRef(({children:e,tippyOptions:r,...t},o)=>{const{editor:i}=b.useCurrentEditor(),l=g.useRef(null);g.useEffect(()=>{!l.current||!r?.placement||(l.current.setProps({placement:r.placement}),l.current.popperInstance?.update())},[r?.placement]);const a=g.useMemo(()=>({shouldShow:({editor:m,state:p})=>{const{selection:h}=p,{empty:k}=h;return!(m.isActive("image")||k||b.isNodeSelection(h))},tippyOptions:{onCreate:m=>{l.current=m},moveTransition:"transform 0.15s ease-out",...r},...t}),[t,r]);return i?n.jsx("div",{ref:o,children:n.jsx(b.BubbleMenu,{editor:i,...a,children:e})}):null}),S=g.forwardRef(({children:e,asChild:r,onSelect:t,...o},i)=>{const{editor:l}=b.useCurrentEditor(),a=r?X.Slot:"div";return l?n.jsx(a,{ref:i,...o,onClick:()=>t?.(l),children:e}):null});S.displayName="EditorBubbleItem";const q=Y(),D=y.atom(""),z=y.atom(null),ie=({query:e,range:r})=>{const t=y.useSetAtom(D,{store:T}),o=y.useSetAtom(z,{store:T});return g.useEffect(()=>{t(e)},[e,t]),g.useEffect(()=>{o(r)},[r,o]),g.useEffect(()=>{const i=["ArrowUp","ArrowDown","Enter"],l=a=>{if(i.includes(a.key)){a.preventDefault();const c=document.querySelector("#slash-command");c&&c.dispatchEvent(new KeyboardEvent("keydown",{key:a.key,cancelable:!0,bubbles:!0}))}};return document.addEventListener("keydown",l),()=>{document.removeEventListener("keydown",l)}},[]),n.jsx(q.Out,{})},ce=g.forwardRef(({children:e,className:r,...t},o)=>{const i=g.useRef(null),[l,a]=y.useAtom(D);return n.jsx(q.In,{children:n.jsxs(C.Command,{ref:o,onKeyDown:c=>{c.stopPropagation()},id:"slash-command",className:r,...t,children:[n.jsx(C.Command.Input,{value:l,onValueChange:a,style:{display:"none"}}),n.jsx(C.Command.List,{ref:i,children:e})]})})}),F=g.forwardRef(({children:e,onCommand:r,...t},o)=>{const{editor:i}=b.useCurrentEditor(),l=y.useAtomValue(z);return!i||!l?null:n.jsx(C.CommandItem,{ref:o,...t,onSelect:()=>r({editor:i,range:l}),children:e})});F.displayName="EditorCommandItem";const le=C.CommandEmpty,de=w.Extension.create({name:"slash-command",addOptions(){return{suggestion:{char:"/",command:({editor:e,range:r,props:t})=>{t.command({editor:e,range:r})}}}},addProseMirrorPlugins(){return[re({editor:this.editor,...this.options.suggestion})]}}),ue=()=>{let e=null,r=null;return{onStart:t=>{e=new b.ReactRenderer(ie,{props:t,editor:t.editor}),r=oe("body",{getReferenceClientRect:t.clientRect,appendTo:()=>document.body,content:e.element,showOnCreate:!0,interactive:!0,trigger:"manual",placement:"bottom-start"})},onUpdate:t=>{e?.updateProps(t),r&&r[0].setProps({getReferenceClientRect:t.clientRect})},onKeyDown:t=>t.event.key==="Escape"?(r?.[0].hide(),!0):e?.ref?.onKeyDown(t),onExit:()=>{r?.[0].destroy(),e?.destroy()}}},me=e=>e,pe=R.configure({placeholder:({node:e})=>e.type.name==="heading"?`Heading ${e.attrs.level}`:"Press '/' for commands",includeChildren:!0}),ge=G.extend({addInputRules(){return[new w.InputRule({find:/^(?:---|—-|___\s|\*\*\*\s)$/,handler:({state:e,range:r})=>{const t={},{tr:o}=e,i=r.from,l=r.to;o.insert(i-1,this.type.create(t)).delete(o.mapping.map(i),o.mapping.map(l))}})]}}),U=[{name:"Text",icon:s.TextFieldsIcon,command:e=>e?.chain().focus().toggleNode("paragraph","paragraph").run(),isActive:e=>(e?.isActive("paragraph")&&!e?.isActive("bulletList")&&!e?.isActive("orderedList"))??!1},{name:"Heading 1",icon:s.LooksOneIcon,command:e=>e?.chain().focus().toggleHeading({level:1}).run(),isActive:e=>e?.isActive("heading",{level:1})??!1},{name:"Heading 2",icon:s.LooksTwoIcon,command:e=>e?.chain().focus().toggleHeading({level:2}).run(),isActive:e=>e?.isActive("heading",{level:2})??!1},{name:"Heading 3",icon:s.Looks3Icon,command:e=>e?.chain().focus().toggleHeading({level:3}).run(),isActive:e=>e?.isActive("heading",{level:3})??!1},{name:"To-do List",icon:s.CheckBoxIcon,command:e=>e?.chain().focus().toggleTaskList().run(),isActive:e=>e?.isActive("taskItem")??!1},{name:"Bullet List",icon:s.FormatListBulletedIcon,command:e=>e?.chain().focus().toggleBulletList().run(),isActive:e=>e?.isActive("bulletList")??!1},{name:"Numbered List",icon:s.FormatListNumberedIcon,command:e=>e?.chain().focus().toggleOrderedList().run(),isActive:e=>e?.isActive("orderedList")??!1},{name:"Quote",icon:s.FormatQuoteIcon,command:e=>e?.chain().focus().toggleNode("paragraph","paragraph").toggleBlockquote().run(),isActive:e=>e?.isActive("blockquote")??!1},{name:"Code",icon:s.CodeIcon,command:e=>e?.chain().focus().toggleCodeBlock().run(),isActive:e=>e?.isActive("codeBlock")??!1}],fe=({open:e,onOpenChange:r})=>{const{editor:t}=b.useCurrentEditor();if(!t)return null;const o=U.filter(i=>i.isActive(t)).pop()??{name:"Multiple"};return n.jsx(s.Popover,{sideOffset:5,align:"start",className:"w-48 p-1",trigger:n.jsxs(s.Button,{variant:"text",className:"gap-2 rounded-none",color:"text",children:[n.jsx("span",{className:"whitespace-nowrap text-sm",children:o.name}),n.jsx(s.ExpandMoreIcon,{size:"small"})]}),modal:!0,open:e,onOpenChange:r,children:U.map((i,l)=>n.jsxs(S,{onSelect:a=>{i.command(a),r(!1)},className:"flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-gray-700 text-gray-900 dark:text-white",children:[n.jsxs("div",{className:"flex items-center space-x-2",children:[n.jsx(i.icon,{size:"smallest"}),n.jsx("span",{children:i.name})]}),o.name===i.name&&n.jsx(s.CheckIcon,{size:"smallest"})]},l))})};function he(e){try{return new URL(e),!0}catch{return!1}}function xe(e){if(he(e))return e;try{return e.includes(".")&&!e.includes(" ")?new URL(`https://${e}`).toString():null}catch{return null}}const ke=({open:e,onOpenChange:r})=>{const t=g.useRef(null),{editor:o}=b.useCurrentEditor();return g.useEffect(()=>{t.current&&t.current?.focus()}),o?n.jsx(s.Popover,{modal:!0,open:e,onOpenChange:r,trigger:n.jsx(s.Button,{variant:"text",className:"gap-2 rounded-none",color:"text",children:n.jsx("p",{className:s.cls("underline decoration-stone-400 underline-offset-4",{"text-blue-500":o.isActive("link")}),children:"Link"})}),children:n.jsxs("form",{onSubmit:i=>{const l=i.currentTarget;i.preventDefault();const a=l[0],c=xe(a.value);c&&o.chain().focus().setLink({href:c}).run()},className:"flex p-1",children:[n.jsx("input",{ref:t,autoFocus:e,placeholder:"Paste a link",defaultValue:o.getAttributes("link").href||"",className:"text-gray-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none"}),o.getAttributes("link").href?n.jsx(s.Button,{size:"small",variant:"text",type:"button",color:"text",className:"flex items-center",onClick:()=>{o.chain().focus().unsetLink().run()},children:n.jsx(s.DeleteIcon,{size:"small"})}):n.jsx(s.Button,{size:"small",variant:"text",children:n.jsx(s.CheckIcon,{size:"small"})})]})}):null},be=()=>{const{editor:e}=b.useCurrentEditor();if(!e)return null;const r=[{name:"bold",isActive:t=>t?.isActive("bold")??!1,command:t=>t?.chain().focus().toggleBold().run(),icon:s.FormatBoldIcon},{name:"italic",isActive:t=>t?.isActive("italic")??!1,command:t=>t?.chain().focus().toggleItalic().run(),icon:s.FormatItalicIcon},{name:"underline",isActive:t=>t?.isActive("underline")??!1,command:t=>t?.chain().focus().toggleUnderline().run(),icon:s.FormatUnderlinedIcon},{name:"strike",isActive:t=>t?.isActive("strike")??!1,command:t=>t?.chain().focus().toggleStrike().run(),icon:s.FormatStrikethroughIcon},{name:"code",isActive:t=>t?.isActive("code")??!1,command:t=>t?.chain().focus().toggleCode().run(),icon:s.CodeIcon}];return n.jsx("div",{className:"flex",children:r.map((t,o)=>n.jsx(S,{onSelect:i=>{t.command(i)},children:n.jsx(s.Button,{size:"small",color:"text",className:"gap-2 rounded-none h-full",variant:"text",children:n.jsx(t.icon,{className:s.cls({"text-inherit":!t.isActive(e),"text-blue-500":t.isActive(e)})})})},o))})};function M(e,r,t,o=300){const i=g.useRef(!1),l=()=>{r(),i.current=!1},a=g.useRef(void 0);g.useEffect(()=>(i.current=!0,clearTimeout(a.current),a.current=setTimeout(l,o),()=>{}),[t,e])}function I(e){return Array.isArray(e)?e.map(r=>I(r)):(typeof e=="object"&&e!==null&&(e.attrs&&typeof e.attrs=="object"&&"class"in e.attrs&&delete e.attrs.class,Object.keys(e).forEach(r=>{e[r]=I(e[r])})),e)}const ye=pe,ve=$.configure({HTMLAttributes:{class:s.cls("text-gray-600 dark:text-slate-300 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer")}}),Ce=te.TaskList.configure({HTMLAttributes:{class:s.cls("not-prose")}}),we=ee.TaskItem.configure({HTMLAttributes:{class:s.cls("flex items-start my-4")},nested:!0}),Le=ge.configure({HTMLAttributes:{class:s.cls("mt-4 mb-6 border-t",s.defaultBorderMixin)}}),Ae=J.configure({bulletList:{HTMLAttributes:{class:s.cls("list-disc list-outside leading-3 -mt-2")}},orderedList:{HTMLAttributes:{class:s.cls("list-decimal list-outside leading-3 -mt-2")}},listItem:{HTMLAttributes:{class:s.cls("leading-normal -mb-2")}},blockquote:{HTMLAttributes:{class:s.cls("border-l-4 border-primary")}},codeBlock:{HTMLAttributes:{class:s.cls("rounded bg-blue-50 dark:bg-gray-700 border p-5 font-mono font-medium",s.defaultBorderMixin)}},code:{HTMLAttributes:{class:s.cls("rounded-md bg-slate-50 dark:bg-gray-700 px-1.5 py-1 font-mono font-medium"),spellcheck:"false"}},horizontalRule:!1,dropcursor:{color:"#DBEAFE",width:4},gapcursor:!1});async function K(e,r,t,o,i,l){const{schema:a}=r.state;let c=e.getState(r.state);const m=document.createElement("div"),p=document.createElement("img");p.setAttribute("class","opacity-40 rounded-lg border border-stone-200"),p.src=t.target?.result,m.appendChild(p);const h=A.Decoration.widget(o,m);c=c?.add(r.state.doc,[h]),r.dispatch(r.state.tr.setMeta(e,{decorationSet:c}));const k=await i(l);console.log("uploaded image",k);const x=a.nodes.image.create({src:k}),L=r.state.tr.replaceWith(o,o,x);c=c?.remove([h]),L.setMeta(e,{decorationSet:c}),r.dispatch(L)}const Ee=e=>{const r=new ne.Plugin({state:{init:()=>A.DecorationSet.empty,apply:(t,o)=>{const i=t.getMeta(r);return i&&i.decorationSet?i.decorationSet:o.map(t.mapping,t.doc)}},props:{handleDOMEvents:{drop:(t,o)=>{if(console.log("drop event",o),!o.dataTransfer?.files||o.dataTransfer?.files.length===0)return!1;o.preventDefault();const l=Array.from(o.dataTransfer.files).filter(a=>/image/i.test(a.type));return l.length===0?!1:(l.forEach(a=>{const c=t.posAtCoords({left:o.clientX,top:o.clientY});if(!c)return;const m=new FileReader;m.onload=async p=>{await K(r,t,p,c.pos,e,a)},m.readAsDataURL(a)}),!0)}},handlePaste(t,o,i){const l=Array.from(o.clipboardData?.items||[]),a=t.state.selection.from;console.log("pos",a);let c=!1;return l.forEach(m=>{const p=m.getAsFile();if(console.log("image",p),p){c=!0;const h=new FileReader;h.onload=async k=>{await K(r,t,k,a,e,p)},h.readAsDataURL(p)}}),c},decorations(t){return r.getState(t)}},view(t){return{update(o,i){const l=r.getState(i),a=r.getState(o.state);l!==a&&o.updateState(o.state)}}}});return r},Te=e=>j.extend({addProseMirrorPlugins(){return[Ee(e)]}}).configure({allowBase64:!0,HTMLAttributes:{class:s.cls("rounded-lg border",s.defaultBorderMixin)}}),Se=w.Extension.create({name:"CustomKeymap",addCommands(){return{selectTextWithinNodeBoundaries:()=>({editor:e,commands:r})=>{const{state:t}=e,{tr:o}=t,i=o.selection.$from.start(),l=o.selection.$to.end();return r.setTextSelection({from:i,to:l})}}},addKeyboardShortcuts(){return{"Mod-a":({editor:e})=>{const{state:r}=e,{tr:t}=r,o=t.selection.from,i=t.selection.to,l=t.selection.$from.start(),a=t.selection.$to.end();return o>l||i<a?(e.chain().selectTextWithinNodeBoundaries().run(),!0):!1}}}});function Me(e){const r=e.getBoundingClientRect();return{top:r.top,left:r.left,width:r.width}}function N(e){return document.elementsFromPoint(e.x,e.y).find(r=>r.parentElement?.matches?.(".ProseMirror")||r.matches(["li","p:not(:first-child)","pre","blockquote","h1, h2, h3, h4, h5, h6"].join(", ")))}function O(e,r,t){const o=e.getBoundingClientRect();return r.posAtCoords({left:o.left+50+t.dragHandleWidth,top:o.top+1})?.inside}function Ie(e){function r(a,c){if(c.focus(),!a.dataTransfer)return;const m=N({x:a.clientX+50+e.dragHandleWidth,y:a.clientY});if(!(m instanceof Element))return;const p=O(m,c,e);if(p==null||p<0)return;c.dispatch(c.state.tr.setSelection(E.NodeSelection.create(c.state.doc,p)));const h=c.state.selection.content(),{dom:k,text:x}=A.__serializeForClipboard(c,h);a.dataTransfer.clearData(),a.dataTransfer.setData("text/html",k.innerHTML),a.dataTransfer.setData("text/plain",x),a.dataTransfer.effectAllowed="copyMove",a.dataTransfer.setDragImage(m,0,0),c.dragging={slice:h,move:a.ctrlKey}}function t(a,c){c.focus(),c.dom.classList.remove("dragging");const m=N({x:a.clientX+50+e.dragHandleWidth,y:a.clientY});if(!(m instanceof Element))return;const p=O(m,c,e);p&&c.dispatch(c.state.tr.setSelection(E.NodeSelection.create(c.state.doc,p)))}let o=null;function i(){o&&o.classList.add("hide")}function l(){o&&o.classList.remove("hide")}return new E.Plugin({view:a=>(o=document.createElement("div"),o.draggable=!0,o.dataset.dragHandle="",o.classList.add("drag-handle"),o.addEventListener("dragstart",c=>{r(c,a)}),o.addEventListener("click",c=>{t(c,a)}),i(),a?.dom?.parentElement?.appendChild(o),{destroy:()=>{o?.remove?.(),o=null}}),props:{handleDOMEvents:{mousemove:(a,c)=>{if(!a.editable)return;const m=N({x:c.clientX+50+e.dragHandleWidth,y:c.clientY});if(!(m instanceof Element)){i();return}const p=window.getComputedStyle(m),h=parseInt(p.lineHeight,10),k=parseInt(p.paddingTop,10),x=Me(m);x.top+=(h-24)/2,x.top+=k,m.matches("ul:not([data-type=taskList]) li, ol li")&&(x.left-=e.dragHandleWidth),x.width=e.dragHandleWidth,o&&(o.style.left=`${x.left-x.width}px`,o.style.top=`${x.top}px`,l())},keydown:()=>{i()},mousewheel:()=>{i()},dragstart:a=>{a.dom.classList.add("dragging")},drop:a=>{a.dom.classList.remove("dragging")},dragend:a=>{a.dom.classList.remove("dragging")}}}})}const Ne=w.Extension.create({name:"dragAndDrop",addProseMirrorPlugins(){return[Ie({dragHandleWidth:24})]}}),Pe=({handleImageUpload:e,initialContent:r,onJsonContentChange:t,onHtmlContentChange:o,onMarkdownContentChange:i})=>{const l={handleDOMEvents:{keydown:(d,f)=>!!(["ArrowUp","ArrowDown","Enter"].includes(f.key)&&document.querySelector("#slash-command"))}},a=me([{title:"Text",description:"Just start typing with plain text.",searchTerms:["p","paragraph"],icon:n.jsx(s.TextFieldsIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).toggleNode("paragraph","paragraph").run()}},{title:"To-do List",description:"Track tasks with a to-do list.",searchTerms:["todo","task","list","check","checkbox"],icon:n.jsx(s.CheckBoxIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).toggleTaskList().run()}},{title:"Heading 1",description:"Big section heading.",searchTerms:["title","big","large"],icon:n.jsx(s.LooksOneIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).setNode("heading",{level:1}).run()}},{title:"Heading 2",description:"Medium section heading.",searchTerms:["subtitle","medium"],icon:n.jsx(s.LooksTwoIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).setNode("heading",{level:2}).run()}},{title:"Heading 3",description:"Small section heading.",searchTerms:["subtitle","small"],icon:n.jsx(s.Looks3Icon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).setNode("heading",{level:3}).run()}},{title:"Bullet List",description:"Create a simple bullet list.",searchTerms:["unordered","point"],icon:n.jsx(s.FormatListBulletedIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).toggleBulletList().run()}},{title:"Numbered List",description:"Create a list with numbering.",searchTerms:["ordered"],icon:n.jsx(s.FormatListNumberedIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).toggleOrderedList().run()}},{title:"Quote",description:"Capture a quote.",searchTerms:["blockquote"],icon:n.jsx(s.FormatQuoteIcon,{size:18}),command:({editor:d,range:f})=>d.chain().focus().deleteRange(f).toggleNode("paragraph","paragraph").toggleBlockquote().run()},{title:"Code",description:"Capture a code snippet.",searchTerms:["codeblock"],icon:n.jsx(s.CodeIcon,{size:18}),command:({editor:d,range:f})=>d.chain().focus().deleteRange(f).toggleCodeBlock().run()},{title:"Image",description:"Upload an image from your computer.",searchTerms:["photo","picture","media"],icon:n.jsx(s.ImageIcon,{size:18}),command:({editor:d,range:f})=>{d.chain().focus().deleteRange(f).run();const v=document.createElement("input");v.type="file",v.accept="image/*",v.onchange=async()=>{if(v.files?.length){if(!v.files[0])return;d.view.state.selection.from}},v.click()}}]),c=de.configure({suggestion:{items:()=>a,render:ue}}),m=g.useMemo(()=>Te(e),[]),p=[W,Q,Z.Color,V.configure({multicolor:!0}),_.Markdown.configure({html:!1,transformCopiedText:!0}),Se,Ne,Ae,ye,ve,m,Ce,we,Le,c],[h,k]=g.useState(!1),[x,L]=g.useState(!1);s.useInjectStyles("Editor",He);const P=g.useRef(null),[qe,De]=g.useState(null),[B,ze]=g.useState(null),[H,Fe]=g.useState(null),Ue=d=>{P.current=d,i&&De(d.storage.markdown.getMarkdown()),t&&ze(I(d.getJSON())),o&&Fe(d.getHTML())};return M(qe,()=>{if(P.current){const d=P.current.storage.markdown.getMarkdown();i?.(Be(d))}},!1,500),M(B,()=>{B&&t?.(B)},!1,500),M(H,()=>{H&&o?.(H)},!1,500),r?n.jsx("div",{className:"relative w-full p-8",children:n.jsx(se,{children:n.jsx("div",{className:"relative min-h-[500px] w-full bg-white dark:bg-gray-950 rounded-lg",children:n.jsxs(b.EditorProvider,{content:r,extensions:p,editorProps:{...l,attributes:{class:"prose-lg prose-headings:font-title font-default focus:outline-none max-w-full p-12"}},onUpdate:({editor:d})=>{console.debug("Editor updated"),Ue(d)},children:[n.jsxs(ce,{className:s.cls("text-gray-900 dark:text-white z-50 h-auto max-h-[330px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-gray-900 px-1 py-2 shadow transition-all",s.defaultBorderMixin),children:[n.jsx(le,{className:"px-2 text-gray-700 dark:text-slate-300",children:"No results"}),a.map(d=>n.jsxs(F,{value:d.title,onCommand:f=>d?.command?.(f),className:"flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-gray-700 aria-selected:bg-blue-50 aria-selected:dark:bg-gray-700",children:[n.jsx("div",{className:s.cls("flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-gray-900",s.defaultBorderMixin),children:d.icon}),n.jsxs("div",{children:[n.jsx("p",{className:"font-medium",children:d.title}),n.jsx("p",{className:"text-xs text-gray-700 dark:text-slate-300",children:d.description})]})]},d.title))]}),n.jsxs(ae,{tippyOptions:{placement:"top"},className:s.cls("flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-gray-900 shadow",s.defaultBorderMixin),children:[n.jsx(fe,{open:h,onOpenChange:k}),n.jsx(s.Separator,{orientation:"vertical"}),n.jsx(ke,{open:x,onOpenChange:L}),n.jsx(s.Separator,{orientation:"vertical"}),n.jsx(be,{})]})]})})})}):null};function Be(e){const r=/!\[.*?\]\(.*?\)/g;return e.replace(r,t=>`${t}
2
2
  `)}const He=`
3
3
 
4
4
  .ProseMirror .is-editor-empty:first-child::before {