{"_id":"@dojo-ng/rich-text-menu","name":"@dojo-ng/rich-text-menu","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@dojo-ng/rich-text-menu","version":"0.1.0","license":"BSD-3-Clause","description":"Caret-anchored menu machinery for @dojo-ng/rich-text plugins","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.json","clean":"rm -rf dist"},"dependencies":{"@dojo-ng/rich-text":"^0.1.0","@dojo-ng/popup":"^0.1.0","@dojo-ng/list":"^0.1.0","lexical":"^0.21.0","lit":"^3.3.0"},"_id":"@dojo-ng/rich-text-menu@0.1.0","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-Fb5ADs9hvO8CA0TWDwlHyVrUbKB0IwC9TPLt9L6bCa2ndkyTv3dC0YJaapu7+D5X90w17tuTcAVZOu68nEQcaQ==","shasum":"c34c7e560dbf1c1e12b2840765addd659ea42270","tarball":"https://registry.npmjs.org/@dojo-ng/rich-text-menu/-/rich-text-menu-0.1.0.tgz","fileCount":6,"unpackedSize":15796,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDJ6ty4LEoLTdh11DxB4UmX/bxTkh2h+GWkT0UcPNWfNAIgLzBT3xATZNdK6uvo9shlwOpzThcwJytcrC4YcxVleBc="}]},"_npmUser":{"name":"bitranch","email":"bill@bitranch.com"},"directories":{},"maintainers":[{"name":"saysomething","email":"joshs@holmescorp.com"},{"name":"bitranch","email":"bill@bitranch.com"},{"name":"jepe","email":"jeffreyp@holmescorp.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rich-text-menu_0.1.0_1788374436987_0.6588288649323375"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-02T18:40:36.835Z","0.1.0":"2026-09-02T18:40:37.125Z","modified":"2026-09-02T18:40:37.334Z"},"maintainers":[{"name":"saysomething","email":"joshs@holmescorp.com"},{"name":"bitranch","email":"bill@bitranch.com"},{"name":"jepe","email":"jeffreyp@holmescorp.com"}],"description":"Caret-anchored menu machinery for @dojo-ng/rich-text plugins","license":"BSD-3-Clause","readme":"# @dojo-ng/rich-text-menu\n\nCaret-anchored menu machinery for @dojo-ng/rich-text plugins\n\nPart of [Dojo NG](../../README.md), a framework-agnostic web component library. BSD-3-Clause.\n\n> Internal plumbing for `@dojo-ng/rich-text` caret-anchored menus (used by the mentions and slash-command plugins) — not a custom element and not a plugin you load directly. Exports `createEditorMenu(ctx, config)` plus the `EditorMenuConfig`/`MenuMatch` types and the pure `computeMatch(textBeforeCaret, matchFn)` helper. You give it a `config` with `match(textBeforeCaret) => { start, query } | null` (locate the trigger + query in the caret's text), `onQueryChange(query)` (fetch/filter, then call the returned menu's `setOptions(options, loading?)`), and `onPick(option)` (called AFTER the trigger text has been removed). The menu owns a `dj-popup` + `dj-list` positioned at the caret, arrow/Enter/Tab/Escape navigation, a polite live region, and light-dismiss (outside click, Escape, or blur). Positioning and the interactive feel are browser-verified; the matcher is unit-testable via `computeMatch`.\n\n## Install\n\n```bash\nnpm install @dojo-ng/rich-text-menu\n```\n\n## Usage\n\nInside a plugin's `setup(ctx)`, create a menu from a trigger config and drive it with `setOptions`. See `@dojo-ng/rich-text-mentions` for a complete plugin built on this.\n\n```html\nimport { createEditorMenu } from \"@dojo-ng/rich-text-menu\";\n\nexport const myPlugin = {\n  name: \"at-menu\",\n  setup(ctx) {\n    const menu = createEditorMenu(ctx, {\n      match: (text) => { const m = /(^|\\s)@(\\w*)$/.exec(text); return m ? { start: m.index + m[1].length, query: m[2] } : null; },\n      onQueryChange: async (q) => menu.setOptions((await fetchPeople(q)).map((p) => ({ value: p.id, label: p.name }))),\n      onPick: (opt) => ctx.editor.update(() => { /* insert something for opt */ }),\n    });\n    return () => menu.dispose();\n  },\n};\n```\n","readmeFilename":"README.md","_rev":"1-a39737656da5fcdd4db781177532b438"}