{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "plugin-context-docs",
  "title": "Plugin Context",
  "description": "Use editor, plugin, option, API, and transform context inside Plate plugins.",
  "files": [
    {
      "path": "../../content/docs/(guides)/plugin-context.mdx",
      "content": "---\ntitle: Plugin Context\ndescription: Use editor, plugin, option, API, and transform context inside Plate plugins.\n---\n\nPlugin context is the object Plate passes to plugin configuration callbacks,\nhandlers, extensions, transforms, and render components. It gives you the\nresolved editor, current plugin, node type, `api`, `tf`, and option helpers\nwithout reaching through global state. Use it inside plugin-owned code; use\neditor methods or React hooks when code runs outside a plugin callback.\n\n## Context Shape\n\n`PlatePluginContext` extends the shared plugin context with a React\n`PlateEditor`. The same helper names are available in headless Slate plugins,\nbut the editor type is `SlateEditor`.\n\n| Property | Use for |\n| --- | --- |\n| `editor` | The resolved editor instance. |\n| `plugin` | The resolved plugin configuration for the current plugin. |\n| `type` | The plugin node type, usually `plugin.node.type`. |\n| `api` | Editor API plus plugin-specific API methods. |\n| `tf` | Editor transforms plus plugin-specific transforms. |\n| `getOption(key, ...args)` | Read an option, selector, or `'state'` from the current plugin. |\n| `getOptions()` | Read the full option state for the current plugin. |\n| `setOption(key, value)` | Update one option in the current plugin store. |\n| `setOptions(optionsOrDraft)` | Update multiple options or mutate a draft. |\n\n## Plugin Methods\n\nHandlers receive context plus the event or payload for that handler. Use the\ncontext helpers instead of closing over editor state.\n\n```ts title=\"counter-plugin.ts\" showLineNumbers\nimport { createPlatePlugin } from 'platejs/react';\n\nexport const CounterPlugin = createPlatePlugin({\n  key: 'counter',\n  options: {\n    count: 0,\n    enabled: true,\n  },\n  handlers: {\n    onKeyDown: ({ event, getOption, setOption, type }) => {\n      if (!getOption('enabled')) return;\n\n      if (event.key === '+') {\n        setOption('count', getOption('count') + 1);\n        console.info(`${type} count incremented`);\n      }\n    },\n  },\n});\n```\n\n`getOption` and `setOption` are scoped to `CounterPlugin` in this example.\n\n## Extension Callbacks\n\nConfiguration, extension, selector, API, transform, and editor override callbacks\nalso receive plugin context.\n\n```ts title=\"counter-plugin.ts\" showLineNumbers\nimport { createPlatePlugin } from 'platejs/react';\n\nexport const CounterPlugin = createPlatePlugin({\n  key: 'counter',\n  options: {\n    count: 0,\n  },\n})\n  .extendSelectors(({ getOptions }) => ({\n    label: () => `Count: ${getOptions().count}`,\n  }))\n  .extendApi(({ getOption }) => ({\n    isEmpty: () => getOption('count') === 0,\n  }));\n```\n\nSelectors are readable through `getOption` and subscribable through\n`usePluginOption`.\n\n## Another Plugin\n\nUse `getEditorPlugin(editor, Plugin)` when plugin-owned code needs another\nplugin's context. The editor argument is required.\n\n```ts title=\"link-aware-plugin.ts\" showLineNumbers\nimport { LinkPlugin } from '@platejs/link/react';\nimport { createPlatePlugin, getEditorPlugin } from 'platejs/react';\n\nexport const LinkAwarePlugin = createPlatePlugin({\n  key: 'linkAware',\n  handlers: {\n    onKeyDown: ({ editor, event }) => {\n      if (event.key !== 'Enter') return;\n\n      const link = getEditorPlugin(editor, LinkPlugin);\n\n      console.info(`Link node type: ${link.type}`);\n    },\n  },\n});\n```\n\nUse this for cross-plugin reads. Keep cross-plugin writes rare; they couple two\nplugins tightly.\n\n## React Components\n\nUse `useEditorPlugin` inside a component rendered under `<Plate>`. It returns\nthe same context plus the editor store.\n\n```tsx title=\"counter-badge.tsx\" showLineNumbers\nimport { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport { CounterPlugin } from './counter-plugin';\n\nexport function CounterBadge() {\n  const { type } = useEditorPlugin(CounterPlugin);\n  const count = usePluginOption(CounterPlugin, 'count');\n  const label = usePluginOption(CounterPlugin, 'label');\n\n  return (\n    <span data-plugin-type={type}>\n      {label} ({count})\n    </span>\n  );\n}\n```\n\nUse `usePluginOptions` when a component needs a derived value from several\noptions.\n\n```tsx title=\"counter-badge.tsx\" showLineNumbers\nimport { usePluginOptions } from 'platejs/react';\n\nimport { CounterPlugin } from './counter-plugin';\n\nexport function CounterStatus() {\n  const status = usePluginOptions(CounterPlugin, (state) =>\n    state.count === 0 ? 'empty' : 'active'\n  );\n\n  return <span>{status}</span>;\n}\n```\n\nFor code outside the nearest `<Plate>` provider, pass an editor explicitly with\n`useEditorPluginOption` or `useEditorPluginOptions`.\n\n## Option State\n\nPlugin options are stored per editor. Updating one editor's plugin options does\nnot update another editor.\n\n```ts title=\"counter-plugin.ts\" showLineNumbers\nexport const CounterPluginWithInitialCount = CounterPlugin.configure(\n  ({ getOptions }) => ({\n    options: {\n      count: getOptions().count + 1,\n    },\n  })\n);\n```\n\n`setOptions` accepts either a partial object or a draft callback.\n\n```ts title=\"counter-actions.ts\" showLineNumbers\nimport { getEditorPlugin, type PlateEditor } from 'platejs/react';\n\nimport { CounterPlugin } from './counter-plugin';\n\nexport function resetCounter(editor: PlateEditor) {\n  const { setOptions } = getEditorPlugin(editor, CounterPlugin);\n\n  setOptions({\n    count: 1,\n  });\n\n  setOptions((draft) => {\n    draft.count += 1;\n  });\n}\n```\n\nPlate reports `OPTION_UNDEFINED` through the debug API when `getOption`,\n`setOption`, or `usePluginOption` targets a missing option or selector.\n\n## API Reference\n\n| Helper | Scope | Notes |\n| --- | --- | --- |\n| `getEditorPlugin(editor, plugin)` | Any editor code. | Returns plugin context for the given editor and plugin. |\n| `useEditorPlugin(plugin, id?)` | React under `<Plate>`. | Returns plugin context plus `store`. |\n| `usePluginOption(plugin, key, ...args)` | React under `<Plate>`. | Subscribes to one option, selector, or `'state'`. |\n| `usePluginOptions(plugin, selector, options?)` | React under `<Plate>`. | Subscribes to a selected value from the option state. |\n| `useEditorPluginOption(editor, plugin, key, ...args)` | React with explicit editor. | Use outside the closest editor provider. |\n| `useEditorPluginOptions(editor, plugin, selector, options?)` | React with explicit editor. | Explicit-editor variant of `usePluginOptions`. |\n\nFor plugin extension methods, see [Plugin Methods](/docs/plugin-methods). For\nplugin configuration, see [Plugin](/docs/plugin).\n",
      "type": "registry:file",
      "target": "content/docs/plate/(guides)/plugin-context.mdx"
    }
  ],
  "type": "registry:file"
}