react-word-editor 0.0.0-stage → 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/RichTextEditor.jsx","../src/editor/outputs.js","../src/editor/handle.js","../src/toolbar/Toolbar.jsx","../src/toolbar/controls.jsx","../src/toolbar/ToolbarSelect.jsx","../src/toolbar/ColorButton.jsx","../src/toolbar/TablePicker.jsx","../src/toolbar/MenuButton.jsx","../src/toolbar/icons.jsx","../src/toolbar/TableTools.jsx","../src/toolbar/toolbarState.js"],"sourcesContent":["import React, { useEffect, useMemo, useRef } from 'react';\nimport { EditorContent, useEditor, useEditorState } from '@tiptap/react';\nimport { buildEditorExtensions } from './extensions';\nimport { readAsDataUrl } from './extensions/imageUpload';\nimport { ensureNodeIds } from './extensions/nodeIds';\nimport { cleanHtml } from './paste/cleanHtml';\nimport { getOutput, sameValue, toEditorContent } from './editor/outputs';\nimport { createEditorHandle } from './editor/handle';\nimport { replaceVariables } from './editor/variables';\nimport { SILENT_META } from './utils/meta';\nimport Toolbar from './toolbar/Toolbar';\nimport TableTools from './toolbar/TableTools';\nimport { selectToolbarState } from './toolbar/toolbarState';\nimport { DEFAULT_FONT_FAMILIES, DEFAULT_FONT_SIZES, DEFAULT_TOOLBAR } from './toolbar/constants';\n\nconst countWords = (text) => (text.trim() ? text.trim().split(/\\s+/).length : 0);\n\nconst RichTextEditor = ({\n value,\n onChange,\n setValue,\n fnProps = [],\n outputFormat = 'html',\n pdfOptions,\n height,\n minHeight = 200,\n disabled = false,\n readOnly = false,\n placeholder,\n toolbar = true,\n fontFamilies = DEFAULT_FONT_FAMILIES,\n fontSizes = DEFAULT_FONT_SIZES,\n dynamicData,\n nodeIds = false,\n onInit,\n onReady,\n onFocus,\n onBlur,\n handleFocusRestore,\n onImageUpload,\n maxImageSize,\n onError,\n autoFocus = false,\n pageView = false,\n showWordCount = true,\n className = '',\n style,\n contentClassName = '',\n}) => {\n const latest = useRef({});\n latest.current = { onChange, setValue, fnProps, outputFormat, pdfOptions, dynamicData, onFocus, onBlur, handleFocusRestore, onError };\n const lastEmitted = useRef(value);\n const locked = disabled || readOnly;\n\n const emit = (editor) => {\n const l = latest.current;\n const out = getOutput(editor, l.outputFormat, l.pdfOptions);\n lastEmitted.current = out;\n if (l.onChange) l.onChange(out, ...(l.fnProps || []));\n else if (l.setValue) l.setValue(out, ...(l.fnProps || []));\n };\n\n const extensions = useMemo(\n () =>\n buildEditorExtensions({\n nodeIds,\n placeholder,\n onImageUpload: (file) => {\n const upload = latest.current.onImageUploadProp;\n return upload ? upload(file) : readAsDataUrl(file);\n },\n maxImageSize,\n onError: (err) => latest.current.onError?.(err),\n }),\n // Extensions are fixed for the editor's lifetime.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [nodeIds, placeholder],\n );\n latest.current.onImageUploadProp = onImageUpload;\n\n const editor = useEditor(\n {\n extensions,\n content: toEditorContent(value),\n editable: !locked,\n autofocus: autoFocus,\n immediatelyRender: true,\n shouldRerenderOnTransaction: false,\n editorProps: {\n transformPastedHTML: cleanHtml,\n attributes: { class: `fe-content ${contentClassName}`.trim(), spellcheck: 'true' },\n },\n onUpdate: ({ editor: ed, transaction }) => {\n if (transaction.getMeta(SILENT_META)) return;\n emit(ed);\n },\n onFocus: ({ event }) => {\n latest.current.onFocus?.(event);\n latest.current.handleFocusRestore?.(event);\n },\n onBlur: ({ editor: ed, event }) => {\n if (latest.current.dynamicData) replaceVariables(ed, latest.current.dynamicData);\n latest.current.onBlur?.(event);\n },\n },\n [extensions],\n );\n\n const handle = useMemo(() => (editor ? createEditorHandle(editor, { pdfOptions }) : null), [editor, pdfOptions]);\n\n useEffect(() => {\n if (!editor || !handle) return;\n if (nodeIds) ensureNodeIds(editor);\n onInit?.({ type: 'init', target: handle }, handle);\n onReady?.(handle);\n // Fire once per editor instance, like TinyMCE's onInit.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n if (sameValue(value, lastEmitted.current)) return;\n if (typeof value === 'string' && outputFormat === 'html' && value === getOutput(editor, 'html')) {\n lastEmitted.current = value;\n return;\n }\n lastEmitted.current = value;\n editor.commands.setContent(toEditorContent(value), { emitUpdate: false });\n if (nodeIds) ensureNodeIds(editor);\n }, [editor, value, outputFormat, nodeIds]);\n\n useEffect(() => {\n if (editor && !editor.isDestroyed) editor.setEditable(!locked, false);\n }, [editor, locked]);\n\n const state = useEditorState({ editor, selector: selectToolbarState }) || {};\n const words = useEditorState({\n editor,\n selector: ({ editor: ed }) => (showWordCount && ed ? countWords(ed.state.doc.textBetween(0, ed.state.doc.content.size, ' ', ' ')) : 0),\n });\n\n const toolbarItems = Array.isArray(toolbar) ? toolbar : DEFAULT_TOOLBAR;\n const sized = height !== undefined && height !== null;\n\n return (\n <div\n className={`fe-editor${pageView ? ' fe-editor--page' : ''}${locked ? ' fe-editor--disabled' : ''}${sized ? ' fe-editor--sized' : ''} ${className}`.trim()}\n style={{ ...(sized ? { height } : {}), ...style }}\n >\n {toolbar && !readOnly ? (\n <div className=\"fe-toolbars\">\n <Toolbar\n editor={editor}\n state={state}\n items={toolbarItems}\n disabled={locked}\n fontFamilies={fontFamilies}\n fontSizes={fontSizes}\n imageOptions={{ onImageUpload, maxImageSize, onError }}\n />\n {state.inTable && !locked ? <TableTools editor={editor} state={state} disabled={locked} /> : null}\n </div>\n ) : null}\n <div className=\"fe-scroll\" style={sized ? undefined : { minHeight }} onClick={() => !locked && editor?.isFocused === false && editor?.commands.focus()}>\n <div className=\"fe-page\">\n <EditorContent editor={editor} />\n </div>\n </div>\n {showWordCount ? (\n <div className=\"fe-status\">\n {words} {words === 1 ? 'word' : 'words'}\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default RichTextEditor;\n","import { jsonToText } from '../output/text';\nimport { jsonToPdfTree } from '../pdf/tree';\nimport { isDocJson, normalizeHtmlInput } from '../output/convert';\n\nexport const OUTPUT_FORMATS = ['html', 'text', 'json', 'pdf', 'all'];\n\nconst isEmptyDoc = (editor) => editor.isEmpty;\n\nexport const getOutput = (editor, format = 'html', pdfOptions) => {\n if (!editor || editor.isDestroyed) return null;\n const json = () => editor.getJSON();\n const html = () => (isEmptyDoc(editor) ? '' : editor.getHTML());\n switch (format) {\n case 'text':\n return jsonToText(json());\n case 'json':\n return json();\n case 'pdf':\n return jsonToPdfTree(json(), pdfOptions);\n case 'all': {\n const doc = json();\n return {\n html: html(),\n text: jsonToText(doc),\n json: doc,\n pdf: jsonToPdfTree(doc, pdfOptions),\n };\n }\n default:\n return html();\n }\n};\n\n// What to hand to editor.setContent for a `value` prop.\nexport const toEditorContent = (value) => {\n if (isDocJson(value)) return value;\n if (value && typeof value === 'object' && isDocJson(value.json)) return value.json;\n if (value && typeof value === 'object' && typeof value.html === 'string') {\n return normalizeHtmlInput(value.html);\n }\n if (value && typeof value === 'object') return '';\n return normalizeHtmlInput(value);\n};\n\nexport const sameValue = (a, b) => {\n if (a === b) return true;\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch (e) {\n return false;\n }\n }\n return false;\n};\n","import { getOutput, toEditorContent } from './outputs';\n\n// A small TinyMCE-like facade so code written against `onInit(evt, editor)`\n// keeps working: editor.getContent(), setContent(), getBody(), focus().\nexport const createEditorHandle = (editor, { pdfOptions } = {}) => ({\n tiptap: editor,\n getContent: (args = {}) => getOutput(editor, args.format || 'html', pdfOptions),\n setContent: (value, { emitUpdate = true } = {}) => {\n editor.commands.setContent(toEditorContent(value), { emitUpdate });\n },\n insertContent: (value) => editor.chain().focus().insertContent(toEditorContent(value)).run(),\n getHTML: () => getOutput(editor, 'html'),\n getText: () => getOutput(editor, 'text'),\n getJSON: () => editor.getJSON(),\n getPdfTree: (options) => getOutput(editor, 'pdf', options || pdfOptions),\n getBody: () => editor.view?.dom,\n focus: () => editor.commands.focus(),\n isEmpty: () => editor.isEmpty,\n setDisabled: (disabled) => editor.setEditable(!disabled),\n});\n","import React, { useRef } from 'react';\nimport {\n AlignCenter, AlignJustify, AlignLeft, AlignRight, Baseline, Bold, Highlighter,\n CaseSensitive, ImagePlus, IndentDecrease, IndentIncrease, Italic, Link2, List, ListOrdered,\n Minus, Redo2, RemoveFormatting, Strikethrough, Subscript, Superscript,\n Underline, Undo2, UnfoldVertical,\n} from 'lucide-react';\nimport { BLOCK_TYPES, DEFAULT_TOOLBAR, LINE_HEIGHTS, PARAGRAPH_SPACING, TEXT_CASES } from './constants';\nimport { Divider, ToolbarButton } from './controls';\nimport ToolbarSelect from './ToolbarSelect';\nimport ColorButton from './ColorButton';\nimport TablePicker from './TablePicker';\nimport MenuButton from './MenuButton';\nimport { SpacingIcon } from './icons';\nimport { insertImages } from '../extensions/imageUpload';\n\nconst toggle = (editor, cmd) => () => editor.chain().focus()[cmd]().run();\n\nconst setBlockType = (editor, value) => {\n const chain = editor.chain().focus();\n if (value === 'paragraph') chain.setParagraph().run();\n else chain.setHeading({ level: Number(value.slice(1)) }).run();\n};\n\nconst promptLink = (editor) => {\n const previous = editor.getAttributes('link').href || '';\n const url = window.prompt('Link URL (leave empty to remove)', previous);\n if (url === null) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (!url.trim()) chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n};\n\nconst SPACING_ITEMS = [\n PARAGRAPH_SPACING[0],\n '|',\n ...PARAGRAPH_SPACING.slice(1).map((p, i) => ({ ...p, icon: <SpacingIcon gap={i} /> })),\n];\n\nconst ALIGN_ITEMS = {\n alignLeft: { icon: AlignLeft, label: 'Align left', value: 'left' },\n alignCenter: { icon: AlignCenter, label: 'Center', value: 'center' },\n alignRight: { icon: AlignRight, label: 'Align right', value: 'right' },\n alignJustify: { icon: AlignJustify, label: 'Justify', value: 'justify' },\n};\n\nconst MARK_ITEMS = {\n bold: { icon: Bold, label: 'Bold (Ctrl+B)', cmd: 'toggleBold' },\n italic: { icon: Italic, label: 'Italic (Ctrl+I)', cmd: 'toggleItalic' },\n underline: { icon: Underline, label: 'Underline (Ctrl+U)', cmd: 'toggleUnderline' },\n strike: { icon: Strikethrough, label: 'Strikethrough', cmd: 'toggleStrike' },\n subscript: { icon: Subscript, label: 'Subscript', cmd: 'toggleSubscript' },\n superscript: { icon: Superscript, label: 'Superscript', cmd: 'toggleSuperscript' },\n bulletList: { icon: List, label: 'Bullets', cmd: 'toggleBulletList' },\n orderedList: { icon: ListOrdered, label: 'Numbering', cmd: 'toggleOrderedList' },\n};\n\nconst Toolbar = ({ editor, state, items = DEFAULT_TOOLBAR, disabled, fontFamilies, fontSizes, imageOptions }) => {\n const fileRef = useRef(null);\n if (!editor) return null;\n\n const sizeOptions = [\n { value: '', label: 'Size', menuLabel: 'Default' },\n ...fontSizes.map((s) => ({ value: `${s}pt`, label: s })),\n ...(state.fontSize && !fontSizes.some((s) => `${s}pt` === state.fontSize)\n ? [{ value: state.fontSize, label: state.fontSize.replace(/pt$/, ''), hidden: true }]\n : []),\n ];\n const familyOptions = [\n ...fontFamilies.map((f) => (f.value ? { ...f, style: { fontFamily: f.value } } : f)),\n ...(state.fontFamily && !fontFamilies.some((f) => f.value === state.fontFamily)\n ? [{ value: state.fontFamily, label: state.fontFamily.split(',')[0].replace(/[\"']/g, ''), hidden: true }]\n : []),\n ];\n\n const render = (key, i) => {\n if (key === '|') return <Divider key={`d${i}`} />;\n if (MARK_ITEMS[key]) {\n const { icon, label, cmd } = MARK_ITEMS[key];\n return <ToolbarButton key={key} icon={icon} label={label} active={state[key]} disabled={disabled} onClick={toggle(editor, cmd)} />;\n }\n if (ALIGN_ITEMS[key]) {\n const { icon, label, value } = ALIGN_ITEMS[key];\n return <ToolbarButton key={key} icon={icon} label={label} active={state.textAlign === value} disabled={disabled} onClick={() => editor.chain().focus().setTextAlign(value).run()} />;\n }\n switch (key) {\n case 'undo':\n return <ToolbarButton key={key} icon={Undo2} label=\"Undo (Ctrl+Z)\" disabled={disabled || !state.canUndo} onClick={toggle(editor, 'undo')} />;\n case 'redo':\n return <ToolbarButton key={key} icon={Redo2} label=\"Redo (Ctrl+Y)\" disabled={disabled || !state.canRedo} onClick={toggle(editor, 'redo')} />;\n case 'blockType':\n return <ToolbarSelect key={key} label=\"Text style\" width={108} value={state.blockType} options={BLOCK_TYPES} disabled={disabled} onChange={(v) => setBlockType(editor, v)} />;\n case 'fontFamily':\n return <ToolbarSelect key={key} label=\"Font\" width={130} value={state.fontFamily || ''} options={familyOptions} disabled={disabled} onChange={(v) => (v ? editor.chain().focus().setFontFamily(v).run() : editor.chain().focus().unsetFontFamily().run())} />;\n case 'fontSize':\n return <ToolbarSelect key={key} label=\"Font size\" width={64} value={state.fontSize || ''} options={sizeOptions} disabled={disabled} onChange={(v) => (v ? editor.chain().focus().setFontSize(v).run() : editor.chain().focus().unsetFontSize().run())} />;\n case 'textColor':\n return <ColorButton key={key} icon={Baseline} label=\"Font colour\" clearLabel=\"Automatic\" color={state.color} disabled={disabled} onPick={(c) => editor.chain().focus().setColor(c).run()} onClear={() => editor.chain().focus().unsetColor().run()} />;\n case 'highlight':\n return <ColorButton key={key} icon={Highlighter} label=\"Highlight\" clearLabel=\"No colour\" color={state.backgroundColor} disabled={disabled} onPick={(c) => editor.chain().focus().setBackgroundColor(c).run()} onClear={() => editor.chain().focus().unsetBackgroundColor().run()} />;\n case 'indent':\n return <ToolbarButton key={key} icon={IndentIncrease} label=\"Increase indent (Tab)\" disabled={disabled} onClick={toggle(editor, 'indent')} />;\n case 'outdent':\n return <ToolbarButton key={key} icon={IndentDecrease} label=\"Decrease indent (Shift+Tab)\" disabled={disabled} onClick={toggle(editor, 'outdent')} />;\n case 'lineHeight':\n return <ToolbarSelect key={key} label=\"Line spacing\" width={108} value={state.lineHeight ? String(state.lineHeight) : ''} options={LINE_HEIGHTS} disabled={disabled} onChange={(v) => editor.chain().focus().setLineHeight(v || null).run()} />;\n case 'paragraphSpacing':\n return <MenuButton key={key} icon={UnfoldVertical} label=\"Paragraph spacing\" items={SPACING_ITEMS} value={state.paragraphSpacing} showChecks disabled={disabled} onSelect={(v) => editor.chain().focus().setParagraphSpacing(v).run()} />;\n case 'textCase':\n return <MenuButton key={key} icon={CaseSensitive} label=\"Change case\" items={TEXT_CASES} disabled={disabled} onSelect={(v) => editor.chain().focus().setTextCase(v).run()} />;\n case 'table':\n return <TablePicker key={key} editor={editor} disabled={disabled} />;\n case 'image':\n return (\n <React.Fragment key={key}>\n <ToolbarButton icon={ImagePlus} label=\"Insert picture\" disabled={disabled} onClick={() => fileRef.current?.click()} />\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/*\"\n hidden\n onChange={(e) => {\n insertImages(editor, Array.from(e.target.files || []), imageOptions);\n e.target.value = '';\n }}\n />\n </React.Fragment>\n );\n case 'link':\n return <ToolbarButton key={key} icon={Link2} label=\"Link\" active={state.link} disabled={disabled} onClick={() => promptLink(editor)} />;\n case 'horizontalRule':\n return <ToolbarButton key={key} icon={Minus} label=\"Horizontal line\" disabled={disabled} onClick={toggle(editor, 'setHorizontalRule')} />;\n case 'clearFormatting':\n return <ToolbarButton key={key} icon={RemoveFormatting} label=\"Clear formatting\" disabled={disabled} onClick={() => editor.chain().focus().unsetAllMarks().unsetParagraphFormat().unsetTextAlign().run()} />;\n default:\n return null;\n }\n };\n\n return (\n <div className=\"fe-toolbar\" role=\"toolbar\" aria-label=\"Formatting\">\n {items.map(render)}\n </div>\n );\n};\n\nexport default Toolbar;\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nconst keepSelection = (e) => e.preventDefault();\n\nexport const ToolbarButton = ({ icon: Icon, label, active, disabled, onClick, children }) => (\n <button\n type=\"button\"\n className={`fe-btn${active ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n aria-pressed={active ? 'true' : undefined}\n disabled={disabled}\n onMouseDown={keepSelection}\n onClick={onClick}\n >\n {Icon ? <Icon size={16} strokeWidth={2} /> : null}\n {children}\n </button>\n);\n\nexport const Divider = () => <span className=\"fe-divider\" aria-hidden=\"true\" />;\n\nexport const Popover = ({ trigger, children, disabled, className }) => {\n const [open, setOpen] = useState(false);\n const [alignRight, setAlignRight] = useState(false);\n const ref = useRef(null);\n const panelRef = useRef(null);\n\n // The editor clips overflow, so open leftwards when the panel would run past its right edge.\n useLayoutEffect(() => {\n if (!open) return setAlignRight(false);\n const panel = panelRef.current;\n const bounds = ref.current?.closest('.fe-editor')?.getBoundingClientRect();\n if (panel && bounds) setAlignRight(panel.getBoundingClientRect().right > bounds.right);\n return undefined;\n }, [open]);\n\n useEffect(() => {\n if (!open) return undefined;\n const close = (e) => {\n if (ref.current && !ref.current.contains(e.target)) setOpen(false);\n };\n const onKey = (e) => e.key === 'Escape' && setOpen(false);\n document.addEventListener('mousedown', close);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', close);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <span className=\"fe-popover-anchor\" ref={ref}>\n {trigger({ open, toggle: () => !disabled && setOpen((o) => !o) })}\n {open ? (\n <div\n ref={panelRef}\n className={`fe-popover${className ? ` ${className}` : ''}${alignRight ? ' fe-popover--right' : ''}`}\n onMouseDown={keepSelection}\n >\n {children({ close: () => setOpen(false) })}\n </div>\n ) : null}\n </span>\n );\n};\n","import React, { useEffect, useRef } from 'react';\nimport { Popover } from './controls';\n\nconst SelectList = ({ options, value, minWidth, onPick }) => {\n const listRef = useRef(null);\n\n useEffect(() => {\n listRef.current?.querySelector('.is-checked')?.scrollIntoView?.({ block: 'nearest' });\n }, []);\n\n return (\n <div className=\"fe-menu fe-menu--select\" role=\"listbox\" ref={listRef} style={{ minWidth }}>\n {options\n .filter((opt) => !opt.hidden)\n .map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"option\"\n aria-selected={opt.value === value}\n className={`fe-menu__item${opt.value === value ? ' is-checked' : ''}`}\n style={opt.style}\n onClick={() => onPick(opt.value)}\n >\n {opt.menuLabel || opt.label}\n </button>\n ))}\n </div>\n );\n};\n\nconst ToolbarSelect = ({ label, value, options, disabled, onChange, width }) => {\n const current = options.find((opt) => opt.value === value);\n\n return (\n <Popover\n disabled={disabled}\n className=\"fe-popover--menu\"\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-select${open ? ' fe-select--open' : ''}`}\n title={label}\n aria-label={label}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={disabled}\n style={width ? { width } : undefined}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <span className=\"fe-select__value\">{current?.label ?? label}</span>\n </button>\n )}\n >\n {({ close }) => (\n <SelectList\n options={options}\n value={value}\n minWidth={width}\n onPick={(v) => {\n if (v !== value) onChange(v);\n close();\n }}\n />\n )}\n </Popover>\n );\n};\n\nexport default ToolbarSelect;\n","import React from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { COLOR_SWATCHES } from './constants';\nimport { Popover } from './controls';\n\nconst ColorButton = ({ icon: Icon, label, color, disabled, onPick, onClear, clearLabel }) => (\n <Popover\n disabled={disabled}\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn fe-btn--split${open ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <span className=\"fe-color-icon\">\n <Icon size={16} />\n <span className=\"fe-color-bar\" style={{ background: color || 'transparent' }} />\n </span>\n <ChevronDown size={12} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-colors\">\n <button\n type=\"button\"\n className=\"fe-colors__clear\"\n onClick={() => {\n onClear();\n close();\n }}\n >\n {clearLabel}\n </button>\n <div className=\"fe-colors__grid\">\n {COLOR_SWATCHES.map((c) => (\n <button\n key={c}\n type=\"button\"\n className=\"fe-swatch\"\n title={c}\n aria-label={c}\n style={{ background: c }}\n onClick={() => {\n onPick(c);\n close();\n }}\n />\n ))}\n </div>\n <label className=\"fe-colors__custom\">\n More colours\n <input\n type=\"color\"\n value={/^#[0-9a-f]{6}$/i.test(color || '') ? color : '#000000'}\n onChange={(e) => onPick(e.target.value)}\n />\n </label>\n </div>\n )}\n </Popover>\n);\n\nexport default ColorButton;\n","import React, { useState } from 'react';\nimport { Table2 } from 'lucide-react';\nimport { TABLE_PICKER_SIZE } from './constants';\nimport { Popover } from './controls';\n\nconst TablePicker = ({ editor, disabled }) => {\n const [hover, setHover] = useState({ rows: 0, cols: 0 });\n const { rows, cols } = TABLE_PICKER_SIZE;\n\n return (\n <Popover\n disabled={disabled}\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn${open ? ' fe-btn--active' : ''}`}\n title=\"Insert table\"\n aria-label=\"Insert table\"\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <Table2 size={16} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-table-picker\" onMouseLeave={() => setHover({ rows: 0, cols: 0 })}>\n <div\n className=\"fe-table-picker__grid\"\n style={{ gridTemplateColumns: `repeat(${cols}, 16px)` }}\n >\n {Array.from({ length: rows * cols }, (_, i) => {\n const r = Math.floor(i / cols) + 1;\n const c = (i % cols) + 1;\n const on = r <= hover.rows && c <= hover.cols;\n return (\n <button\n key={i}\n type=\"button\"\n aria-label={`${r} by ${c} table`}\n className={`fe-table-picker__cell${on ? ' is-on' : ''}`}\n onMouseEnter={() => setHover({ rows: r, cols: c })}\n onClick={() => {\n editor.chain().focus().insertTable({ rows: r, cols: c, withHeaderRow: false }).run();\n close();\n }}\n />\n );\n })}\n </div>\n <div className=\"fe-table-picker__label\">\n {hover.rows ? `${hover.rows} × ${hover.cols} table` : 'Insert table'}\n </div>\n </div>\n )}\n </Popover>\n );\n};\n\nexport default TablePicker;\n","import React from 'react';\nimport { Check, ChevronDown } from 'lucide-react';\nimport { Popover } from './controls';\n\nconst MenuButton = ({ icon: Icon, label, items, value, disabled, onSelect, showChecks }) => (\n <Popover\n disabled={disabled}\n className=\"fe-popover--menu\"\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn fe-btn--split${open ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <Icon size={16} />\n <ChevronDown size={12} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-menu\" role=\"menu\" aria-label={label}>\n {items.map((item, i) => {\n if (item === '|') return <div key={`s${i}`} className=\"fe-menu__sep\" role=\"separator\" />;\n const checked = item.checked ?? (value !== undefined && item.value === value);\n return (\n <button\n key={item.value}\n type=\"button\"\n role={showChecks ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked={showChecks ? !!checked : undefined}\n className={`fe-menu__item${checked ? ' is-checked' : ''}`}\n disabled={item.disabled}\n onClick={() => {\n onSelect(item.value);\n close();\n }}\n >\n {showChecks ? (\n <span className=\"fe-menu__check\">{checked ? <Check size={14} /> : null}</span>\n ) : null}\n {item.icon ? <span className=\"fe-menu__icon\">{item.icon}</span> : null}\n <span>{item.label}</span>\n </button>\n );\n })}\n </div>\n )}\n </Popover>\n);\n\nexport default MenuButton;\n","import React from 'react';\n\nconst LINES = {\n top: 'M2 2H14',\n bottom: 'M2 14H14',\n left: 'M2 2V14',\n right: 'M14 2V14',\n insideH: 'M2 8H14',\n insideV: 'M8 2V14',\n};\n\nexport const BorderIcon = ({ lines = [] }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d={Object.values(LINES).join(' ')}\n stroke=\"currentColor\"\n strokeOpacity=\".35\"\n strokeDasharray=\"1 1.5\"\n />\n {lines.length ? (\n <path d={lines.map((l) => LINES[l]).join(' ')} stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"square\" />\n ) : null}\n </svg>\n);\n\n// Gap between three groups of lines grows with the spacing preset.\nexport const SpacingIcon = ({ gap = 2 }) => {\n const rows = [];\n let y = 2;\n for (let group = 0; group < 3 && y < 15; group += 1) {\n rows.push(y, y + 2);\n y += 4 + gap;\n }\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d={rows.filter((r) => r < 15).map((r) => `M2 ${r}H14`).join(' ')} stroke=\"currentColor\" />\n </svg>\n );\n};\n","import React from 'react';\nimport {\n BetweenHorizontalEnd,\n BetweenHorizontalStart,\n BetweenVerticalEnd,\n BetweenVerticalStart,\n PaintBucket,\n PanelTop,\n SquareSplitHorizontal,\n TableCellsMerge,\n Trash2,\n Rows3,\n Columns3,\n AlignVerticalJustifyStart,\n AlignVerticalJustifyCenter,\n AlignVerticalJustifyEnd,\n} from 'lucide-react';\nimport { Divider, ToolbarButton } from './controls';\nimport ColorButton from './ColorButton';\nimport MenuButton from './MenuButton';\nimport { BorderIcon } from './icons';\nimport { TABLE_BORDER_OPTIONS } from './constants';\n\nconst AllBordersIcon = () => <BorderIcon lines={['top', 'bottom', 'left', 'right', 'insideH', 'insideV']} />;\n\nconst unavailable = (mode, borders) => {\n if (mode === 'inside') return !borders?.hasInside;\n if (mode === 'insideH' || mode === 'insideV') return !borders?.exists?.[mode];\n return false;\n};\n\nconst borderItems = (borders) =>\n TABLE_BORDER_OPTIONS.map((opt) =>\n opt === '|'\n ? opt\n : {\n value: opt.value,\n label: opt.label,\n icon: <BorderIcon lines={opt.lines} />,\n checked: !!borders?.[opt.value],\n disabled: unavailable(opt.value, borders),\n },\n );\n\nconst VALIGN = [\n { value: 'top', icon: AlignVerticalJustifyStart, label: 'Align cell top' },\n { value: 'middle', icon: AlignVerticalJustifyCenter, label: 'Align cell middle' },\n { value: 'bottom', icon: AlignVerticalJustifyEnd, label: 'Align cell bottom' },\n];\n\nconst TableTools = ({ editor, state, disabled }) => {\n const run = (fn) => () => fn(editor.chain().focus()).run();\n const can = editor.can();\n\n return (\n <div className=\"fe-toolbar fe-toolbar--table\" role=\"toolbar\" aria-label=\"Table tools\">\n <span className=\"fe-toolbar__caption\">Table</span>\n <ToolbarButton icon={BetweenHorizontalStart} label=\"Insert row above\" disabled={disabled} onClick={run((c) => c.addRowBefore())} />\n <ToolbarButton icon={BetweenHorizontalEnd} label=\"Insert row below\" disabled={disabled} onClick={run((c) => c.addRowAfter())} />\n <ToolbarButton icon={BetweenVerticalStart} label=\"Insert column left\" disabled={disabled} onClick={run((c) => c.addColumnBefore())} />\n <ToolbarButton icon={BetweenVerticalEnd} label=\"Insert column right\" disabled={disabled} onClick={run((c) => c.addColumnAfter())} />\n <Divider />\n <ToolbarButton icon={Rows3} label=\"Delete row\" disabled={disabled} onClick={run((c) => c.deleteRow())} />\n <ToolbarButton icon={Columns3} label=\"Delete column\" disabled={disabled} onClick={run((c) => c.deleteColumn())} />\n <ToolbarButton icon={Trash2} label=\"Delete table\" disabled={disabled} onClick={run((c) => c.deleteTable())} />\n <Divider />\n <ToolbarButton icon={TableCellsMerge} label=\"Merge cells\" disabled={disabled || !can.mergeCells()} onClick={run((c) => c.mergeCells())} />\n <ToolbarButton icon={SquareSplitHorizontal} label=\"Split cell\" disabled={disabled || !can.splitCell()} onClick={run((c) => c.splitCell())} />\n <ToolbarButton icon={PanelTop} label=\"Toggle header row\" disabled={disabled} onClick={run((c) => c.toggleHeaderRow())} />\n <Divider />\n <ColorButton\n icon={PaintBucket}\n label=\"Cell shading\"\n clearLabel=\"No fill\"\n color={state.cellBackground}\n disabled={disabled}\n onPick={(color) => editor.chain().focus().setCellAttribute('backgroundColor', color).run()}\n onClear={() => editor.chain().focus().setCellAttribute('backgroundColor', null).run()}\n />\n {VALIGN.map(({ value, icon, label }) => (\n <ToolbarButton\n key={value}\n icon={icon}\n label={label}\n active={state.cellVerticalAlign === value}\n disabled={disabled}\n onClick={run((c) => c.setCellAttribute('verticalAlign', value))}\n />\n ))}\n <MenuButton\n icon={AllBordersIcon}\n label=\"Borders\"\n items={borderItems(state.tableBorders)}\n showChecks\n disabled={disabled}\n onSelect={(mode) => editor.chain().focus().setTableBorders(mode).run()}\n />\n </div>\n );\n};\n\nexport default TableTools;\n","import { matchSpacingPreset } from '../extensions/paragraphFormat';\nimport { getTableBorderState } from '../extensions/tableBorders';\n\nconst blockTypeOf = (editor) => {\n for (let level = 1; level <= 4; level += 1) {\n if (editor.isActive('heading', { level })) return `h${level}`;\n }\n return 'paragraph';\n};\n\nconst currentBlockAttrs = (editor) => {\n const { $from } = editor.state.selection;\n for (let d = $from.depth; d >= 0; d -= 1) {\n const node = $from.node(d);\n if (node.type.name === 'paragraph' || node.type.name === 'heading') return node.attrs;\n }\n return {};\n};\n\nconst currentCellAttrs = (editor) => {\n const { $from } = editor.state.selection;\n for (let d = $from.depth; d >= 0; d -= 1) {\n const node = $from.node(d);\n if (node.type.name === 'tableCell' || node.type.name === 'tableHeader') return node.attrs;\n }\n return null;\n};\n\nexport const selectToolbarState = ({ editor }) => {\n if (!editor) return {};\n const textStyle = editor.getAttributes('textStyle');\n const block = currentBlockAttrs(editor);\n const cell = currentCellAttrs(editor);\n return {\n bold: editor.isActive('bold'),\n italic: editor.isActive('italic'),\n underline: editor.isActive('underline'),\n strike: editor.isActive('strike'),\n subscript: editor.isActive('subscript'),\n superscript: editor.isActive('superscript'),\n bulletList: editor.isActive('bulletList'),\n orderedList: editor.isActive('orderedList'),\n link: editor.isActive('link'),\n blockType: blockTypeOf(editor),\n textAlign: block.textAlign || 'left',\n lineHeight: block.lineHeight || null,\n paragraphSpacing: matchSpacingPreset(block),\n fontFamily: textStyle.fontFamily || '',\n fontSize: textStyle.fontSize || '',\n color: textStyle.color || null,\n backgroundColor: textStyle.backgroundColor || null,\n canUndo: editor.can().undo(),\n canRedo: editor.can().redo(),\n inTable: !!cell,\n cellBackground: cell?.backgroundColor || null,\n cellVerticalAlign: cell?.verticalAlign || null,\n tableBorders: cell ? getTableBorderState(editor.state) : null,\n };\n};\n"],"mappings":"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","names":["React","useEffect","useRef","React","useRef","React","useEffect","useRef","jsx","useRef","useEffect","toggle","React","jsx","jsxs","toggle","React","useState","jsx","jsxs","useState","toggle","React","ChevronDown","jsx","jsxs","toggle","ChevronDown","React","jsx","jsxs","jsx","jsxs","useRef","React","React","jsx","jsxs","jsx","jsxs","useRef","editor","useEffect"]}
package/dist/pdf.cjs ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ var _chunkNNYINC42cjs = require('./chunk-NNYINC42.cjs');
10
+
11
+ // src/pdf/render.jsx
12
+ var _react = require('react'); var _react2 = _interopRequireDefault(_react);
13
+ var _renderer = require('@react-pdf/renderer');
14
+ var _jsxruntime = require('react/jsx-runtime');
15
+ var COMPONENTS = { root: _renderer.View, view: _renderer.View, text: _renderer.Text, link: _renderer.Link, image: _renderer.Image };
16
+ var renderNode = (node, key, components) => {
17
+ if (typeof node === "string") return node;
18
+ if (!node) return null;
19
+ const Component = components[node.type] || _renderer.View;
20
+ const props = { key, style: node.style, ...node.props || {} };
21
+ if (node.type === "image") return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, { ...props, src: node.src });
22
+ if (node.type === "link") props.src = node.src;
23
+ const children = (node.children || []).map((child, i) => renderNode(child, i, components));
24
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, { ...props, children });
25
+ };
26
+ var renderPdfTree = (tree, { components } = {}) => renderNode(tree, void 0, { ...COMPONENTS, ...components || {} });
27
+ var toPdfTree = (value, options) => {
28
+ if (_chunkNNYINC42cjs.isPdfTree.call(void 0, value)) return value;
29
+ if (value === null || value === void 0 || value === "") return _chunkNNYINC42cjs.jsonToPdfTree.call(void 0, null, options);
30
+ return _chunkNNYINC42cjs.jsonToPdfTree.call(void 0, _chunkNNYINC42cjs.isDocJson.call(void 0, value) ? value : _chunkNNYINC42cjs.toDocJson.call(void 0, value), options);
31
+ };
32
+ var RichTextPdf = ({ value, children, options, style, components }) => {
33
+ const source = value != null ? value : children;
34
+ const styleFontSize = typeof (style == null ? void 0 : style.fontSize) === "number" ? style.fontSize : void 0;
35
+ const tree = _react.useMemo.call(void 0,
36
+ () => toPdfTree(
37
+ source,
38
+ styleFontSize && (options == null ? void 0 : options.fontSize) === void 0 ? { ...options, fontSize: styleFontSize } : options
39
+ ),
40
+ [source, options, styleFontSize]
41
+ );
42
+ const rendered = renderPdfTree(tree, { components });
43
+ if (!style) return rendered;
44
+ return _react2.default.cloneElement(rendered, { style: [tree.style, style] });
45
+ };
46
+ var render_default = RichTextPdf;
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+ exports.DEFAULT_PDF_OPTIONS = _chunkNNYINC42cjs.DEFAULT_PDF_OPTIONS; exports.PDF_TREE_VERSION = _chunkNNYINC42cjs.PDF_TREE_VERSION; exports.RichTextPdf = RichTextPdf; exports.STANDARD_FONTS = _chunkNNYINC42cjs.STANDARD_FONTS; exports.default = render_default; exports.isPdfTree = _chunkNNYINC42cjs.isPdfTree; exports.jsonToPdfTree = _chunkNNYINC42cjs.jsonToPdfTree; exports.renderPdfTree = renderPdfTree; exports.toPdfTree = toPdfTree;
58
+ //# sourceMappingURL=pdf.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/harsh/Documents/Flabs/flabs-editor/dist/pdf.cjs","../src/pdf/render.jsx"],"names":[],"mappings":"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","file":"/Users/harsh/Documents/Flabs/flabs-editor/dist/pdf.cjs","sourcesContent":[null,"import React, { useMemo } from 'react';\nimport { Image, Link, Text, View } from '@react-pdf/renderer';\nimport { isDocJson, toDocJson } from '../output/convert';\nimport { isPdfTree, jsonToPdfTree } from './tree';\n\nconst COMPONENTS = { root: View, view: View, text: Text, link: Link, image: Image };\n\nconst renderNode = (node, key, components) => {\n if (typeof node === 'string') return node;\n if (!node) return null;\n const Component = components[node.type] || View;\n const props = { key, style: node.style, ...(node.props || {}) };\n if (node.type === 'image') return <Component {...props} src={node.src} />;\n if (node.type === 'link') props.src = node.src;\n const children = (node.children || []).map((child, i) => renderNode(child, i, components));\n return <Component {...props}>{children}</Component>;\n};\n\nexport const renderPdfTree = (tree, { components } = {}) =>\n renderNode(tree, undefined, { ...COMPONENTS, ...(components || {}) });\n\n// Accepts editor HTML (including legacy TinyMCE HTML), editor JSON or a\n// ready pdf tree, and renders react-pdf elements directly.\nexport const toPdfTree = (value, options) => {\n if (isPdfTree(value)) return value;\n if (value === null || value === undefined || value === '') return jsonToPdfTree(null, options);\n return jsonToPdfTree(isDocJson(value) ? value : toDocJson(value), options);\n};\n\nexport const RichTextPdf = ({ value, children, options, style, components }) => {\n const source = value ?? children;\n const styleFontSize = typeof style?.fontSize === 'number' ? style.fontSize : undefined;\n const tree = useMemo(\n () =>\n toPdfTree(\n source,\n styleFontSize && options?.fontSize === undefined ? { ...options, fontSize: styleFontSize } : options,\n ),\n [source, options, styleFontSize],\n );\n const rendered = renderPdfTree(tree, { components });\n if (!style) return rendered;\n return React.cloneElement(rendered, { style: [tree.style, style] });\n};\n\nexport default RichTextPdf;\n"]}
package/dist/pdf.js ADDED
@@ -0,0 +1,58 @@
1
+ import {
2
+ DEFAULT_PDF_OPTIONS,
3
+ PDF_TREE_VERSION,
4
+ STANDARD_FONTS,
5
+ isDocJson,
6
+ isPdfTree,
7
+ jsonToPdfTree,
8
+ toDocJson
9
+ } from "./chunk-JQEG2JQ7.js";
10
+
11
+ // src/pdf/render.jsx
12
+ import React, { useMemo } from "react";
13
+ import { Image, Link, Text, View } from "@react-pdf/renderer";
14
+ import { jsx } from "react/jsx-runtime";
15
+ var COMPONENTS = { root: View, view: View, text: Text, link: Link, image: Image };
16
+ var renderNode = (node, key, components) => {
17
+ if (typeof node === "string") return node;
18
+ if (!node) return null;
19
+ const Component = components[node.type] || View;
20
+ const props = { key, style: node.style, ...node.props || {} };
21
+ if (node.type === "image") return /* @__PURE__ */ jsx(Component, { ...props, src: node.src });
22
+ if (node.type === "link") props.src = node.src;
23
+ const children = (node.children || []).map((child, i) => renderNode(child, i, components));
24
+ return /* @__PURE__ */ jsx(Component, { ...props, children });
25
+ };
26
+ var renderPdfTree = (tree, { components } = {}) => renderNode(tree, void 0, { ...COMPONENTS, ...components || {} });
27
+ var toPdfTree = (value, options) => {
28
+ if (isPdfTree(value)) return value;
29
+ if (value === null || value === void 0 || value === "") return jsonToPdfTree(null, options);
30
+ return jsonToPdfTree(isDocJson(value) ? value : toDocJson(value), options);
31
+ };
32
+ var RichTextPdf = ({ value, children, options, style, components }) => {
33
+ const source = value != null ? value : children;
34
+ const styleFontSize = typeof (style == null ? void 0 : style.fontSize) === "number" ? style.fontSize : void 0;
35
+ const tree = useMemo(
36
+ () => toPdfTree(
37
+ source,
38
+ styleFontSize && (options == null ? void 0 : options.fontSize) === void 0 ? { ...options, fontSize: styleFontSize } : options
39
+ ),
40
+ [source, options, styleFontSize]
41
+ );
42
+ const rendered = renderPdfTree(tree, { components });
43
+ if (!style) return rendered;
44
+ return React.cloneElement(rendered, { style: [tree.style, style] });
45
+ };
46
+ var render_default = RichTextPdf;
47
+ export {
48
+ DEFAULT_PDF_OPTIONS,
49
+ PDF_TREE_VERSION,
50
+ RichTextPdf,
51
+ STANDARD_FONTS,
52
+ render_default as default,
53
+ isPdfTree,
54
+ jsonToPdfTree,
55
+ renderPdfTree,
56
+ toPdfTree
57
+ };
58
+ //# sourceMappingURL=pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pdf/render.jsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { Image, Link, Text, View } from '@react-pdf/renderer';\nimport { isDocJson, toDocJson } from '../output/convert';\nimport { isPdfTree, jsonToPdfTree } from './tree';\n\nconst COMPONENTS = { root: View, view: View, text: Text, link: Link, image: Image };\n\nconst renderNode = (node, key, components) => {\n if (typeof node === 'string') return node;\n if (!node) return null;\n const Component = components[node.type] || View;\n const props = { key, style: node.style, ...(node.props || {}) };\n if (node.type === 'image') return <Component {...props} src={node.src} />;\n if (node.type === 'link') props.src = node.src;\n const children = (node.children || []).map((child, i) => renderNode(child, i, components));\n return <Component {...props}>{children}</Component>;\n};\n\nexport const renderPdfTree = (tree, { components } = {}) =>\n renderNode(tree, undefined, { ...COMPONENTS, ...(components || {}) });\n\n// Accepts editor HTML (including legacy TinyMCE HTML), editor JSON or a\n// ready pdf tree, and renders react-pdf elements directly.\nexport const toPdfTree = (value, options) => {\n if (isPdfTree(value)) return value;\n if (value === null || value === undefined || value === '') return jsonToPdfTree(null, options);\n return jsonToPdfTree(isDocJson(value) ? value : toDocJson(value), options);\n};\n\nexport const RichTextPdf = ({ value, children, options, style, components }) => {\n const source = value ?? children;\n const styleFontSize = typeof style?.fontSize === 'number' ? style.fontSize : undefined;\n const tree = useMemo(\n () =>\n toPdfTree(\n source,\n styleFontSize && options?.fontSize === undefined ? { ...options, fontSize: styleFontSize } : options,\n ),\n [source, options, styleFontSize],\n );\n const rendered = renderPdfTree(tree, { components });\n if (!style) return rendered;\n return React.cloneElement(rendered, { style: [tree.style, style] });\n};\n\nexport default RichTextPdf;\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,SAAS,eAAe;AAC/B,SAAS,OAAO,MAAM,MAAM,YAAY;AAWJ;AAPpC,IAAM,aAAa,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,MAAM;AAElF,IAAM,aAAa,CAAC,MAAM,KAAK,eAAe;AAC5C,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,YAAY,WAAW,KAAK,IAAI,KAAK;AAC3C,QAAM,QAAQ,EAAE,KAAK,OAAO,KAAK,OAAO,GAAI,KAAK,SAAS,CAAC,EAAG;AAC9D,MAAI,KAAK,SAAS,QAAS,QAAO,oBAAC,aAAW,GAAG,OAAO,KAAK,KAAK,KAAK;AACvE,MAAI,KAAK,SAAS,OAAQ,OAAM,MAAM,KAAK;AAC3C,QAAM,YAAY,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,OAAO,MAAM,WAAW,OAAO,GAAG,UAAU,CAAC;AACzF,SAAO,oBAAC,aAAW,GAAG,OAAQ,UAAS;AACzC;AAEO,IAAM,gBAAgB,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,MACpD,WAAW,MAAM,QAAW,EAAE,GAAG,YAAY,GAAI,cAAc,CAAC,EAAG,CAAC;AAI/D,IAAM,YAAY,CAAC,OAAO,YAAY;AAC3C,MAAI,UAAU,KAAK,EAAG,QAAO;AAC7B,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GAAI,QAAO,cAAc,MAAM,OAAO;AAC7F,SAAO,cAAc,UAAU,KAAK,IAAI,QAAQ,UAAU,KAAK,GAAG,OAAO;AAC3E;AAEO,IAAM,cAAc,CAAC,EAAE,OAAO,UAAU,SAAS,OAAO,WAAW,MAAM;AAC9E,QAAM,SAAS,wBAAS;AACxB,QAAM,gBAAgB,QAAO,+BAAO,cAAa,WAAW,MAAM,WAAW;AAC7E,QAAM,OAAO;AAAA,IACX,MACE;AAAA,MACE;AAAA,MACA,kBAAiB,mCAAS,cAAa,SAAY,EAAE,GAAG,SAAS,UAAU,cAAc,IAAI;AAAA,IAC/F;AAAA,IACF,CAAC,QAAQ,SAAS,aAAa;AAAA,EACjC;AACA,QAAM,WAAW,cAAc,MAAM,EAAE,WAAW,CAAC;AACnD,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,aAAa,UAAU,EAAE,OAAO,CAAC,KAAK,OAAO,KAAK,EAAE,CAAC;AACpE;AAEA,IAAO,iBAAQ;","names":[]}
package/dist/style.css ADDED
@@ -0,0 +1,164 @@
1
+ .fe-editor {
2
+ --fe-primary: #2d5cf2;
3
+ --fe-primary-soft: #e8eefe;
4
+ --fe-border: #d9d9d9;
5
+ --fe-toolbar-bg: #f7f8fa;
6
+ --fe-text: #1f1f1f;
7
+ --fe-muted: #6b7280;
8
+ --fe-canvas: #eef0f3;
9
+ --fe-radius: 6px;
10
+ --fe-font: Roboto, -apple-system, 'Segoe UI', Arial, sans-serif;
11
+ --fe-content-font: Roboto, Arial, sans-serif;
12
+ --fe-content-size: 14px;
13
+ --fe-grid: #c0c4cc;
14
+
15
+ display: flex;
16
+ flex-direction: column;
17
+ border: 1px solid var(--fe-border);
18
+ border-radius: var(--fe-radius);
19
+ background: #fff;
20
+ color: var(--fe-text);
21
+ font-family: var(--fe-font);
22
+ overflow: hidden;
23
+ box-sizing: border-box;
24
+ }
25
+ .fe-editor *,
26
+ .fe-editor *::before,
27
+ .fe-editor *::after { box-sizing: border-box; }
28
+
29
+ /* Toolbar */
30
+ .fe-toolbars { flex: none; border-bottom: 1px solid var(--fe-border); background: var(--fe-toolbar-bg); }
31
+ .fe-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding: 4px 6px; }
32
+ .fe-toolbar--table { border-top: 1px solid var(--fe-border); background: #fbfbfc; }
33
+ .fe-toolbar__caption { font-size: 11px; font-weight: 600; color: var(--fe-primary); text-transform: uppercase; letter-spacing: .04em; margin: 0 6px 0 2px; }
34
+ .fe-divider { width: 1px; height: 20px; background: var(--fe-border); margin: 0 4px; }
35
+
36
+ .fe-btn {
37
+ display: inline-flex; align-items: center; justify-content: center; gap: 2px;
38
+ min-width: 28px; height: 28px; padding: 0 5px;
39
+ border: 1px solid transparent; border-radius: 4px; background: transparent;
40
+ color: #3a3f47; cursor: pointer; font: inherit; line-height: 1;
41
+ }
42
+ .fe-btn:hover:not(:disabled) { background: #e9ebef; }
43
+ .fe-btn--active, .fe-btn--active:hover:not(:disabled) { background: var(--fe-primary-soft); border-color: #c9d6fc; color: var(--fe-primary); }
44
+ .fe-btn:disabled { opacity: .4; cursor: default; }
45
+ .fe-btn:focus-visible, .fe-select:focus-visible { outline: 2px solid var(--fe-primary); outline-offset: 1px; }
46
+ .fe-btn--split { padding: 0 3px 0 5px; }
47
+
48
+ .fe-select {
49
+ height: 28px; padding: 0 24px 0 8px; border: 1px solid var(--fe-border); border-radius: 4px;
50
+ background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center;
51
+ color: var(--fe-text); font: inherit; font-size: 13px; cursor: pointer;
52
+ display: inline-flex; align-items: center; flex: none; text-align: left;
53
+ white-space: nowrap; overflow: hidden; transition: border-color .15s;
54
+ }
55
+ .fe-select:hover:not(:disabled) { border-color: #b8bdc6; }
56
+ .fe-select--open, .fe-select--open:hover:not(:disabled) { border-color: var(--fe-primary); box-shadow: 0 0 0 2px var(--fe-primary-soft); }
57
+ .fe-select__value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
58
+ .fe-select:disabled { opacity: .5; cursor: default; }
59
+
60
+ .fe-color-icon { display: inline-flex; flex-direction: column; align-items: center; }
61
+ .fe-color-bar { width: 16px; height: 3px; margin-top: 1px; border-radius: 1px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.12); }
62
+
63
+ .fe-popover-anchor { position: relative; display: inline-flex; }
64
+ .fe-popover {
65
+ position: absolute; top: calc(100% + 4px); left: 0; z-index: 1050;
66
+ padding: 8px; background: #fff; border: 1px solid var(--fe-border); border-radius: var(--fe-radius);
67
+ box-shadow: 0 6px 16px rgba(0,0,0,.08), 0 3px 6px -4px rgba(0,0,0,.12);
68
+ }
69
+ .fe-colors { width: 172px; display: flex; flex-direction: column; gap: 8px; font-size: 12px; }
70
+ .fe-colors__clear { border: 1px solid var(--fe-border); background: #fff; border-radius: 4px; padding: 4px; cursor: pointer; font: inherit; }
71
+ .fe-colors__clear:hover { background: #f3f4f6; }
72
+ .fe-colors__grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 4px; }
73
+ .fe-swatch { width: 22px; height: 22px; border-radius: 3px; border: 1px solid rgba(0,0,0,.15); cursor: pointer; padding: 0; }
74
+ .fe-swatch:hover { transform: scale(1.12); }
75
+ .fe-colors__custom { display: flex; align-items: center; justify-content: space-between; color: var(--fe-muted); cursor: pointer; }
76
+ .fe-colors__custom input { width: 32px; height: 22px; border: none; padding: 0; background: none; cursor: pointer; }
77
+
78
+ .fe-table-picker__grid { display: grid; gap: 2px; }
79
+ .fe-table-picker__cell { width: 16px; height: 16px; border: 1px solid #c8ccd4; background: #fff; border-radius: 2px; padding: 0; cursor: pointer; }
80
+ .fe-table-picker__cell.is-on { background: var(--fe-primary-soft); border-color: var(--fe-primary); }
81
+ .fe-table-picker__label { margin-top: 6px; text-align: center; font-size: 12px; color: var(--fe-muted); }
82
+
83
+ /* Writing area */
84
+ .fe-scroll { flex: 1 1 auto; overflow: auto; cursor: text; background: #fff; }
85
+ .fe-editor--sized .fe-scroll { min-height: 0; }
86
+ .fe-page { min-height: 100%; }
87
+ .fe-editor--page .fe-scroll { background: var(--fe-canvas); padding: 24px 16px; }
88
+ .fe-editor--page .fe-page {
89
+ width: 100%; max-width: 794px; min-height: 1000px; margin: 0 auto; background: #fff;
90
+ box-shadow: 0 1px 3px rgba(0,0,0,.12), 0 0 0 1px rgba(0,0,0,.04);
91
+ }
92
+ .fe-editor--page .fe-content { padding: 72px 72px; }
93
+ .fe-editor--disabled .fe-scroll { background: #fafafa; cursor: default; }
94
+ .fe-status { flex: none; padding: 2px 10px; border-top: 1px solid var(--fe-border); background: var(--fe-toolbar-bg); font-size: 11px; color: var(--fe-muted); text-align: right; }
95
+
96
+ /* Content */
97
+ .fe-content {
98
+ min-height: 100%; padding: 12px 16px; outline: none;
99
+ font-family: var(--fe-content-font); font-size: var(--fe-content-size); line-height: 1.4;
100
+ color: var(--fe-text); word-wrap: break-word; white-space: pre-wrap;
101
+ }
102
+ .fe-content > * + * { margin-top: 0; }
103
+ .fe-content p { margin: 0 0 6px; }
104
+ .fe-content h1, .fe-content h2, .fe-content h3, .fe-content h4 { margin: 10px 0 6px; line-height: 1.25; font-weight: 700; }
105
+ .fe-content h1 { font-size: 2em; }
106
+ .fe-content h2 { font-size: 1.6em; }
107
+ .fe-content h3 { font-size: 1.3em; }
108
+ .fe-content h4 { font-size: 1.15em; }
109
+ .fe-content ul, .fe-content ol { margin: 0 0 6px; padding-left: 28px; }
110
+ .fe-content li > p { margin: 0 0 2px; }
111
+ .fe-content blockquote { margin: 0 0 6px; padding-left: 12px; border-left: 3px solid #d0d4da; color: #4b5563; }
112
+ .fe-content hr { border: none; border-top: 1px solid #b8bcc4; margin: 10px 0; }
113
+ .fe-content hr.ProseMirror-selectednode { border-top-color: var(--fe-primary); }
114
+ .fe-content a { color: var(--fe-primary); text-decoration: underline; }
115
+ .fe-content img { max-width: 100%; height: auto; display: block; margin: 4px 0; }
116
+ .fe-content img.ProseMirror-selectednode { outline: 2px solid var(--fe-primary); }
117
+ .fe-content code { background: #f3f4f6; border-radius: 3px; padding: 1px 4px; font-size: .9em; }
118
+
119
+ .fe-content table { border-collapse: collapse; table-layout: fixed; margin: 0 0 8px; max-width: 100%; overflow: hidden; }
120
+ .fe-content td, .fe-content th {
121
+ position: relative; vertical-align: top; min-width: 24px; padding: 3px 6px;
122
+ border: 1px solid #000;
123
+ }
124
+ .fe-content th { font-weight: 700; text-align: left; background: #f5f6f8; }
125
+ .fe-content td > p, .fe-content th > p { margin: 0; }
126
+ /* Light guide for cells whose borders are off, like Word's gridlines. */
127
+ .fe-editor:not(.fe-editor--disabled) .fe-content td[style*=": none"]::before,
128
+ .fe-editor:not(.fe-editor--disabled) .fe-content th[style*=": none"]::before {
129
+ content: ''; position: absolute; inset: 0; border: 1px dashed #d5d8de; pointer-events: none;
130
+ }
131
+ .fe-content .selectedCell::after {
132
+ content: ''; position: absolute; inset: 0; background: rgba(45, 92, 242, .12); pointer-events: none; z-index: 2;
133
+ }
134
+ .fe-content .column-resize-handle {
135
+ position: absolute; right: -2px; top: 0; bottom: -2px; width: 4px; background: var(--fe-primary); pointer-events: none; z-index: 3;
136
+ }
137
+ .fe-content.resize-cursor, .fe-editor .resize-cursor { cursor: col-resize; }
138
+ .fe-content table[style*="min-width"] { width: 100%; }
139
+ .fe-content .tableWrapper { overflow-x: auto; max-width: 100%; }
140
+
141
+ .fe-content p.is-editor-empty:first-child::before {
142
+ content: attr(data-placeholder); float: left; height: 0; pointer-events: none; color: #a0a4ab;
143
+ }
144
+ .fe-content .ProseMirror-gapcursor:after { border-top-color: var(--fe-text); }
145
+
146
+ /* Dropdown menus */
147
+ .fe-popover--menu { padding: 4px 0; }
148
+ .fe-menu { display: flex; flex-direction: column; min-width: 180px; font-size: 13px; }
149
+ .fe-menu__item {
150
+ display: flex; align-items: center; gap: 8px; width: 100%; padding: 5px 12px 5px 8px;
151
+ border: none; background: transparent; color: var(--fe-text); font: inherit; text-align: left;
152
+ white-space: nowrap; cursor: pointer;
153
+ }
154
+ .fe-menu__item:hover:not(:disabled) { background: #f0f3fe; }
155
+ .fe-menu__item.is-checked { color: var(--fe-primary); }
156
+ .fe-menu--select { min-width: 0; max-height: 280px; overflow-y: auto; }
157
+ .fe-menu--select .fe-menu__item { padding: 5px 12px; }
158
+ .fe-menu--select .fe-menu__item.is-checked { background: var(--fe-primary-soft); font-weight: 500; }
159
+ .fe-menu__item:disabled { opacity: .4; cursor: default; }
160
+ .fe-menu__check { display: inline-flex; width: 14px; flex: none; }
161
+ .fe-menu__icon { display: inline-flex; flex: none; color: #4b5563; }
162
+ .fe-menu__item.is-checked .fe-menu__icon { color: inherit; }
163
+ .fe-menu__sep { height: 1px; margin: 4px 0; background: var(--fe-border); }
164
+ .fe-popover--right { left: auto; right: 0; }
package/package.json CHANGED
@@ -1,6 +1,86 @@
1
1
  {
2
2
  "name": "react-word-editor",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Word-like rich text editor for React (TipTap based) with faithful Word/Excel paste and HTML, text, JSON and react-pdf outputs.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": [
8
+ "*.css"
9
+ ],
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.js",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ },
17
+ "./convert": {
18
+ "import": "./dist/convert.js",
19
+ "require": "./dist/convert.cjs"
20
+ },
21
+ "./pdf": {
22
+ "import": "./dist/pdf.js",
23
+ "require": "./dist/pdf.cjs"
24
+ },
25
+ "./style.css": "./dist/style.css",
26
+ "./package.json": "./package.json"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "MIGRATION.md"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsup && cp src/styles/editor.css dist/style.css",
35
+ "dev": "vite --config demo/vite.config.js",
36
+ "test": "vitest run",
37
+ "prepublishOnly": "npm run test && npm run build"
38
+ },
39
+ "keywords": [
40
+ "react",
41
+ "rich-text",
42
+ "editor",
43
+ "wysiwyg",
44
+ "tiptap",
45
+ "word",
46
+ "paste",
47
+ "react-pdf"
48
+ ],
49
+ "peerDependencies": {
50
+ "@react-pdf/renderer": ">=3.0.0",
51
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
52
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "@react-pdf/renderer": {
56
+ "optional": true
57
+ }
58
+ },
59
+ "dependencies": {
60
+ "@tiptap/core": "^3.32.2",
61
+ "@tiptap/extension-image": "^3.32.2",
62
+ "@tiptap/extension-subscript": "^3.32.2",
63
+ "@tiptap/extension-superscript": "^3.32.2",
64
+ "@tiptap/extension-table": "^3.32.2",
65
+ "@tiptap/extension-text-align": "^3.32.2",
66
+ "@tiptap/extension-text-style": "^3.32.2",
67
+ "@tiptap/extensions": "^3.32.2",
68
+ "@tiptap/pm": "^3.32.2",
69
+ "@tiptap/react": "^3.32.2",
70
+ "@tiptap/starter-kit": "^3.32.2",
71
+ "lucide-react": "^0.460.0"
72
+ },
73
+ "devDependencies": {
74
+ "@react-pdf/renderer": "^4.3.1",
75
+ "@testing-library/react": "^16.3.3",
76
+ "@vitejs/plugin-react": "^4.7.0",
77
+ "jsdom": "^25.0.1",
78
+ "pdf-parse": "^1.1.1",
79
+ "react": "^18.2.0",
80
+ "react-dom": "^18.2.0",
81
+ "tsup": "^8.5.1",
82
+ "typescript": "^5.9.3",
83
+ "vite": "^6.4.5",
84
+ "vitest": "^2.1.9"
85
+ }
86
+ }