{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "installation-manual-docs",
  "title": "Manual Installation",
  "description": "Install and configure Plate in your React project without relying on UI component libraries.",
  "files": [
    {
      "path": "../../content/docs/installation/manual.mdx",
      "content": "---\ntitle: Manual Installation\ndescription: Install and configure Plate in your React project without relying on UI component libraries.\n---\n\nThis guide walks you through setting up Plate from scratch, giving you full control over styling and component rendering. This approach is ideal if you're not using a UI library like shadcn/ui or Tailwind CSS.\n\n<Steps>\n\n### Create Project\n\n<Callout type=\"info\">\nThis guide uses **Vite** for demonstrating the initial project setup. Plate is framework-agnostic and integrates seamlessly with other React environments like Next.js or Remix. You can adapt the general setup principles to your chosen framework.\n</Callout>\n\nTo begin with Vite, create a new project and select the **React + TypeScript** template:\n\n```bash\nnpm create vite@latest\n```\n\n### Install Core Dependencies\n\nFirst, install the necessary Plate packages. These packages provide the core editor functionality, React integration, and basic plugins for marks and elements.\n\n```bash\nnpm install platejs @platejs/basic-nodes\n```\n\n-   `platejs`: The core Plate engine and React components.\n-   `@platejs/basic-nodes`: Plugin for basic nodes like headings, bold, italic, underline, etc.\n\n### TypeScript Configuration\n\nPlate provides ESM packages. If you're using TypeScript, ensure your `tsconfig.json` is configured correctly. The recommended setup for Plate requires TypeScript 5.0+ with the `\"moduleResolution\": \"bundler\"` setting:\n\n```jsonc\n// tsconfig.json\n{\n  \"compilerOptions\": {\n    // ... other options\n    \"module\": \"esnext\", // or commonjs if your setup requires it and handles ESM interop\n    \"moduleResolution\": \"bundler\",\n    // ... other options\n  },\n}\n```\n\n<Callout type=\"info\">\n  If you cannot use `\"moduleResolution\": \"bundler\"` or are on an older TypeScript version, please see our [full TypeScript guide](/docs/typescript) for alternative configurations using path aliases.\n</Callout>\n\n### Create Your First Editor\n\nStart by creating a basic editor component. This example sets up a simple editor.\n\n```tsx title=\"src/App.tsx\"\nimport React from 'react';\nimport type { Value } from 'platejs';\nimport { Plate, PlateContent, usePlateEditor } from 'platejs/react';\n\nexport default function App() {\n  const editor = usePlateEditor();\n\n  return (\n    <Plate editor={editor}>\n      <PlateContent \n        style={{ padding: '16px 64px', minHeight: '100px' }}\n        placeholder=\"Type your amazing content here...\"\n      />\n    </Plate>\n  );\n}\n```\n\n<Callout type=\"info\">\n  `usePlateEditor` creates a memoized editor instance, ensuring stability across re-renders. For a non-memoized version, use `createPlateEditor` from `platejs/react`.\n</Callout>\n\n<ComponentPreview name=\"installation-next-01-editor-demo\" height=\"200px\" />\n\nAt this point, you'll have a very basic editor capable of displaying and editing plain text.\n\n### Adding Basic Marks\n\nLet's add support for basic text formatting like bold, italic, and underline.\n\n```tsx showLineNumbers title=\"src/App.tsx\" {4-8,32}\nimport React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BoldPlugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  PlateContent,\n  usePlateEditor,\n} from 'platejs/react';\n\nconst initialValue: Value = [\n  {\n    type: 'p',\n    children: [\n      { text: 'Hello! Try out the ' },\n      { text: 'bold', bold: true },\n      { text: ', ' },\n      { text: 'italic', italic: true },\n      { text: ', and ' },\n      { text: 'underline', underline: true },\n      { text: ' formatting.' },\n    ],\n  },\n];\n\nexport default function App() {\n  const editor = usePlateEditor({\n    plugins: [BoldPlugin, ItalicPlugin, UnderlinePlugin],\n    value: initialValue,\n  });\n\n  return (\n    <Plate editor={editor}>\n      {/* You would typically add a toolbar here to toggle marks */}\n      <PlateContent style={{ padding: '16px 64px', minHeight: '100px' }} />\n    </Plate>\n  );\n}\n```\n\n<Callout type=\"info\" title=\"Default Components\">\n  Mark plugins like `BoldPlugin`, `ItalicPlugin`, and `UnderlinePlugin` come with default components that render as `<strong>`, `<em>`, and `<u>` elements respectively. You don't need to register custom components unless you want to customize their appearance.\n</Callout>\n\n<ComponentPreview name=\"installation-next-02-marks-demo\" height=\"200px\" />\n\nYou'll need to implement your own toolbar to apply these marks. For example, to toggle bold: `editor.tf.bold.toggle()`.\n\n### Adding Basic Elements\n\nNow, let's add support for block-level elements like headings, and blockquotes.\n\n```tsx showLineNumbers title=\"src/App.tsx\" {5,7-9,76-79}\nimport React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BlockquotePlugin,\n  BoldPlugin,\n  H1Plugin,\n  H2Plugin,\n  H3Plugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  PlateContent,\n  PlateElement,\n  usePlateEditor,\n  type PlateElementProps,\n} from 'platejs/react';\n\nconst initialValue: Value = [\n  {\n    children: [{ text: 'Title' }],\n    type: 'h3',\n  },\n  {\n    children: [\n      {\n        children: [{ text: 'This is a quote.' }],\n        type: 'p',\n      },\n    ],\n    type: 'blockquote',\n  },\n  {\n    children: [\n      { text: 'With some ' },\n      { bold: true, text: 'bold' },\n      { text: ' text for emphasis!' },\n    ],\n    type: 'p',\n  },\n];\n\n// Define element components\nfunction H1Element(props: PlateElementProps) {\n  return <PlateElement as=\"h1\" {...props} />;\n}\n\nfunction H2Element(props: PlateElementProps) {\n  return <PlateElement as=\"h2\" {...props} />;\n}\n\nfunction H3Element(props: PlateElementProps) {\n  return <PlateElement as=\"h3\" {...props} />;\n}\n\nfunction BlockquoteElement(props: PlateElementProps) {\n  return (\n    <PlateElement\n      as=\"blockquote\"\n      style={{\n        borderLeft: '2px solid #eee',\n        marginLeft: 0,\n        marginRight: 0,\n        paddingLeft: '24px',\n        color: '#666',\n        fontStyle: 'italic',\n      }}\n      {...props}\n    />\n  );\n}\n\nexport default function App() {\n  const editor = usePlateEditor({\n    plugins: [\n      BoldPlugin,\n      ItalicPlugin,\n      UnderlinePlugin,\n      H1Plugin.withComponent(H1Element),\n      H2Plugin.withComponent(H2Element),\n      H3Plugin.withComponent(H3Element),\n      BlockquotePlugin.withComponent(BlockquoteElement),\n    ],\n    value: initialValue,\n  });\n\n  return (\n    <Plate editor={editor}>\n      {/* You would typically add a toolbar here to toggle elements and marks */}\n      <PlateContent style={{ padding: '16px 64px', minHeight: '100px' }} />\n    </Plate>\n  );\n}\n```\n\n<Callout type=\"note\">\n  Notice how we use `Plugin.withComponent(Component)` to register components with block element plugins like headings and blockquotes. This is the recommended approach for associating React components with Plate plugins when you need custom styling or behavior.\n</Callout>\n\n<ComponentPreview name=\"installation-next-03-elements-demo\" height=\"200px\" />\n\n### Handling Editor Value\n\nTo make the editor's content persistent, let's integrate state management to save and load the editor's value.\n\n```tsx showLineNumbers title=\"src/App.tsx\" {81-84,90-92}\nimport React from 'react';\nimport type { Value } from 'platejs';\n\nimport {\n  BlockquotePlugin,\n  BoldPlugin,\n  H1Plugin,\n  H2Plugin,\n  H3Plugin,\n  ItalicPlugin,\n  UnderlinePlugin,\n} from '@platejs/basic-nodes/react';\nimport {\n  Plate,\n  PlateContent,\n  PlateElement,\n  usePlateEditor,\n  type PlateElementProps,\n} from 'platejs/react';\n\nconst initialValue: Value = [\n  {\n    children: [{ text: 'Title' }],\n    type: 'h3',\n  },\n  {\n    children: [\n      {\n        children: [{ text: 'This is a quote.' }],\n        type: 'p',\n      },\n    ],\n    type: 'blockquote',\n  },\n  {\n    children: [\n      { text: 'With some ' },\n      { bold: true, text: 'bold' },\n      { text: ' text for emphasis!' },\n    ],\n    type: 'p',\n  },\n];\n\n// Define element components\nfunction H1Element(props: PlateElementProps) {\n  return <PlateElement as=\"h1\" {...props} />;\n}\n\nfunction H2Element(props: PlateElementProps) {\n  return <PlateElement as=\"h2\" {...props} />;\n}\n\nfunction H3Element(props: PlateElementProps) {\n  return <PlateElement as=\"h3\" {...props} />;\n}\n\nfunction BlockquoteElement(props: PlateElementProps) {\n  return (\n    <PlateElement\n      as=\"blockquote\"\n      style={{\n        borderLeft: '2px solid #eee',\n        marginLeft: 0,\n        marginRight: 0,\n        paddingLeft: '24px',\n        color: '#666',\n        fontStyle: 'italic',\n      }}\n      {...props}\n    />\n  );\n}\n\nexport default function App() {\n  const editor = usePlateEditor({\n    plugins: [\n      BoldPlugin,\n      ItalicPlugin,\n      UnderlinePlugin,\n      H1Plugin.withComponent(H1Element),\n      H2Plugin.withComponent(H2Element),\n      H3Plugin.withComponent(H3Element),\n      BlockquotePlugin.withComponent(BlockquoteElement),\n    ],\n    value: () => {\n      const savedValue = localStorage.getItem('plate-manual-demo');\n      return savedValue ? JSON.parse(savedValue) : initialValue;\n    },\n  });\n\n  return (\n    <Plate\n      editor={editor}\n      onChange={({ value }) => {\n        localStorage.setItem('plate-manual-demo', JSON.stringify(value));\n      }}\n    >\n      {/* Toolbar would go here */}\n      <div style={{ padding: '8px 0' }}>\n        <button\n          onClick={() => editor.tf.setValue(initialValue)}\n          style={{\n            padding: '4px 8px',\n            margin: '0 4px',\n            border: '1px solid #ccc',\n            borderRadius: '4px',\n            cursor: 'pointer',\n          }}\n        >\n          Reset\n        </button>\n      </div>\n      <PlateContent\n        style={{\n          padding: '16px 64px',\n          minHeight: '100px',\n          border: '1px solid #eee',\n          borderRadius: '4px',\n        }}\n        placeholder=\"Type your amazing content here...\"\n      />\n    </Plate>\n  );\n}\n```\n\n<Callout type=\"info\" title=\"Value Management\">\n  The example above demonstrates a basic pattern for managing editor value:\n  - Initial value is set through the `value` option in `usePlateEditor`\n  - Changes can be handled via the `onChange` prop on `<Plate>`\n  - The reset button uses `editor.tf.setValue()` to restore the initial value\n  - To control the value, see [Controlled Value](/docs/controlled)\n</Callout>\n\n<ComponentPreview name=\"installation-next-demo\" />\n\n### Next Steps\n\nYou've now set up a basic Plate editor manually! From here, you can:\n\n*   **Add Styling:**\n    *   For a quick start with pre-built components, consider using [Plate UI](/docs/installation/plate-ui)\n    *   Or continue styling manually using CSS, CSS-in-JS libraries, or your preferred styling solution\n*   **[Add Plugins](/docs/plugins):** Plate has a rich ecosystem of plugins for features like tables, mentions, images, lists, and more. Install their packages (e.g., `@platejs/table`) and add them to your `plugins` array.\n*   **[Build a Toolbar](/docs/toolbar):** Create React components for toolbar buttons that use the [Editor Transforms](/docs/transforms) to apply formatting (e.g., `editor.tf.bold.toggle()`, `editor.tf.h1.toggle()`). You can also use the editor state with the [Editor API](/docs/api).\n*   **Learn More:**\n    *   [Editor Configuration](/docs/editor)\n    *   [Plugin Configuration](/docs/plugin)\n    *   [Plugin Components](/docs/plugin-components)\n\n</Steps>\n",
      "type": "registry:file",
      "target": "content/docs/plate/installation/manual.mdx"
    }
  ],
  "type": "registry:file"
}