{"_id":"@can3p/headless-mde","_rev":"5-240df8bfd334630918b43c3010a3c8d7","name":"@can3p/headless-mde","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.1":{"name":"@can3p/headless-mde","version":"0.0.1","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"author":{"name":"Resetand / can3p"},"license":"MIT","_id":"@can3p/headless-mde@0.0.1","maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"homepage":"https://github.com/can3p/headless-mde","dist":{"shasum":"f7f99f054d052133ce3dba42e71ef0e5481b0cf1","tarball":"https://registry.npmjs.org/@can3p/headless-mde/-/headless-mde-0.0.1.tgz","fileCount":23,"integrity":"sha512-lhsSFnvcAccSWqxrl6mHc9Gg9j88QKQ6Vggs2Hm1mRt2fFawP4ZpMAynIcbzeSh2SOQgdGAKwwOax3T/jS8C7Q==","signatures":[{"sig":"MEQCIEpjQ2eyut2ADiU1o9WVgl2JmPY8dspT2Gl6Wi8jTzJGAiBo15EYktRetZpBPe9CUapwUz2xaEtxthTL9ASbPFDD5w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72658},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"7a05a5c0140882aaca9a5dbc225f2817a5b07e58","scripts":{"lint":"eslint --max-warnings=0 src --fix","test":"jest --colors","build":"tsc","prepare":"echo 'Ready'","prepublish":"npm run lint && npm run test -- --watchAll=false && npm run build","start-sandbox":"npm run build; npm --prefix sandbox i -f; npm link sandbox/node_modules/react; npm --prefix sandbox run start","test:coverage":"npm run test -- --coverage"},"_npmUser":{"name":"can3p","email":"dpetroff@gmail.com"},"_npmVersion":"10.8.1","description":"UI headless React markdown editor using only textarea","directories":{},"_nodeVersion":"20.15.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^19.0.0","eslint":"^9.18.0","ts-jest":"^29.2.5","react-dom":"^19.0.0","@eslint/js":"^9.18.0","typescript":"^5.7.3","@types/jest":"^29.5.14","@types/node":"^22.12.0","@types/react":"^19.0.8","@types/react-dom":"^19.0.3","typescript-eslint":"^8.21.0","eslint-plugin-react":"^7.37.4","@testing-library/react":"^16.2.0","eslint-config-prettier":"^10.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.1.0","@testing-library/user-event":"^14.6.1"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/headless-mde_0.0.1_1769557379169_0.9828347384391425","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@can3p/headless-mde","version":"0.0.2","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"author":{"name":"Resetand / can3p"},"license":"MIT","_id":"@can3p/headless-mde@0.0.2","maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"homepage":"https://github.com/can3p/headless-mde","bugs":{"url":"https://github.com/can3p/headless-mde/issues"},"dist":{"shasum":"e99b879920c5236379324522a4ba47a7cb83246e","tarball":"https://registry.npmjs.org/@can3p/headless-mde/-/headless-mde-0.0.2.tgz","fileCount":23,"integrity":"sha512-W+oBQOObekl9j3+Zq/9rEzyr6dzdQpWAzLzw4g6fiM6hQRCpfdhLzn1/02yDsqq2xGaKNZqpFkoc7VvT0XzMOw==","signatures":[{"sig":"MEUCIBOj1X/uqE6qhQGieQ0iPe8aiVLAeXBTunKKZ2K3RKj8AiEAwcpTfR4CysqG51YEidiCZyxmH39++jCOZUGfJsRSBAA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@can3p%2fheadless-mde@0.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72352},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"e8212fc3ce76af7a9600a13b6ed7eb38086db07e","scripts":{"lint":"eslint --max-warnings=0 src --fix","test":"jest --colors","build":"tsc","prepare":"echo 'Ready'","prepublish":"npm run lint && npm run test -- --watchAll=false && npm run build","start-sandbox":"npm run build; npm --prefix sandbox i -f; npm link sandbox/node_modules/react; npm --prefix sandbox run start","test:coverage":"npm run test -- --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:aceff325-ce97-4745-98f8-39e9c90960fc"}},"repository":{"url":"git+https://github.com/can3p/headless-mde.git","type":"git"},"_npmVersion":"11.6.2","description":"UI headless React markdown editor using only textarea","directories":{},"_nodeVersion":"24.13.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^19.0.0","eslint":"^9.18.0","ts-jest":"^29.2.5","react-dom":"^19.0.0","@eslint/js":"^9.18.0","typescript":"^5.7.3","@types/jest":"^29.5.14","@types/node":"^22.12.0","@types/react":"^19.0.8","@types/react-dom":"^19.0.3","typescript-eslint":"^8.21.0","eslint-plugin-react":"^7.37.4","@testing-library/react":"^16.2.0","eslint-config-prettier":"^10.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.1.0","@testing-library/user-event":"^14.6.1"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/headless-mde_0.0.2_1769558380317_0.8708328149514013","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@can3p/headless-mde","version":"0.0.3","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"author":{"name":"Resetand / can3p"},"license":"MIT","_id":"@can3p/headless-mde@0.0.3","maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"homepage":"https://github.com/can3p/headless-mde","bugs":{"url":"https://github.com/can3p/headless-mde/issues"},"dist":{"shasum":"dea1369d03a0c0f8162c075b32711ed97768af8c","tarball":"https://registry.npmjs.org/@can3p/headless-mde/-/headless-mde-0.0.3.tgz","fileCount":25,"integrity":"sha512-lHcAuBSLAIUAJIkfkjMZB8HuSDydD7WwWmhHUVUpR2twcdEeynwiJeCh4JNbfzY5Z7YsfIAHZJY7gzTIcUo30A==","signatures":[{"sig":"MEUCIQDrEjIUtDJRey3/Ipm7NSbx9pkPXykl/iZaZm5fl8jXhQIgGk9Jrh49u/+9Ir3XNpe1uMoGH+Nqn/Wn91ifN4eqoNQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@can3p%2fheadless-mde@0.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72797},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./headless":{"types":"./dist/headless.d.ts","import":"./dist/headless.js","default":"./dist/headless.js"}},"gitHead":"0e833aeb4c0ab0feab4c2ed34313e351c1fc14e4","scripts":{"lint":"eslint --max-warnings=0 src --fix","test":"jest --colors","build":"tsc","prepare":"echo 'Ready'","prepublish":"npm run lint && npm run test -- --watchAll=false && npm run build","start-sandbox":"npm run build; npm --prefix sandbox i -f; npm link sandbox/node_modules/react; npm --prefix sandbox run start","test:coverage":"npm run test -- --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:aceff325-ce97-4745-98f8-39e9c90960fc"}},"repository":{"url":"git+https://github.com/can3p/headless-mde.git","type":"git"},"_npmVersion":"11.6.2","description":"UI headless React markdown editor using only textarea","directories":{},"_nodeVersion":"24.13.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^19.0.0","eslint":"^9.18.0","ts-jest":"^29.2.5","react-dom":"^19.0.0","@eslint/js":"^9.18.0","typescript":"^5.7.3","@types/jest":"^29.5.14","@types/node":"^22.12.0","@types/react":"^19.0.8","@types/react-dom":"^19.0.3","typescript-eslint":"^8.21.0","eslint-plugin-react":"^7.37.4","@testing-library/react":"^16.2.0","eslint-config-prettier":"^10.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.1.0","@testing-library/user-event":"^14.6.1"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/headless-mde_0.0.3_1769559148371_0.25794895818281915","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@can3p/headless-mde","version":"0.0.4","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"author":{"name":"Resetand / can3p"},"license":"MIT","_id":"@can3p/headless-mde@0.0.4","maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"homepage":"https://github.com/can3p/headless-mde","bugs":{"url":"https://github.com/can3p/headless-mde/issues"},"dist":{"shasum":"b45c0c00db5fafe660426673e7301cc9a70dab83","tarball":"https://registry.npmjs.org/@can3p/headless-mde/-/headless-mde-0.0.4.tgz","fileCount":25,"integrity":"sha512-m3L7mbuYQrBDIR0CLxqvRL6sQ+CZKaVFIihkvRZ8/XAEZOExgPqgunPQjTNibGOE3g+qskhIEpCJGkU5vi1qUw==","signatures":[{"sig":"MEQCIESdOTkSt8edoJPGqktOYj5RWgD3QmtKjQ5kyGksh4XLAiB08eTKK0DY2p/3b2nC5PHfZLDP9hXcSjX99Zj/wLsquA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@can3p%2fheadless-mde@0.0.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":72971},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./headless":{"types":"./dist/headless.d.ts","import":"./dist/headless.js","default":"./dist/headless.js"}},"gitHead":"1d7da1178abb51d84147a80fdc8a87b35ff971b9","scripts":{"lint":"eslint --max-warnings=0 . --fix","test":"jest --colors","build":"tsc","prepare":"echo 'Ready'","prepublish":"npm run lint && npm run test -- --watchAll=false && npm run build","start-sandbox":"npm run build; npm --prefix sandbox i -f; npm link sandbox/node_modules/react; npm --prefix sandbox run start","test:coverage":"npm run test -- --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:aceff325-ce97-4745-98f8-39e9c90960fc"}},"repository":{"url":"git+https://github.com/can3p/headless-mde.git","type":"git"},"_npmVersion":"11.6.2","description":"UI headless React markdown editor using only textarea","directories":{},"_nodeVersion":"24.13.0","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","react":"^19.0.0","eslint":"^9.18.0","ts-jest":"^29.2.5","react-dom":"^19.0.0","@eslint/js":"^9.18.0","typescript":"^5.7.3","@types/jest":"^29.5.14","@types/node":"^22.12.0","@types/react":"^19.0.8","@types/react-dom":"^19.0.3","typescript-eslint":"^8.21.0","eslint-plugin-react":"^7.37.4","@testing-library/react":"^16.2.0","eslint-config-prettier":"^10.0.1","jest-environment-jsdom":"^29.7.0","@testing-library/jest-dom":"^6.6.3","eslint-plugin-react-hooks":"^5.1.0","@testing-library/user-event":"^14.6.1"},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/headless-mde_0.0.4_1769817231198_0.3445207492255564","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@can3p/headless-mde","type":"module","version":"0.0.5","description":"UI headless React markdown editor using only textarea","homepage":"https://github.com/can3p/headless-mde","repository":{"type":"git","url":"git+https://github.com/can3p/headless-mde.git"},"author":{"name":"Resetand / can3p"},"license":"MIT","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./headless":{"types":"./dist/headless.d.ts","import":"./dist/headless.js","default":"./dist/headless.js"}},"peerDependencies":{"react":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","react-dom":"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"dependencies":{},"devDependencies":{"@eslint/js":"^9.18.0","@testing-library/jest-dom":"^6.6.3","@testing-library/react":"^16.2.0","@testing-library/user-event":"^14.6.1","@types/jest":"^29.5.14","@types/node":"^22.12.0","@types/react":"^19.0.8","@types/react-dom":"^19.0.3","eslint":"^9.18.0","eslint-config-prettier":"^10.0.1","eslint-plugin-react":"^7.37.4","eslint-plugin-react-hooks":"^5.1.0","jest":"^29.7.0","jest-environment-jsdom":"^29.7.0","react":"^19.0.0","react-dom":"^19.0.0","ts-jest":"^29.2.5","typescript":"^5.7.3","typescript-eslint":"^8.21.0"},"scripts":{"lint":"eslint --max-warnings=0 . --fix","build":"tsc","test":"jest --colors","test:coverage":"npm run test -- --coverage","prepublish":"npm run lint && npm run test -- --watchAll=false && npm run build","start-sandbox":"npm run build; npm --prefix sandbox i -f; npm link sandbox/node_modules/react; npm --prefix sandbox run start","prepare":"echo 'Ready'"},"gitHead":"170eafa2a4a4c523fb2dfafb804b60aa29a63d68","_id":"@can3p/headless-mde@0.0.5","bugs":{"url":"https://github.com/can3p/headless-mde/issues"},"_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-nqWzAWMTjvfT78aruI4ltU2e8FnsMiiP/o0Mz3y7H/+WhCrawwBpyqYwjYHZlFNbhd1WySKVlq9NgWfYuyv2vQ==","shasum":"4aecdde24c26e396fa9b58492ec12965883d8b74","tarball":"https://registry.npmjs.org/@can3p/headless-mde/-/headless-mde-0.0.5.tgz","fileCount":25,"unpackedSize":76208,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@can3p%2fheadless-mde@0.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDm8XW4Yg5ot+uydtw8ihzPAjoKy5c+hcpH1IEI7VJWtAiEA/6cHh5UXbSnob5Togf3TsCcZu05oapR4jV1WIcUGudI="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:aceff325-ce97-4745-98f8-39e9c90960fc"}},"directories":{},"maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/headless-mde_0.0.5_1787782318479_0.15030821205035183"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-27T23:42:59.065Z","modified":"2026-08-26T22:11:59.016Z","0.0.1":"2026-01-27T23:42:59.337Z","0.0.2":"2026-01-27T23:59:40.457Z","0.0.3":"2026-01-28T00:12:28.506Z","0.0.4":"2026-01-30T23:53:51.372Z","0.0.5":"2026-08-26T22:11:58.661Z"},"bugs":{"url":"https://github.com/can3p/headless-mde/issues"},"author":{"name":"Resetand / can3p"},"license":"MIT","homepage":"https://github.com/can3p/headless-mde","keywords":["react","textarea","markdown","editor","formatting","shortcuts"],"repository":{"type":"git","url":"git+https://github.com/can3p/headless-mde.git"},"description":"UI headless React markdown editor using only textarea","maintainers":[{"name":"can3p","email":"dpetroff@gmail.com"}],"readme":"# Textarea Markdown\n\nThis is a fork of https://github.com/Resetand/textarea-markdown-editor\n\nThe aim is to trim fix some of the quirks with the scroll position, there will be breaking changes, no compatibility planned.\n\n## Differences from original\n\n### Features\n\n-  Use `*` by default, both types are supported on enter\n-  Textarea reacts reliably to text insertion, no need to invoke any magic to keep the scroll position\n\n### Code\n\n- No more CommmonJS, only ESM\n- Dependencies were updated, added tests for missing cases\n\n### Webpack end ESM\n\nIn case Webpack is not happy with the imports from the package, you may need\nto define the exception in the webpack config:\n\n```\n  let config = {\n    // ....\n\n    // custom loaders configuration\n    module: {\n      rules: [\n        {\n          test: /\\.m?js$/,\n          include: /node_modules\\/@can3p\\/headless-mde/,\n          resolve: {\n            fullySpecified: false,\n          },\n        },\n        // ..\n      ]\n    },\n  };\n```\n\n---\n\n**Textarea Markdown** is a simple markdown editor using only `<textarea/>`. It extends textarea by adding formatting features like shortcuts, list-wrapping, invoked commands and other to make user experience better 🙃\n\nEssentially this library just provides the textarea Component. You can choose any markdown parser, create your own layout, and use your own textarea component that is styled and behaves however you like\n\n<p style='max-width:800px;margin-top:8%' align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/Resetand/textarea-markdown-editor/master/img/overview.gif\" />\n</p>\n\n## Features\n\n-   Lists wrapping\n-   Auto formatting pasted links\n-   Converts `-- ` to `— ` outside fenced code blocks\n-   Indent tabulation\n-   Keyboard shortcuts handling\n-   17 built-in customizable commands\n\n## Usage\n\n```tsx\nimport React, { Fragment, useRef, useState } from 'react';\nimport TextareaMarkdown, { TextareaMarkdownRef } from '@can3p/headless-mde';\n\nfunction App() {\n    const [value, setValue] = useState('');\n    const ref = useRef<TextareaMarkdownRef>(null);\n\n    return (\n        <Fragment>\n            <button onClick={() => ref.current?.trigger('bold')}>Bold</button>\n            <br />\n            <TextareaMarkdown ref={ref} value={value} onChange={(e) => setValue(e.target.value)} />\n        </Fragment>\n    );\n}\n```\n\nℹ️ Ref instance provide the `trigger` function to invoke commands\n\n### Custom textarea `Component`\n\nYou can use custom textarea Component. Just wrap it with `TextareaMarkdown.Wrapper`\n\n```tsx\nimport React, { useRef, useState } from 'react';\nimport TextareaMarkdown, { TextareaMarkdownRef } from '@can3p/headless-mde';\nimport TextareaAutosize from 'react-textarea-autosize';\n\nfunction App() {\n    const [value, setValue] = useState('');\n    const ref = useRef<TextareaMarkdownRef>(null);\n\n    return (\n        <TextareaMarkdown.Wrapper ref={ref}>\n            <TextareaAutosize value={value} onChange={(e) => setValue(e.target.value)} />\n        </TextareaMarkdown.Wrapper>\n    );\n}\n```\n\nℹ️ This solution will not create any real dom wrapper\n\n### Customize commands\n\nYou can specify or overwrite shortcuts for built-in commands or create your own\n\n```tsx\nimport React, { useRef, useState } from 'react';\nimport TextareaMarkdown, { CommandHandler, TextareaMarkdownRef } from '@can3p/headless-mde';\n\n/** Inserts 🙃 at the current position and select it */\nconst emojiCommandHandler: CommandHandler = ({ cursor }) => {\n    // MARKER - means a cursor position, or a selection range if specified two markers\n    cursor.insert(`${cursor.MARKER}🙃${cursor.MARKER}`);\n};\n\nfunction App() {\n    const [value, setValue] = useState('');\n    const ref = useRef<TextareaMarkdownRef>(null);\n\n    return (\n        <Fragment>\n            <button onClick={() => ref.current?.trigger('insert-emoji')}>Insert 🙃</button>\n            <br />\n            <TextareaMarkdown\n                ref={ref}\n                value={value}\n                onChange={(e) => setValue(e.target.value)}\n                commands={[\n                    {\n                        name: 'code',\n                        shortcut: ['command+/', 'ctrl+/'],\n                        shortcutPreventDefault: true,\n                    },\n                    {\n                        name: 'insert-emoji',\n                        handler: emojiCommandHandler,\n                    },\n                ]}\n            />\n        </Fragment>\n    );\n}\n```\n\nℹ️ Note that mutation `element.value` will not trigger `change` event on textarea element. Use `cursor.setValue(...)` or other method of `Cursor`.\n\nℹ️ [Mousetrap.js](https://craig.is/killing/mice) is used under the hood for shortcuts handling.\nIt is great solution with simple and intuitive api. You can read more about combination in the documentation\n\n### Usage without React\n\nFor projects that don't use React, import from the headless entry point:\n\n```js\nimport { bootstrapTextareaMarkdown } from '@can3p/headless-mde/headless';\n\nconst textarea = document.querySelector('textarea'); // element can be obtained from anywhere, this is just an example;\n\nconst { trigger, dispose } = bootstrapTextareaMarkdown(textarea, {\n    options: {}, // optional options config\n    commands: [], // optional commands configs\n});\n```\n\nℹ️ The headless entry point has no React dependencies, so you won't get peer dependency warnings.\n\n---\n\n### 👀 You can find more examples [here](https://github.com/Resetand/textarea-markdown-editor/tree/master/sandbox/src/examples)\n\n---\n\n## API\n\n-   [TextareaMarkdownProps](#textareamarkdownprops)\n-   [Command](#command)\n-   [CommandHandler](#commandhandler)\n-   [Built-in commands](#built-in-commands)\n-   [TextareaMarkdownOptions](#textareamarkdownoptions)\n-   [TextareaMarkdownRef](#textareamarkdownref)\n\n### `TextareaMarkdownProps`\n\nℹ️ `TextareaMarkdown` accepts all props which native textarea supports\n\n#### `options` [`TextareaMarkdownOptions`](#textareamarkdownoptions)\n\nOptions config\n\n#### `commands` [`Command`](#command)[]\n\nArray of commands configuration\n\n<!-- | Property     | Description                     | Type                                                  |\n| ------------ | ------------------------------- | ----------------------------------------------------- |\n| **options**  | Options config                  | [`TextareaMarkdownOptions`](#textareamarkdownoptions) |\n| **commands** | Array of commands configuration | [`Command`](#command)[]                               | -->\n\n---\n\n#### `Command`\n\n| Name                        | Type                                | Description                                                           |\n| :-------------------------- | :---------------------------------- | :-------------------------------------------------------------------- |\n| **name**                    | `TType`                             | Built-in or custom command name                                       |\n| **shortcut?**               | `string` \\| `string`[]              | Shortcut combinations ([Mousetrap.js](https://craig.is/killing/mice)) |\n| **shortcutPreventDefault?** | `boolean`                           | Toggle key event prevent `default:false`                              |\n| **handler?**                | [`CommandHandler`](#commandhandler) | Handler function for custom commands                                  |\n| **enable?**                 | `boolean`                           | Toggle command enabling                                               |\n\n---\n\n#### `CommandHandler`\n\n```ts\nexport type CommandHandler = (context: CommandHandlerContext) => void | Promise<void>;\n\nexport type CommandHandlerContext = {\n    textarea: HTMLTextAreaElement;\n    cursor: Cursor;\n    keyEvent?: KeyboardEvent;\n    clipboardEvent?: ClipboardEvent;\n    options: TextareaMarkdownOptions;\n};\n```\n\n---\n\n#### `Built-in commands`\n\n| Name               | Description                                                        | Shortcut               |\n| ------------------ | ------------------------------------------------------------------ | ---------------------- |\n| **bold**           | Inserts or wraps bold markup                                       | `ctrl/command+b`       |\n| **italic**         | Inserts or wraps italic markup                                     | `ctrl/command+i`       |\n| **strike-through** | Inserts or wraps strike-through markup                             | `ctrl/command+shift+x` |\n| **link**           | Inserts or wraps link markup                                       |                        |\n| **image**          | Inserts or wraps image markup                                      |                        |\n| **unordered-list** | Inserts or wraps unordered list markup                             |                        |\n| **ordered-list**   | Inserts or wraps ordered list markup                               |                        |\n| **code-block**     | Inserts or wraps code block markup                                 |                        |\n| **code-inline**    | Inserts or wraps inline code markup                                |                        |\n| **code**           | Inserts or wraps inline or block code markup dependent of selected |                        |\n| **block-quotes**   | Inserts or wraps block-quotes markup                               |                        |\n| **h1**             | Inserts h1 headline                                                |                        |\n| **h2**             | Inserts h2 headline                                                |                        |\n| **h3**             | Inserts h3 headline                                                |                        |\n| **h4**             | Inserts h4 headline                                                |                        |\n| **h5**             | Inserts h5 headline                                                |                        |\n| **h6**             | Inserts h6 headline                                                |                        |\n\n---\n\n### TextareaMarkdownOptions\n\n| Name                                        | Type                                        | Description                                                                                                                              |\n| :------------------------------------------ | :------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------- |\n| **preferredBoldSyntax**                     | `\"**\"` \\| `\"__\"`                            | Preferred bold wrap syntax `default: '**'`                                                                                               |\n| **preferredItalicSyntax**                   | `\"*\"` \\| `\"_\"`                              | Preferred italic wrap syntax `default: '*'`                                                                                              |\n| **preferredUnorderedListSyntax**            | `\"-\"` \\| `\"*\"` \\| `\"+\"`                     | Preferred unordered list prefix `default: '*'`                                                                                           |\n| **enableEmDashExtension**                   | `boolean`                                   | Converts two dashes followed by a space into an em dash outside fenced code blocks `default:true`                                        |\n| **enableIndentExtension**                   | `boolean`                                   | Will handle `tab` and `shift+tab` keystrokes, on which will insert/remove indentation instead of the default behavior `default:true`     |\n| **enableLinkPasteExtension**                | `boolean`                                   | Will handle `paste` event, on which will wrap pasted with link/image markup if pasted is URL `default:true`                              |\n| **enableOrderedListAutoCorrectExtension**   | `boolean`                                   | Will autocorrect invalid ordered list patterns when `enter` is pressed `default:false`                                                   |\n| **enablePrefixWrappingExtension**           | `boolean`                                   | Will handle `enter` keystroke, on which will wrap current list sequence if needed `default:true`                                         |\n| **enableProperLineRemoveBehaviorExtension** | `boolean`                                   | Will handle `command/ctrl+backspace` keystrokes, on which will remove only a current line instead of the default behavior `default:true` |\n| **customPrefixWrapping**                    | (`PrefixWrappingConfig` \\| `string`)[]      | Array of custom prefixes, that need to be wrapped. (Will not work with `enablePrefixWrappingExtension:false`)                            |\n| **blockQuotesPlaceholder**                  | `string`                                    | `default: 'quote'`                                                                                                                       |\n| **boldPlaceholder**                         | `string`                                    | `default: 'bold'`                                                                                                                        |\n| **codeBlockPlaceholder**                    | `string`                                    | `default: 'code block'`                                                                                                                  |\n| **codeInlinePlaceholder**                   | `string`                                    | `default: 'code'`                                                                                                                        |\n| **headlinePlaceholder**                     | `string` \\| (`level`: `number`) => `string` | `default: (lvl) => 'headline ' + lvl`                                                                                                    |\n| **imageTextPlaceholder**                    | `string`                                    | Used inside default image markup `![<example>](...)` `default: 'example'`                                                                |\n| **imageUrlPlaceholder**                     | `string`                                    | Used inside default image markup `![...](<image.png>)` `default: 'image.png'`                                                            |\n| **italicPlaceholder**                       | `string`                                    | `default: 'italic'`                                                                                                                      |\n| **linkTextPlaceholder**                     | `string`                                    | Used inside default link markup `[<example>](...)` `default: 'example'`                                                                  |\n| **linkUrlPlaceholder**                      | `string`                                    | Used inside default image markup `![...](<url>)` `default: 'url'`                                                                        |\n| **orderedListPlaceholder**                  | `string`                                    | `default: 'ordered list'`                                                                                                                |\n| **strikeThroughPlaceholder**                | `string`                                    | `default: 'strike through'`                                                                                                              |\n| **unorderedListPlaceholder**                | `string`                                    | `default: 'unordered list'`                                                                                                              |\n\n---\n\n#### `TextareaMarkdownRef`\n\nℹ️ Extends `HTMLTextAreaElement` instance\n\n```typescript\ntrigger: (command: string) => void;\ncursor: Cursor\n```\n\n## Development\n\n### Publishing Releases\n\nThis package is automatically published to npm when a GitHub release is created.\n\nSetup was done by following trusted publisher guide: https://docs.npmjs.com/trusted-publishers\n\n#### Creating a release\n\nJust create a GitHub release with a version tag (e.g., `v1.0.0`). The workflow will:\n\n1. Extract the version from the tag\n2. Update `package.json` automatically\n3. Run lint, tests, and build\n4. Commit the version bump and move the tag to point to it\n5. Publish to npm\n\nNo manual version bumping required! The release tag will always point to the commit with the correct version in `package.json`.\n\n## Acknowledgements\n\nAll praise goes to https://github.com/Resetand !\n","readmeFilename":"README.md"}