{"_id":"@amusendame/beakblock-react","_rev":"3-05ebc42431bf1d4378dd536d4f442616","name":"@amusendame/beakblock-react","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@amusendame/beakblock-react","version":"0.1.0","keywords":["editor","rich-text","prosemirror","block-editor","wysiwyg","notion-like","react","react-hooks","typescript","text-editor"],"license":"Apache-2.0","_id":"@amusendame/beakblock-react@0.1.0","maintainers":[{"name":"amusendame","email":"aurthurmusendame@gmail.com"}],"homepage":"https://github.com/aurthurm/beakblock#readme","bugs":{"url":"https://github.com/aurthurm/beakblock/issues"},"dist":{"shasum":"d84d6c9812949f5929086cdd051086047f566615","tarball":"https://registry.npmjs.org/@amusendame/beakblock-react/-/beakblock-react-0.1.0.tgz","fileCount":39,"integrity":"sha512-dye0pk44mCPn9q0PP37G774S+SkCH4f3ANCKWIT6Nl7w9YFNJVh+ZMCXrRlrL9+/QmYwNeIWFzTOfnmI9nGlvA==","signatures":[{"sig":"MEYCIQCxQznw3wcEOumCuP/dTU0ROIoEAWwBfGw7Q35HpO2mtgIhAPFFHeHID2FxPN0Q3/dWEa+dKeOVyk34NHv3gC9g6lIA","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":416425},"main":"./dist/index.js","type":"module","_from":"file:amusendame-beakblock-react-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint src","build":"vite build","clean":"rm -rf dist"},"_npmUser":{"name":"amusendame","email":"aurthurmusendame@gmail.com"},"_resolved":"/tmp/c867523511d920ad1ccfc3b5d3aae6d1/amusendame-beakblock-react-0.1.0.tgz","_integrity":"sha512-dye0pk44mCPn9q0PP37G774S+SkCH4f3ANCKWIT6Nl7w9YFNJVh+ZMCXrRlrL9+/QmYwNeIWFzTOfnmI9nGlvA==","repository":{"url":"git+https://github.com/aurthurm/beakblock.git","type":"git","directory":"packages/react"},"_npmVersion":"11.7.0","description":"React bindings for BeakBlock editor","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","dependencies":{"@amusendame/beakblock-core":"0.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.7","typescript":"^5.7.2","@types/react":"^18.3.18","vite-plugin-dts":"^4.4.0","@types/react-dom":"^18.3.5"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/beakblock-react_0.1.0_1776513851553_0.039219750838849654","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@amusendame/beakblock-react","version":"0.1.1","keywords":["editor","rich-text","prosemirror","block-editor","wysiwyg","notion-like","react","react-hooks","typescript","text-editor"],"license":"Apache-2.0","_id":"@amusendame/beakblock-react@0.1.1","maintainers":[{"name":"amusendame","email":"aurthurmusendame@gmail.com"}],"homepage":"https://github.com/aurthurm/beakblock#readme","bugs":{"url":"https://github.com/aurthurm/beakblock/issues"},"dist":{"shasum":"83e671af26adb105b318eee4c8c4ba7836f1b194","tarball":"https://registry.npmjs.org/@amusendame/beakblock-react/-/beakblock-react-0.1.1.tgz","fileCount":39,"integrity":"sha512-Ha+bJ1QHj9at7o5KG94Lzk4uTRULfLyukEnwnI5LzVvLVascwK2oMVOCAaKiEpnPHeLs7sHjV/hCfxzM0F88YQ==","signatures":[{"sig":"MEUCIE1QITqsvxnxIV/E6VoBQdlt/nXCQIhWRaN3yxhvYaRYAiEAn6VipBn6E+vwEStg/BD8EBeI1VkWc8vMQGvkp/hbfbA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":416425},"main":"./dist/index.js","type":"module","_from":"file:amusendame-beakblock-react-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"vite build --watch","lint":"eslint src","build":"vite build","clean":"rm -rf dist"},"_npmUser":{"name":"amusendame","email":"aurthurmusendame@gmail.com"},"_resolved":"/tmp/fce37ee9a058f4ca70dc9a4018c6ed8b/amusendame-beakblock-react-0.1.1.tgz","_integrity":"sha512-Ha+bJ1QHj9at7o5KG94Lzk4uTRULfLyukEnwnI5LzVvLVascwK2oMVOCAaKiEpnPHeLs7sHjV/hCfxzM0F88YQ==","repository":{"url":"git+https://github.com/aurthurm/beakblock.git","type":"git","directory":"packages/react"},"_npmVersion":"11.7.0","description":"React bindings for BeakBlock editor","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","dependencies":{"@amusendame/beakblock-core":"0.1.1"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.7","typescript":"^5.7.2","@types/react":"^18.3.18","vite-plugin-dts":"^4.4.0","@types/react-dom":"^18.3.5"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/beakblock-react_0.1.1_1776521340402_0.7772614014928156","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@amusendame/beakblock-react","version":"0.1.2","description":"React bindings for BeakBlock editor","license":"Apache-2.0","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"keywords":["editor","rich-text","prosemirror","block-editor","wysiwyg","notion-like","react","react-hooks","typescript","text-editor"],"dependencies":{"@amusendame/beakblock-core":"0.1.2"},"devDependencies":{"@types/react":"^18.3.18","@types/react-dom":"^18.3.5","typescript":"^5.7.2","vite":"^6.0.7","vite-plugin-dts":"^4.4.0"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"sideEffects":false,"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"repository":{"type":"git","url":"git+https://github.com/aurthurm/beakblock.git","directory":"packages/react"},"homepage":"https://github.com/aurthurm/beakblock#readme","bugs":{"url":"https://github.com/aurthurm/beakblock/issues"},"scripts":{"build":"vite build","dev":"vite build --watch","lint":"eslint src","clean":"rm -rf dist"},"_id":"@amusendame/beakblock-react@0.1.2","_integrity":"sha512-pO5+F5wc4gj55I0EDXxyqiPHE/scg2bTa0CwRf/hgrnCRJZ3AxUMano08TSAGmEVQGxdA5vEWSNjOCkBJsEFKg==","_resolved":"/tmp/68535bc064c04b22d6b63703f2dc04a6/amusendame-beakblock-react-0.1.2.tgz","_from":"file:amusendame-beakblock-react-0.1.2.tgz","_nodeVersion":"22.22.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-pO5+F5wc4gj55I0EDXxyqiPHE/scg2bTa0CwRf/hgrnCRJZ3AxUMano08TSAGmEVQGxdA5vEWSNjOCkBJsEFKg==","shasum":"8c583cdb5ffd471bf67cc71ead28d007dca5085f","tarball":"https://registry.npmjs.org/@amusendame/beakblock-react/-/beakblock-react-0.1.2.tgz","fileCount":39,"unpackedSize":416425,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDarJGW24y2c1/sPu4jYssNT3yD9M+8HJ0DLGV8/Cu/oQIhANzMCk0qihDLi+/Ymm+4O3jvkUeMHlVQfMvpHFrQcnm3"}]},"_npmUser":{"name":"amusendame","email":"aurthurmusendame@gmail.com"},"directories":{},"maintainers":[{"name":"amusendame","email":"aurthurmusendame@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/beakblock-react_0.1.2_1776580970739_0.6019875131750523"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-18T12:04:11.486Z","modified":"2026-04-19T06:42:51.015Z","0.1.0":"2026-04-18T12:04:11.713Z","0.1.1":"2026-04-18T14:09:00.558Z","0.1.2":"2026-04-19T06:42:50.890Z"},"bugs":{"url":"https://github.com/aurthurm/beakblock/issues"},"license":"Apache-2.0","homepage":"https://github.com/aurthurm/beakblock#readme","keywords":["editor","rich-text","prosemirror","block-editor","wysiwyg","notion-like","react","react-hooks","typescript","text-editor"],"repository":{"type":"git","url":"git+https://github.com/aurthurm/beakblock.git","directory":"packages/react"},"description":"React bindings for BeakBlock editor","maintainers":[{"name":"amusendame","email":"aurthurmusendame@gmail.com"}],"readme":"# @amusendame/beakblock-react\n\nReact bindings for the BeakBlock rich text editor.\n\n## Installation\n\n```bash\nnpm install @amusendame/beakblock-react @amusendame/beakblock-core\n# or\npnpm add @amusendame/beakblock-react @amusendame/beakblock-core\n```\n\n## Quick Start\n\n```tsx\nimport { useBeakBlock, BeakBlockView, SlashMenu, BubbleMenu } from '@amusendame/beakblock-react';\nimport '@amusendame/beakblock-core/styles/editor.css';\n\nfunction MyEditor() {\n  const editor = useBeakBlock({\n    initialContent: [\n      {\n        type: 'heading',\n        props: { level: 1 },\n        content: [{ type: 'text', text: 'Hello World', styles: {} }],\n      },\n      {\n        type: 'paragraph',\n        content: [{ type: 'text', text: 'Start editing...', styles: {} }],\n      },\n    ],\n  });\n\n  if (!editor) return <div>Loading...</div>;\n\n  return (\n    <div className=\"editor-container\">\n      <BeakBlockView editor={editor} />\n      <SlashMenu editor={editor} />\n      <BubbleMenu editor={editor} />\n    </div>\n  );\n}\n```\n\n## Hooks\n\n### useBeakBlock\n\nCreates and manages an BeakBlockEditor instance.\n\n```tsx\nconst editor = useBeakBlock({\n  initialContent: [...],\n  editable: true,\n  autoFocus: 'end',\n  onUpdate: (blocks) => console.log(blocks),\n  deps: [someValue], // Recreate editor when deps change\n});\n```\n\n### useEditorContent\n\nSubscribe to document changes.\n\n```tsx\nconst blocks = useEditorContent(editor);\n// blocks updates whenever the document changes\n```\n\n### useEditorSelection\n\nSubscribe to selection changes.\n\n```tsx\nconst selectedBlocks = useEditorSelection(editor);\n// selectedBlocks updates when selection changes\n```\n\n### useEditorFocus\n\nTrack editor focus state.\n\n```tsx\nconst isFocused = useEditorFocus(editor);\n```\n\n## Comments\n\nUse **`CommentStore`** and **`createCommentPlugin`** from `@amusendame/beakblock-core`, and **`CommentModal`** from this package. There is no React `CommentRail` yet; use the modal and bubble menu.\n\nWire **`BubbleMenu`** with `onComment` to open the modal. On every editor transaction with a document change, call **`store.mapAnchors(transaction.mapping)`** so thread anchors match the document.\n\nFull API and patterns: **[Comments guide](../../docs/comments.md)**.\n\n## Components\n\n### BeakBlockView\n\nRenders the editor view.\n\n```tsx\n<BeakBlockView\n  editor={editor}\n  className=\"my-editor\"\n/>\n```\n\nWith ref for imperative access:\n\n```tsx\nconst viewRef = useRef<BeakBlockViewRef>(null);\n\n<BeakBlockView\n  ref={viewRef}\n  editor={editor}\n/>\n\n// Later: viewRef.current?.focus()\n```\n\n### SlashMenu\n\nCommand palette triggered by typing `/`.\n\n```tsx\n<SlashMenu editor={editor} />\n```\n\nSee [SlashMenu Customization](#slashmenu-customization) for advanced usage.\n\n### BubbleMenu\n\nFloating toolbar for text formatting.\n\n```tsx\n<BubbleMenu editor={editor} />\n```\n\nSee [BubbleMenu Customization](#bubblemenu-customization) for advanced usage.\n\n### ColorPicker\n\nColor picker for text and background colors.\n\n```tsx\nimport { ColorPicker } from '@amusendame/beakblock-react';\n\n<ColorPicker\n  editor={editor}\n  currentTextColor={textColor}\n  currentBackgroundColor={bgColor}\n/>\n```\n\nSee [ColorPicker Customization](#colorpicker-customization) for advanced usage.\n\n### TableHandles\n\nRow/column manipulation handles for tables.\n\n```tsx\n<TableHandles editor={editor} />\n```\n\n### MediaMenu\n\nMenu for media blocks (images, videos, files).\n\n```tsx\n<MediaMenu editor={editor} />\n```\n\n---\n\n## Customization API\n\n### BubbleMenu Customization\n\nThe BubbleMenu supports extensive customization through props.\n\n#### Props\n\n```tsx\ninterface BubbleMenuProps {\n  editor: BeakBlockEditor | null;\n  customItems?: BubbleMenuItem[];  // Add custom buttons\n  itemOrder?: string[];            // Control order (use '---' for dividers)\n  hideItems?: string[];            // Hide default items\n  className?: string;\n  children?: React.ReactNode;\n}\n```\n\n#### Default Item IDs\n\n- **Block type:** `blockType`\n- **Alignment:** `alignLeft`, `alignCenter`, `alignRight`\n- **Formatting:** `bold`, `italic`, `underline`, `strikethrough`\n- **Style:** `code`, `link`, `color`\n\n#### Example: Add a Custom Button\n\n```tsx\nimport { BubbleMenu, BubbleMenuItem } from '@amusendame/beakblock-react';\n\nconst translateButton: BubbleMenuItem = {\n  id: 'translate',\n  label: 'Translate',\n  icon: (\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\">\n      <path d=\"M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10\" />\n    </svg>\n  ),\n  action: async (editor, state) => {\n    const text = editor.pm.state.doc.textBetween(state.from, state.to);\n    const translated = await translateAPI(text);\n    // Replace selection...\n  },\n};\n\n<BubbleMenu\n  editor={editor}\n  customItems={[translateButton]}\n/>\n```\n\n#### Example: Reorder Items\n\n```tsx\n<BubbleMenu\n  editor={editor}\n  itemOrder={[\n    'bold', 'italic', 'underline',\n    '---',  // Divider\n    'link', 'color',\n    '---',\n    'translate',  // Custom item\n  ]}\n/>\n```\n\n#### Example: Minimal Toolbar\n\n```tsx\n<BubbleMenu\n  editor={editor}\n  itemOrder={['bold', 'italic', '---', 'link']}\n/>\n```\n\n#### Example: Hide Items\n\n```tsx\n<BubbleMenu\n  editor={editor}\n  hideItems={['strikethrough', 'code', 'alignLeft', 'alignCenter', 'alignRight']}\n/>\n```\n\n---\n\n### SlashMenu Customization\n\nThe SlashMenu supports customization similar to BubbleMenu.\n\n#### Props\n\n```tsx\ninterface SlashMenuProps {\n  editor: BeakBlockEditor | null;\n  items?: SlashMenuItem[];         // Replace all defaults\n  customItems?: SlashMenuItem[];   // Add to defaults\n  itemOrder?: string[];            // Control order (only listed items shown)\n  hideItems?: string[];            // Hide specific items\n  renderItem?: (item: SlashMenuItem, isSelected: boolean) => React.ReactNode;\n  className?: string;\n}\n```\n\n#### Default Item IDs\n\n- **Text:** `paragraph`, `heading`\n- **Lists:** `bulletList`, `numberedList`, `checkList`\n- **Blocks:** `blockquote`, `codeBlock`, `callout`, `divider`\n- **Tables:** `table`\n- **Media:** `image`, `video`, `audio`, `file`\n\n#### Example: Add Custom Items\n\n```tsx\nimport { SlashMenu, SlashMenuItem } from '@amusendame/beakblock-react';\n\nconst customItems: SlashMenuItem[] = [\n  {\n    id: 'emoji',\n    title: 'Emoji',\n    description: 'Insert an emoji picker',\n    icon: '😀',\n    action: (editor) => {\n      // Show emoji picker...\n    },\n  },\n  {\n    id: 'template',\n    title: 'Template',\n    description: 'Insert a predefined template',\n    icon: '📄',\n    action: (editor) => {\n      // Insert template...\n    },\n  },\n];\n\n<SlashMenu\n  editor={editor}\n  customItems={customItems}\n/>\n```\n\n#### Example: Custom Order\n\n```tsx\n<SlashMenu\n  editor={editor}\n  itemOrder={['paragraph', 'heading', 'bulletList', 'emoji', 'template']}\n/>\n```\n\n#### Example: Hide Items\n\n```tsx\n<SlashMenu\n  editor={editor}\n  hideItems={['table', 'video', 'audio', 'file']}\n/>\n```\n\n---\n\n### ColorPicker Customization\n\nThe ColorPicker component allows custom color palettes.\n\n#### Props\n\n```tsx\ninterface ColorPickerProps {\n  editor: BeakBlockEditor;\n  currentTextColor: string | null;\n  currentBackgroundColor: string | null;\n  textColors?: ColorOption[];       // Custom text color palette\n  backgroundColors?: ColorOption[]; // Custom background color palette\n  textColorLabel?: string;          // Label for text color section\n  backgroundColorLabel?: string;    // Label for background section\n  onClose?: () => void;\n}\n\ninterface ColorOption {\n  value: string;  // CSS color value ('' for default/remove)\n  label: string;  // Display label\n}\n```\n\n#### Default Palettes\n\n```tsx\nimport { DEFAULT_TEXT_COLORS, DEFAULT_BACKGROUND_COLORS } from '@amusendame/beakblock-react';\n\n// DEFAULT_TEXT_COLORS includes:\n// Default, Gray, Red, Orange, Yellow, Green, Blue, Purple, Pink\n\n// DEFAULT_BACKGROUND_COLORS includes:\n// Default, Gray, Red, Orange, Yellow, Green, Blue, Purple, Pink (lighter versions)\n```\n\n#### Example: Brand Color Palette\n\n```tsx\nimport { ColorPicker, ColorOption } from '@amusendame/beakblock-react';\n\nconst brandTextColors: ColorOption[] = [\n  { value: '', label: 'Default' },\n  { value: '#1a1a1a', label: 'Black' },\n  { value: '#0066cc', label: 'Primary' },\n  { value: '#00994d', label: 'Success' },\n  { value: '#cc3300', label: 'Error' },\n];\n\nconst brandBackgroundColors: ColorOption[] = [\n  { value: '', label: 'None' },\n  { value: '#e6f2ff', label: 'Blue' },\n  { value: '#e6ffe6', label: 'Green' },\n  { value: '#ffe6e6', label: 'Red' },\n];\n\n<ColorPicker\n  editor={editor}\n  currentTextColor={textColor}\n  currentBackgroundColor={bgColor}\n  textColors={brandTextColors}\n  backgroundColors={brandBackgroundColors}\n  textColorLabel=\"Text Color\"\n  backgroundColorLabel=\"Highlight\"\n/>\n```\n\n---\n\n## Accessing ProseMirror\n\nThe editor instance provides full ProseMirror access:\n\n```tsx\nfunction MyEditor() {\n  const editor = useBeakBlock({...});\n\n  const handleBold = () => {\n    editor.toggleBold();\n  };\n\n  const handleCustomAction = () => {\n    // Direct ProseMirror access\n    const tr = editor.pm.createTransaction();\n    tr.insertText('Custom text');\n    editor.pm.dispatch(tr);\n  };\n\n  return (\n    <>\n      <button onClick={handleBold}>Bold</button>\n      <button onClick={handleCustomAction}>Insert</button>\n      <BeakBlockView editor={editor} />\n    </>\n  );\n}\n```\n\n---\n\n## Exports\n\n### Components\n\n- `BeakBlockView` - Main editor view\n- `SlashMenu` - Command palette\n- `BubbleMenu` - Floating toolbar\n- `ColorPicker` - Color selection\n- `TableMenu` - Table manipulation menu\n- `TableHandles` - Table row/column handles\n- `MediaMenu` - Media block menu\n- `LinkPopover` - Link editing popover\n\n### Hooks\n\n- `useBeakBlock` - Create editor instance\n- `useEditorContent` - Subscribe to content\n- `useEditorSelection` - Subscribe to selection\n- `useEditorFocus` - Track focus state\n\n### Constants\n\n- `BUBBLE_MENU_ITEMS` - Default bubble menu items map\n- `DEFAULT_BUBBLE_MENU_ORDER` - Default bubble menu item order\n- `DEFAULT_TEXT_COLORS` - Default text color palette\n- `DEFAULT_BACKGROUND_COLORS` - Default background color palette\n\n### Types\n\n- `BeakBlockViewProps`, `BeakBlockViewRef`\n- `SlashMenuProps`, `SlashMenuItem`\n- `BubbleMenuProps`, `BubbleMenuItem`\n- `ColorPickerProps`, `ColorOption`\n- `TableMenuProps`, `TableHandlesProps`\n- `MediaMenuProps`, `LinkPopoverProps`\n\n---\n\n## Documentation\n\nFor complete documentation, see:\n\n- [React Integration Guide](../../docs/react-integration.md)\n- [Styling Guide](../../docs/styling.md)\n- [Custom Blocks](../../docs/custom-blocks.md)\n- [Plugins](../../docs/plugins.md)\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}