[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-72679":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":18,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":22,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":16,"starSnapshotCount":16,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},72679,"overtype","panphora\u002Fovertype","panphora","The markdown editor that's just a textarea https:\u002F\u002Fovertype.dev","",null,"JavaScript",3665,95,8,5,0,1,3,14,62.85,"MIT License",false,"main",[],"2026-06-12 04:01:06","# OverType\n\nA lightweight markdown editor library with perfect WYSIWYG alignment using an invisible textarea overlay technique. Includes optional toolbar. ~111KB minified with all features.\n\n## Live Examples\n\n🎮 **Try it out**: [Interactive demos on overtype.dev](https:\u002F\u002Fovertype.dev)\n- [Basic Editor](https:\u002F\u002Fovertype.dev\u002F#basic-editor) - Minimal setup with live preview\n- [With Toolbar](https:\u002F\u002Fovertype.dev\u002F#toolbar) - Full formatting toolbar\n- [Multiple Instances](https:\u002F\u002Fovertype.dev\u002Fdemo.html#multiple-instances) - Several editors on one page\n- [View Modes](https:\u002F\u002Fovertype.dev\u002Fdemo.html#view-modes) - Preview synchronization\n- [Themes](https:\u002F\u002Fovertype.dev\u002Fdemo.html#themes) - Light\u002Fdark theme switching\n- [All Features](https:\u002F\u002Fovertype.dev\u002Fdemo.html#markdown-features) - Complete markdown showcase\n\n## Features\n\n- 👻 **Invisible textarea overlay** - Transparent input layer overlaid on styled preview for seamless editing\n- 🎨 **Global theming** - Solar (light) and Cave (dark) themes that apply to all instances\n- ⌨️ **Keyboard shortcuts** - Common markdown shortcuts (Cmd\u002FCtrl+B for bold, etc.)\n- 📱 **Mobile optimized** - Responsive design with mobile-specific styles\n- 🔄 **DOM persistence aware** - Recovers from existing DOM (perfect for HyperClay and similar platforms)\n- 🚀 **Lightweight** - ~111KB minified\n- 🎯 **Optional toolbar** - Clean, minimal toolbar with all essential formatting\n- ✨ **Smart shortcuts** - Keyboard shortcuts with selection preservation\n- 📝 **Smart list continuation** - GitHub-style automatic list continuation on Enter\n- 🔧 **Framework agnostic** - Works with React, Vue, vanilla JS, and more\n\n## How it works\n\n![OverType Architecture Diagram](https:\u002F\u002Fwebsharebox.s3.amazonaws.com\u002Fdiagram.png)\n\nWe overlap an invisible textarea on top of styled output, giving the illusion of editing styled text using a plain textarea.\n\n## Comparisons\n\n| Feature | OverType | HyperMD | Milkdown | TUI Editor | EasyMDE |\n|---------|----------|---------|----------|------------|---------|\n| **Size** | ~111KB | 364.02 KB | 344.51 KB | 560.99 KB | 323.69 KB |\n| **Dependencies** | Bundled | CodeMirror | ProseMirror + plugins | Multiple libs | CodeMirror |\n| **Setup** | Single file | Complex config | Build step required | Complex config | Moderate |\n| **Approach** | Invisible textarea | ContentEditable | ContentEditable | ContentEditable | CodeMirror |\n| **Mobile** | Perfect native | Issues common | Issues common | Issues common | Limited |\n| **Markdown syntax** | Visible | Hidden | Hidden | Toggle | Visible |\n| **Advanced features** | Basic | Full | Full | Full | Moderate |\n| **Best for** | Simple, fast, mobile | Full WYSIWYG | Modern frameworks | Enterprise apps | Classic editing |\n\n**Choose OverType when you need:**\n- Tiny bundle size (10x smaller than alternatives)\n- Zero dependencies - single file that works immediately\n- Perfect native browser features (undo\u002Fredo, mobile keyboards, optional spellcheck)\n- Dead-simple integration without build tools\n- Easy to understand, modify, and extend\n- Excellent mobile support with visible markdown syntax\n\n**Choose other editors when you need:**\n- Full WYSIWYG with hidden markdown syntax\n- Advanced features like tables, diagrams, or collaborative editing\n- Rich plugin ecosystems\n- Enterprise features and extensive customization\n- Framework-specific integration (React, Vue, etc.)\n- Complex multi-layered architecture for deep customization\n\n## Installation\n\n### NPM\n```bash\nnpm install overtype\n```\n\n### CDN\n```html\n\u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002Fovertype@latest\u002Fdist\u002Fovertype.min.js\">\u003C\u002Fscript>\n```\n\n## Quick Start\n\n```javascript\n\u002F\u002F Create a single editor\nconst [editor] = new OverType('#editor', {\n  value: '# Hello World',\n  theme: 'solar'\n});\n\n\u002F\u002F Get\u002Fset content\neditor.getValue();\neditor.setValue('# New Content');\n\n\u002F\u002F Change theme for this instance\neditor.setTheme('cave');\n```\n\n## Usage\n\n### Basic Editor\n\n```html\n\u003Cdiv id=\"editor\" style=\"height: 400px;\">\u003C\u002Fdiv>\n\n\u003Cscript>\n  const [editor] = new OverType('#editor', {\n    placeholder: 'Start typing markdown...',\n    value: '# Welcome\\n\\nStart writing **markdown** here!',\n    onChange: (value, instance) => {\n      console.log('Content changed:', value);\n    }\n  });\n\u003C\u002Fscript>\n```\n\n### Toolbar\n\n```javascript\n\u002F\u002F Enable default toolbar with all formatting buttons\nconst [editor] = new OverType('#editor', {\n  toolbar: true,\n  value: '# Document\\n\\nSelect text and use the toolbar!'\n});\n\n\u002F\u002F Default toolbar: Bold, Italic, Code | Link | H1, H2, H3 | Lists, Tasks | Quote | View Mode\n```\n\n**Custom Toolbar (v2.0):**\n\n```javascript\nimport OverType, { toolbarButtons } from 'overtype';\n\nconst [editor] = new OverType('#editor', {\n  toolbar: true,\n  toolbarButtons: [\n    toolbarButtons.bold,\n    toolbarButtons.italic,\n    toolbarButtons.separator,\n    {\n      name: 'save',\n      icon: '\u003Csvg>...\u003C\u002Fsvg>',\n      title: 'Save',\n      action: ({ editor, getValue }) => {\n        localStorage.setItem('draft', getValue());\n      }\n    }\n  ]\n});\n\n\u002F\u002F Available: bold, italic, code, link, h1, h2, h3, bulletList,\n\u002F\u002F orderedList, taskList, quote, separator, viewMode\n```\n\n**Driving formatting from your own UI:**\n\nOverType re-exports the bundled `markdown-actions` library so you can build a fully custom toolbar (or any UI) without installing or bundling `markdown-actions` separately:\n\n```javascript\nimport OverType, { markdownActions } from 'overtype';\n\nconst [editor] = new OverType('#editor');\n\n\u002F\u002F Apply formatting to the editor's textarea directly\ndocument.querySelector('#bold-btn').addEventListener('click', () => {\n  markdownActions.toggleBold(editor.textarea);\n  editor.textarea.focus();\n});\n```\n\nAvailable actions include `toggleBold`, `toggleItalic`, `toggleCode`, `insertLink`, `toggleBulletList`, `toggleNumberedList`, `toggleQuote`, `toggleTaskList`, `insertHeader`, `toggleH1`\u002F`H2`\u002F`H3`, `getActiveFormats`, `hasFormat`, `expandSelection`, and `applyCustomFormat`. The same namespace is available as `window.markdownActions` and `OverType.markdownActions` in script-tag builds.\n\nSee [examples\u002Fcustom-toolbar.html](examples\u002Fcustom-toolbar.html) for complete examples.\n\n### View Modes\n\nThree modes available via toolbar dropdown or programmatically:\n\n```javascript\neditor.showNormalEditMode();   \u002F\u002F Default WYSIWYG editing\neditor.showPlainTextarea();    \u002F\u002F Raw markdown, no preview\neditor.showPreviewMode();      \u002F\u002F Read-only preview with clickable links\n```\n\n### Task Lists\n\nGitHub-style checkboxes render in preview mode:\n\n```javascript\nconst [editor] = new OverType('#editor', {\n  value: '- [ ] Todo\\n- [x] Done',\n  toolbar: true  \u002F\u002F Use view mode dropdown to see checkboxes\n});\n\n\u002F\u002F Edit mode: Shows `- [ ]` and `- [x]` syntax (preserves alignment)\n\u002F\u002F Preview mode: Renders actual checkbox inputs\n```\n\n### Syntax Highlighting\n\n```javascript\nimport { codeToHtml } from 'shiki';\n\n\u002F\u002F Global highlighter (all instances)\nOverType.setCodeHighlighter((code, lang) =>\n  codeToHtml(code, { lang, theme: 'nord' })\n);\n\n\u002F\u002F Per-instance override\nconst [editor] = new OverType('#editor', {\n  codeHighlighter: (code, lang) => myHighlighter(code, lang)\n});\n```\n\nSee [docs\u002FSYNTAX_HIGHLIGHTING.md](docs\u002FSYNTAX_HIGHLIGHTING.md) for complete guide.\n\n### Keyboard Shortcuts\n\nThe toolbar and keyboard shortcuts work together seamlessly:\n\n- **Cmd\u002FCtrl + B** - Bold\n- **Cmd\u002FCtrl + I** - Italic\n- **Cmd\u002FCtrl + K** - Insert link\n- **Cmd\u002FCtrl + Shift + 7** - Numbered list\n- **Cmd\u002FCtrl + Shift + 8** - Bullet list\n\nAll shortcuts preserve text selection, allowing you to apply multiple formats quickly.\n\n### Multiple Editors\n\n```javascript\n\u002F\u002F Initialize multiple editors at once\nconst editors = OverType.init('.markdown-editor', {\n  theme: 'cave',\n  fontSize: '16px'\n});\n\n\u002F\u002F Each editor is independent\neditors.forEach((editor, index) => {\n  editor.setValue(`# Editor ${index + 1}`);\n});\n```\n\n### Form Integration\n\n```javascript\n\u002F\u002F Use with form validation\nconst [editor] = new OverType('#message', {\n  placeholder: 'Your message...',\n  textareaProps: {\n    required: true,\n    maxLength: 500,\n    name: 'message'\n  }\n});\n\n\u002F\u002F The textarea will work with native form validation\ndocument.querySelector('form').addEventListener('submit', (e) => {\n  const content = editor.getValue();\n  \u002F\u002F Form will automatically validate required field\n});\n```\n\n### File Uploads\n\nOverType handles paste and drop of files when `fileUpload` is configured. You upload to your own backend in `onInsertFile` and return the markdown to insert. When that markdown link is later removed from the editor, `onRemoveFile` fires so you can clean up the backend file.\n\n```javascript\nconst [editor] = new OverType('#editor', {\n  fileUpload: {\n    enabled: true,\n    maxSize: 10 * 1024 * 1024,                  \u002F\u002F 10MB\n    mimeTypes: ['image\u002Fpng', 'image\u002Fjpeg'],     \u002F\u002F optional whitelist; empty = accept all\n    batch: false,                               \u002F\u002F true = one onInsertFile call per drop\n\n    \u002F\u002F Upload to your backend, return the markdown link to insert\n    onInsertFile: async (file) => {\n      const { url } = await uploadToBackend(file);\n      const isImage = file.type.startsWith('image\u002F');\n      return isImage ? `![${file.name}](${url})` : `[${file.name}](${url})`;\n    },\n\n    \u002F\u002F Optional: fires when an inserted link is removed from the editor.\n    \u002F\u002F Useful for deleting orphaned files from storage.\n    onRemoveFile: ({ url, filename, file }) => {\n      fetch(`\u002Fapi\u002Ffiles\u002F${encodeURIComponent(url)}`, { method: 'DELETE' });\n    }\n  }\n});\n```\n\n`onRemoveFile` only fires for URLs that OverType originally inserted via `onInsertFile`. URL edits, manual paste of an existing link, or programmatic edits to non-tracked URLs do not trigger it.\n\nSee [examples\u002Ffile-upload.html](website\u002Fexamples\u002Ffile-upload.html) for a complete working demo.\n\n### Custom Theme\n\n```javascript\nconst [editor] = new OverType('#editor', {\n  theme: {\n    name: 'my-theme',\n    colors: {\n      bgPrimary: '#faf0ca',\n      bgSecondary: '#ffffff',\n      text: '#0d3b66',\n      h1: '#f95738',\n      h2: '#ee964b',\n      h3: '#3d8a51',\n      strong: '#ee964b',\n      em: '#f95738',\n      link: '#0d3b66',\n      code: '#0d3b66',\n      codeBg: 'rgba(244, 211, 94, 0.2)',\n      blockquote: '#5a7a9b',\n      hr: '#5a7a9b',\n      syntaxMarker: 'rgba(13, 59, 102, 0.52)',\n      cursor: '#f95738',\n      selection: 'rgba(244, 211, 94, 0.4)'\n    }\n  }\n});\n```\n\n### Preview & HTML Export\n\nGenerate HTML previews or export the rendered content:\n\n```javascript\nconst [editor] = new OverType('#editor', {\n  value: '# Title\\n\\n**Bold** text with [links](https:\u002F\u002Fexample.com)'\n});\n\n\u002F\u002F Get the raw markdown\nconst markdown = editor.getValue();\n\u002F\u002F Returns: \"# Title\\n\\n**Bold** text with [links](https:\u002F\u002Fexample.com)\"\n\n\u002F\u002F Get rendered HTML with syntax markers (for debugging\u002Finspection)\nconst html = editor.getRenderedHTML();\n\u002F\u002F Returns HTML with \u003Cspan class=\"syntax-marker\"> elements visible\n\n\u002F\u002F Get clean HTML for export (no OverType-specific markup)\nconst cleanHTML = editor.getRenderedHTML({ cleanHTML: true });\n\u002F\u002F Returns clean HTML suitable for saving\u002Fexporting\n\n\u002F\u002F Convenience method for clean HTML\nconst exportHTML = editor.getCleanHTML();\n\u002F\u002F Same as getRenderedHTML({ cleanHTML: true })\n\n\u002F\u002F Get the current preview element's HTML (actual DOM content)\nconst previewHTML = editor.getPreviewHTML();\n\u002F\u002F Returns exactly what's shown in the editor's preview layer\n\n\u002F\u002F Example: Export clean HTML to server\nconst htmlToSave = editor.getCleanHTML();  \u002F\u002F No syntax markers\n\u002F\u002F Example: Clone exact preview appearance\ndocument.getElementById('clone').innerHTML = editor.getPreviewHTML();\n```\n\n### Stats Bar\n\nEnable a built-in stats bar that shows character, word, and line counts:\n\n```javascript\n\u002F\u002F Enable stats bar on initialization\nconst [editor] = new OverType('#editor', {\n  showStats: true\n});\n\n\u002F\u002F Show or hide stats bar dynamically\neditor.showStats(true);  \u002F\u002F Show\neditor.showStats(false); \u002F\u002F Hide\n\n\u002F\u002F Custom stats format\nconst [editor] = new OverType('#editor', {\n  showStats: true,\n  statsFormatter: (stats) => {\n    \u002F\u002F stats object contains: { chars, words, lines, line, column }\n    return `\u003Cspan>${stats.chars} characters\u003C\u002Fspan>\n            \u003Cspan>${stats.words} words\u003C\u002Fspan>\n            \u003Cspan>${stats.lines} lines\u003C\u002Fspan>\n            \u003Cspan>Line ${stats.line}, Col ${stats.column}\u003C\u002Fspan>`;\n  }\n});\n```\n\nThe stats bar automatically adapts to your theme colors using CSS variables.\n\n### React Component\n\n```jsx\nfunction MarkdownEditor({ value, onChange }) {\n  const ref = useRef();\n  const editorRef = useRef();\n  \n  useEffect(() => {\n    const [instance] = OverType.init(ref.current, {\n      value,\n      onChange\n    });\n    editorRef.current = instance;\n    \n    return () => editorRef.current?.destroy();\n  }, []);\n  \n  useEffect(() => {\n    if (editorRef.current && value !== editorRef.current.getValue()) {\n      editorRef.current.setValue(value);\n    }\n  }, [value]);\n  \n  return \u003Cdiv ref={ref} style={{ height: '400px' }} \u002F>;\n}\n```\n\n### Standalone Parser\n\nImport and use the markdown parser without the full editor for server-side rendering, static site generation, or browser extensions:\n\n```javascript\n\u002F\u002F Import just the parser\nimport { MarkdownParser } from 'overtype\u002Fparser';\n\n\u002F\u002F Parse markdown to HTML\nconst html = MarkdownParser.parse('# Hello World\\n\\nThis is **bold** text.');\n\n\u002F\u002F Use in Node.js for SSR\napp.get('\u002Fpreview', (req, res) => {\n  const markdown = req.body.content;\n  const html = MarkdownParser.parse(markdown);\n  res.json({ html });\n});\n\n\u002F\u002F Use in static site generator\nconst posts = markdownFiles.map(file => ({\n  content: MarkdownParser.parse(file.content),\n  metadata: file.metadata\n}));\n\n\u002F\u002F Use in browser extension\nchrome.runtime.onMessage.addListener((request, sender, sendResponse) => {\n  if (request.markdown) {\n    const html = MarkdownParser.parse(request.markdown);\n    sendResponse({ html });\n  }\n});\n```\n\n**Benefits:**\n- No DOM dependencies required\n- Smaller bundle when you only need parsing\n- Same markdown rendering as the editor\n- Perfect for headless\u002Fserver-side use cases\n\n## API\n\n### Constructor\n\n```javascript\nnew OverType(target, options)\n```\n\n**Parameters:**\n- `target` - Selector string, Element, NodeList, or Array of elements\n- `options` - Configuration object (see below)\n\n**Returns:** Array of OverType instances (always an array, even for single element)\n\n### Options\n\n```javascript\n{\n  \u002F\u002F Typography\n  fontSize: '14px',\n  lineHeight: 1.6,\n  fontFamily: 'monospace',\n  padding: '16px',\n  \n  \u002F\u002F Theme - 'solar', 'cave', or custom theme object\n  theme: 'solar',\n  \n  \u002F\u002F Custom colors (override theme colors)\n  colors: {\n    h1: '#e63946',\n    h2: '#457b9d',\n    \u002F\u002F ... any color variable\n  },\n  \n  \u002F\u002F Mobile styles (applied at \u003C= 640px)\n  mobile: {\n    fontSize: '16px',\n    padding: '12px',\n    lineHeight: 1.5\n  },\n  \n  \u002F\u002F Behavior\n  autofocus: false,\n  placeholder: 'Start typing...',\n  value: '',\n  \n  \u002F\u002F Auto-resize\n  autoResize: false,      \u002F\u002F Auto-expand height with content\n  minHeight: '100px',     \u002F\u002F Minimum height when autoResize is enabled\n  maxHeight: null,        \u002F\u002F Maximum height (null = unlimited)\n  \n  \u002F\u002F Native textarea properties\n  textareaProps: {\n    required: true,\n    maxLength: 500,\n    name: 'content',\n    \u002F\u002F Any HTML textarea attribute\n  },\n  \n  \u002F\u002F Toolbar\n  toolbar: false,         \u002F\u002F Enable\u002Fdisable toolbar\n  toolbarButtons: [],     \u002F\u002F Custom button array (v2.0)\n                          \u002F\u002F Defaults to all built-in buttons when toolbar: true\n\n  \u002F\u002F Syntax highlighting\n  codeHighlighter: null,  \u002F\u002F Function: (code, lang) => html\n                          \u002F\u002F Overrides global OverType.setCodeHighlighter()\n\n  \u002F\u002F Smart lists\n  smartLists: true,       \u002F\u002F Enable GitHub-style list continuation on Enter\n\n  \u002F\u002F Spellcheck\n  spellcheck: false,      \u002F\u002F Enable browser spellcheck (disabled by default)\n\n  \u002F\u002F Stats bar\n  showStats: false,       \u002F\u002F Enable\u002Fdisable stats bar\n  statsFormatter: (stats) => {  \u002F\u002F Custom stats format\n    return `${stats.chars} chars | ${stats.words} words`;\n  },\n  \n  \u002F\u002F Callbacks\n  onChange: (value, instance) => {},\n  onKeydown: (event, instance) => {},\n  onFocus: (event, instance) => {},\n  onBlur: (event, instance) => {},\n\n  \u002F\u002F File upload (paste\u002Fdrop) — see \"File Uploads\" section below\n  fileUpload: {\n    enabled: true,\n    maxSize: 10 * 1024 * 1024,                            \u002F\u002F bytes (default 10MB)\n    mimeTypes: [],                                        \u002F\u002F empty = accept all\n    batch: false,                                         \u002F\u002F single onInsertFile call per drop\n    onInsertFile: async (file) => `[${file.name}](url)`,  \u002F\u002F required: return inserted markdown\n    onRemoveFile: ({ url, filename, file }) => {}         \u002F\u002F fires when an inserted link is removed\n  }\n}\n```\n\n### Instance Methods\n\n```javascript\n\u002F\u002F Get current markdown content\neditor.getValue()\n\n\u002F\u002F Set markdown content\neditor.setValue(markdown)\n\n\u002F\u002F Get rendered HTML of the current content\neditor.getRenderedHTML()                    \u002F\u002F With syntax markers (for debugging)\neditor.getRenderedHTML({ cleanHTML: true }) \u002F\u002F Clean HTML without OverType markup\neditor.getCleanHTML()                       \u002F\u002F Alias for getRenderedHTML({ cleanHTML: true })\n\n\u002F\u002F Get the current preview element's HTML\neditor.getPreviewHTML()            \u002F\u002F Actual DOM content from preview layer\n\n\u002F\u002F Change theme (instance-specific, overrides global theme)\neditor.setTheme('cave')  \u002F\u002F Built-in theme name\neditor.setTheme(customThemeObject)  \u002F\u002F Custom theme\n\n\u002F\u002F Set code highlighter (instance-specific)\neditor.setCodeHighlighter((code, lang) => highlightedHTML)\neditor.setCodeHighlighter(null)  \u002F\u002F Disable for this instance\n\n\u002F\u002F View modes\neditor.showNormalEditMode()   \u002F\u002F Switch to normal edit mode (default)\neditor.showPlainTextarea()    \u002F\u002F Switch to plain textarea mode\neditor.showPreviewMode()      \u002F\u002F Switch to preview mode\n\n\u002F\u002F Focus\u002Fblur\neditor.focus()\neditor.blur()\n\n\u002F\u002F Show or hide stats bar\neditor.showStats(true)   \u002F\u002F Show stats\neditor.showStats(false)  \u002F\u002F Hide stats\n\n\u002F\u002F Check if initialized\neditor.isInitialized()\n\n\u002F\u002F Re-initialize with new options\neditor.reinit(options)\n\n\u002F\u002F Destroy the editor\neditor.destroy()\n```\n\n### Static Methods\n\n```javascript\n\u002F\u002F Set global theme (affects all instances without instance themes)\nOverType.setTheme('cave')  \u002F\u002F Built-in theme\nOverType.setTheme(customTheme)  \u002F\u002F Custom theme object\nOverType.setTheme('solar', { h1: '#custom' })  \u002F\u002F Override specific colors\n\n\u002F\u002F Set global code highlighter (affects all instances without instance highlighter)\nOverType.setCodeHighlighter((code, lang) => highlightedHTML)\nOverType.setCodeHighlighter(null)  \u002F\u002F Disable global highlighting\n\n\u002F\u002F Extend parsing with custom syntax (footnotes, directives, etc.)\n\u002F\u002F IMPORTANT: You must maintain 1-to-1 character alignment - wrap text, don't change it\n\u002F\u002F See: https:\u002F\u002Fpanphora.github.io\u002Fovertype\u002Fexamples\u002Fcustom-syntax.html\nOverType.setCustomSyntax((html) => {\n  return html.replace(\u002F\\[\\^(\\w+)\\]\u002Fg, '\u003Cspan class=\"footnote\">$&\u003C\u002Fspan>');\n})\n\n\u002F\u002F Note: Instance methods override global settings\n\n\u002F\u002F Initialize multiple editors (same as constructor)\nOverType.init(target, options)\n\n\u002F\u002F Initialize with per-element config via data-ot-* attributes\n\u002F\u002F Uses kebab-case: data-ot-show-stats=\"true\" → showStats: true\n\u002F\u002F Accepts a selector, Element, NodeList, or Array of elements\nOverType.initFromData('.editor', { \u002F* defaults *\u002F })\n\n\u002F\u002F Get instance from a selector, Element, NodeList, or Array\n\u002F\u002F Returns the instance for the first matching element\nOverType.getInstance(target)\n\n\u002F\u002F Destroy all instances\nOverType.destroyAll()\n\n\u002F\u002F Access themes\nOverType.themes.solar\nOverType.themes.cave\n```\n\n## Keyboard Shortcuts\n\n| Shortcut | Action |\n|----------|--------|\n| Cmd\u002FCtrl + B | Toggle bold |\n| Cmd\u002FCtrl + I | Toggle italic |\n| Cmd\u002FCtrl + K | Wrap in code |\n| Cmd\u002FCtrl + Shift + K | Insert link |\n| Cmd\u002FCtrl + Shift + 7 | Toggle numbered list |\n| Cmd\u002FCtrl + Shift + 8 | Toggle bullet list |\n\n## Supported Markdown\n\n- **Headers** - `# H1`, `## H2`, `### H3`\n- **Bold** - `**text**` or `__text__`\n- **Italic** - `*text*` or `_text_`\n- **Strikethrough** - `~~text~~` or `~text~` (GFM)\n- **Code** - `` `inline code` ``\n- **Code blocks** - ` ```language `\n- **Links** - `[text](url)`\n- **Lists** - `- item`, `* item`, `1. item`\n- **Task lists** - `- [ ] todo`, `- [x] done` (GFM, renders in preview mode)\n- **Blockquotes** - `> quote`\n- **Horizontal rule** - `---`, `***`, or `___`\n\n**Note:** Syntax remains visible in edit mode (e.g., `**bold**` shows markers). Use preview mode for full rendering.\n\n## Web Component\n\nOverType provides a fully-featured native Web Component `\u003Covertype-editor>` with Shadow DOM encapsulation and a declarative HTML API.\n\n**Quick example:**\n```html\n\u003Covertype-editor\n  value=\"# Hello OverType!\"\n  theme=\"solar\"\n  height=\"300px\"\n  toolbar>\n\u003C\u002Fovertype-editor>\n```\n\n📖 **[Complete Web Component Documentation](docs\u002FWEB-COMPONENT.md)**\n\nFeatures include:\n- Complete style isolation with Shadow DOM\n- 15 reactive HTML attributes\n- Framework-agnostic (React, Vue, Angular)\n- Built-in themes (Solar, Cave)\n- Custom events API\n- Zero configuration required\n\n## Migration from v1.x\n\n### Breaking Change: Toolbar API (v2.0)\n\n**Old options removed:**\n```javascript\n\u002F\u002F ❌ No longer supported\n{\n  customToolbarButtons: [...],\n  hideButtons: [...],\n  buttonOrder: [...]\n}\n```\n\n**New approach:**\n```javascript\n\u002F\u002F ✅ v2.0: Single explicit array\nimport { toolbarButtons } from 'overtype';\n\n{\n  toolbar: true,\n  toolbarButtons: [\n    toolbarButtons.bold,\n    toolbarButtons.italic,\n    { name: 'custom', icon: '...', action: ({ editor, getValue }) => {} }\n  ]\n}\n```\n\n**If using default toolbar** (`toolbar: true` with no customization), no changes needed.\n\nSee [examples\u002Fcustom-toolbar.html](examples\u002Fcustom-toolbar.html) for migration examples.\n\n## DOM Persistence & Re-initialization\n\nOverType is designed to work with platforms that persist DOM across page loads (like HyperClay):\n\n```javascript\n\u002F\u002F Safe to call multiple times - will recover existing editors\nOverType.init('.editor');\n\n\u002F\u002F The library will:\n\u002F\u002F 1. Check for existing OverType DOM structure\n\u002F\u002F 2. Recover content from existing textarea if found\n\u002F\u002F 3. Re-establish event bindings\n\u002F\u002F 4. Or create fresh editor if no existing DOM\n```\n\n## Examples\n\nCheck the `examples` folder for complete examples:\n\n- `basic.html` - Simple single editor\n- `multiple.html` - Multiple independent editors\n- `custom-theme.html` - Theme customization\n- `custom-toolbar.html` - Custom toolbar buttons (v2.0)\n- `dynamic.html` - Dynamic creation\u002Fdestruction\n\n## Limitations\n\nDue to the transparent textarea overlay approach, OverType has some intentional design limitations:\n\n### Images Not Supported\nImages (`![alt](url)`) are not rendered. Variable-height images would break the character alignment between textarea and preview.\n\n### Monospace Font Required\nAll text must use a monospace font to maintain alignment. Variable-width fonts would cause the textarea cursor position to drift from the visual text position.\n\n### Fixed Font Size\nAll content must use the same font size. Different sizes for headers or other elements would break vertical alignment.\n\n### Visible Markdown Syntax\nAll markdown formatting characters remain visible (e.g., `**bold**` shows the asterisks). This is intentional - hiding them would break the 1:1 character mapping.\n\n### Links Require Modifier Key\nLinks are clickable with Cmd\u002FCtrl+Click only. Direct clicking would interfere with text editing since clicks need to position the cursor in the textarea.\n\nThese limitations are what enable OverType's core benefits: perfect native textarea behavior, tiny size, and zero complexity.\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Development build with watch\nnpm run dev\n\n# Production build\nnpm run build\n\n# Run tests\nnpm test\n\n# Check bundle size\nnpm run size\n```\n\n## Browser Support\n\n- Chrome 62+\n- Firefox 78+\n- Safari 16+\n- Edge (Chromium)\n\nRequires support for:\n- CSS Custom Properties\n- ES6 features\n- Lookbehind assertions in RegExp (for italic parsing)\n\n## Architecture\n\nOverType uses a unique invisible textarea overlay approach:\n\n1. **Two perfectly aligned layers:**\n   - Invisible textarea (top) - handles input and cursor\n   - Styled preview div (bottom) - shows formatted markdown\n\n2. **Character-perfect alignment:**\n   - Monospace font required\n   - No size changes in styling\n   - Syntax markers remain visible\n\n3. **Single source of truth:**\n   - Textarea content drives everything\n   - One-way data flow: textarea → parser → preview\n\n## Data Attribute Configuration\n\nUse `OverType.initFromData()` to configure multiple editors via HTML data attributes:\n\n```html\n\u003Cdiv class=\"editor\" data-ot-toolbar=\"true\" data-ot-theme=\"cave\">\u003C\u002Fdiv>\n\u003Cdiv class=\"editor\" data-ot-auto-resize=\"true\" data-ot-min-height=\"200px\">\u003C\u002Fdiv>\n\u003Cdiv class=\"editor\" data-ot-show-stats=\"true\" data-ot-placeholder=\"Write here...\">\u003C\u002Fdiv>\n\n\u003Cscript>\n  OverType.initFromData('.editor', { fontSize: '14px' }); \u002F\u002F defaults\n\u003C\u002Fscript>\n```\n\nUses kebab-case attributes that convert to camelCase options (e.g., `data-ot-show-stats` → `showStats`).\n\n**Supported:** `toolbar`, `theme`, `value`, `placeholder`, `autofocus`, `auto-resize`, `min-height`, `max-height`, `font-size`, `line-height`, `show-stats`, `smart-lists`, `show-active-line-raw`\n\n**Not supported (use JS):** `toolbarButtons`, `textareaProps`, `onChange`, `onKeydown`, `onFocus`, `onBlur`, `statsFormatter`, `codeHighlighter`, `colors`, `mobile`\n\n## Contributors\n\nSpecial thanks to:\n\n### Core Features & Fixes\n- [Josh Doman](https:\u002F\u002Fgithub.com\u002Fjoshdoman) - Fixed inline code formatting preservation ([#6](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F6)), improved code fence detection ([#19](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F19))\n- [kbhomes](https:\u002F\u002Fgithub.com\u002Fkbhomes) - Fixed text selection desync during overscroll ([#17](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F17))\n- [Kristián Kostecký](https:\u002F\u002Fgithub.com\u002Fkristiankostecky) - Fixed toolbar option being ignored in reinit() ([#62](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F62))\n- [Lyric Wai](https:\u002F\u002Fgithub.com\u002Flyricat) - Fixed double-escaping of links ([#64](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F64)), shared code block alignment fix ([#65](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F65))\n- [kozi](https:\u002F\u002Fgithub.com\u002Fkozi) - Reported Firefox link tooltip bug ([#68](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F68)), toolbar positioning ([#69](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F69)), theme CSS variable issues ([#70](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F70), [#71](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F71))\n- [1951FDG](https:\u002F\u002Fgithub.com\u002F1951FDG) - Reported unordered list rendering bug ([#74](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F74)), suggested showStats() API improvement ([#77](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F77)), reported placeholder CSS regression ([#102](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F102))\n- [nodesocket](https:\u002F\u002Fgithub.com\u002Fnodesocket) - Reported toolbarButtons export issues ([#73](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F73), [#78](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F78)), suggested image toolbar button ([#89](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F89)), reported custom theme stats bar styling ([#101](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F101)), suggested onRemoveFile callback ([#104](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F104))\n- [Travis Bell](https:\u002F\u002Fgithub.com\u002Ftravisbell) - Reported keyboard shortcuts bug in ESM build ([#80](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F80))\n- [fab2713](https:\u002F\u002Fgithub.com\u002Ffab2713) - Reported italic rendering in lists ([#81](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F81)), reinit maxHeight ([#82](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F82)), placeholder visibility ([#83](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F83)), suggested auto theme ([#84](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F84)), relative URL prefix ([#85](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F85)), minification improvements ([#94](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F94))\n- [oooo-ps](https:\u002F\u002Fgithub.com\u002Foooo-ps) - Reported remote script loading issue ([#86](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F86))\n- [ddarfantasy](https:\u002F\u002Fgithub.com\u002Fddarfantasy), [ThaUnknown](https:\u002F\u002Fgithub.com\u002FThaUnknown) - Reported and debugged text misalignment caused by CSS framework font resets ([#91](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F91))\n- [milen-yordanov](https:\u002F\u002Fgithub.com\u002Fmilen-yordanov) - Reported code block colors ignoring theme in preview mode ([#97](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F97))\n- [asalimian](https:\u002F\u002Fgithub.com\u002Fasalimian) - Reported spellcheck being disabled ([#98](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F98))\n- [be5invis](https:\u002F\u002Fgithub.com\u002Fbe5invis) - Reported reinit() not propagating fontSize changes ([#108](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F108)), suggested focus\u002Fblur callbacks ([#107](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F107))\n- [Danny Vink](https:\u002F\u002Fgithub.com\u002Fdannyvink) - Fixed task list overlay alignment with spaced checkbox markers ([#109](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F109))\n- [yurivish](https:\u002F\u002Fgithub.com\u002Fyurivish) - Reported fontFamily option not being applied ([#110](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F110))\n- [phinnaeus](https:\u002F\u002Fgithub.com\u002Fphinnaeus) - Diagnosed missing fontFamily wiring ([#110](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F110))\n- [Tan Nhu](https:\u002F\u002Fgithub.com\u002Ftnhu) - Fixed onChange feedback loop with async syntax highlighters ([#111](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F111))\n- [pscanf](https:\u002F\u002Fgithub.com\u002Fpscanf) - Re-exported markdown-actions for custom toolbar implementations ([#105](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F105), [#106](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F106))\n\n### TypeScript & Framework Support\n- [merlinz01](https:\u002F\u002Fgithub.com\u002Fmerlinz01) - Contributed TypeScript declaration file ([#20](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F20))\n- [ChasLui](https:\u002F\u002Fgithub.com\u002FChasLui) - Web component implementation ([#40](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F40))\n- [pscanf](https:\u002F\u002Fgithub.com\u002Fpscanf) - Added performAction type definition ([#99](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F99))\n\n### New Features & Enhancements\n- [davidlazar](https:\u002F\u002Fgithub.com\u002Fdavidlazar) - Suggested view mode feature ([#24](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F24))\n- [Yukai Huang](https:\u002F\u002Fgithub.com\u002FYukaii) - Contributed syntax highlighting implementation ([#35](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F35))\n- [Rognoni](https:\u002F\u002Fgithub.com\u002Frognoni) - Suggested custom toolbar button API ([#61](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F61))\n- [Deyan Gigov](https:\u002F\u002Fgithub.com\u002Fdido739) - Reported checkbox rendering bug in preview mode ([#60](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F60)), contributed auto theme implementation ([#100](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F100))\n- [GregJohnStewart](https:\u002F\u002Fgithub.com\u002FGregJohnStewart) - Suggested data attribute configuration ([#76](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F76)), reported initFromData array nesting bug ([#93](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F93)), suggested DOM element init ([#92](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F92))\n- [boris-glumpler](https:\u002F\u002Fgithub.com\u002Fboris-glumpler) - Suggested custom syntax highlighting API ([#79](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F79))\n- [sorokya](https:\u002F\u002Fgithub.com\u002Fsorokya) - Contributed file upload support ([#87](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F87))\n- [aaronmyatt](https:\u002F\u002Fgithub.com\u002Faaronmyatt) - Contributed show\u002Fhide toolbar methods ([#95](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F95))\n- [rouilj](https:\u002F\u002Fgithub.com\u002Frouilj) - Suggested progressive textarea enhancement ([#90](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F90))\n- [inklesspen](https:\u002F\u002Fgithub.com\u002Finklesspen) - Suggested autocompletion popups ([#96](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F96))\n\n### Developer Experience\n- [Ned Twigg](https:\u002F\u002Fgithub.com\u002Fnedtwigg) - Built gitcasso browser extension using OverType ([#59](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F59))\n- [Victor](https:\u002F\u002Fgithub.com\u002FViggieM) - Suggested exportable MarkdownParser ([#58](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F58))\n- [Bernhard Weichel](https:\u002F\u002Fgithub.com\u002Fbwl21) - Reported preview\u002Fedit mode sync bug ([#52](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F52))\n- [Colin Devroe](https:\u002F\u002Fgithub.com\u002Fcdevroe) - Reported setTheme() API bug ([#54](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fissues\u002F54))\n- [Max Bernstein](https:\u002F\u002Fgithub.com\u002Ftekknolagi) - Fixed typo on website ([#11](https:\u002F\u002Fgithub.com\u002Fpanphora\u002Fovertype\u002Fpull\u002F11))\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n\u003Cp>&nbsp;\u003C\u002Fp>\n\n---\n\nBuilt with the radical idea that sometimes dumb ideas work.\n\n**Ready for another radical idea?**  \nLet's remove every layer of the web application stack.\n\n### Hyperclay\n\n[Hyperclay](https:\u002F\u002Fhyperclay.com) by @panphora allows you to make a web app in a single, portable, self-updating, vanilla HTML file. No frameworks, no build steps, no deployment pipelines. Just a single HTML file that persists its own state and can be edited live.\n\nThink of it as a Google Document for interactive code, where the UI, logic, and data all live in one self-modifying file. Share apps instantly, edit them directly, use them offline.\n","OverType 是一个轻量级的 Markdown 编辑器库，采用不可见文本区域覆盖技术实现所见即所得的编辑体验。其核心功能包括透明输入层、全局主题切换（浅色和深色）、键盘快捷键支持以及智能列表延续等特性。OverType 体积小巧（压缩后约111KB），无外部依赖，可选配工具栏，并且针对移动设备进行了优化，适用于需要快速集成、对性能有高要求的场景，如在线文档编辑、博客撰写等。此外，它还具备DOM持久化感知能力，能够与React、Vue等多种前端框架良好兼容。",2,"2026-06-11 03:43:08","high_star"]