npm package: @oyat/editor
Description: A powerful, feature-rich Plate.js editor component with AI integration, collaboration features, and extensive customization options.
Author: OYAT
Latest version: 1.8.4

# Oyat Editor

A powerful, feature-rich Plate.js editor component with AI integration, collaboration features, and extensive customization options.

## Features

- 🚀 **Rich Text Editing** - Full-featured WYSIWYG editor with modern UI
- 🤖 **AI Integration** - Built-in AI assistance for content generation and editing
- 👥 **Collaboration** - Comments, suggestions, and discussion features
- 🎨 **Customizable** - Extensive theming and plugin system
- 📱 **Responsive** - Works seamlessly across all device sizes
- ♿ **Accessible** - Built with accessibility in mind
- 🔧 **TypeScript** - Full TypeScript support with comprehensive type definitions

## Installation

```bash
npm install @oyat/editor
# or
yarn add @oyat/editor
# or
pnpm add @oyat/editor
```

### Peer Dependencies

Make sure you have the required peer dependencies installed:

```bash
npm install react react-dom platejs
# or
pnpm add react react-dom platejs
```

## Quick Start

```tsx
import React from 'react';
import { PlateEditor, TooltipProvider } from '@oyat/editor';
// Styles are automatically included - no separate import needed!

function App() {
  const handleChange = (value) => {
    console.log('Editor content:', value);
  };

  return (
    <TooltipProvider>
      <PlateEditor initialValue="Start typing here..." onChange={handleChange} />
    </TooltipProvider>
  );
}

export default App;
```

> **Note:** Wrap the editor in `TooltipProvider` so toolbar buttons and other controls display tooltips correctly.

## Advanced Usage

### With Media Picker

```tsx
import React from 'react';
import { PlateEditor, TooltipProvider } from '@oyat/editor';

function EditorWithMediaPicker() {
  return (
    <TooltipProvider>
      <PlateEditor
        initialValue="Start typing..."
        onChange={(value) => console.log(value)}
        mediaPicker={({ onSelect }) => (
          <button onClick={() => onSelect({ url: 'https://example.com/image.jpg' })}>
            Insert Image
          </button>
        )}
      />
    </TooltipProvider>
  );
}
```

### With TypeScript

```tsx
import React from 'react';
import { PlateEditor, TooltipProvider, type PlateEditorProps, type Value } from '@oyat/editor';

function TypedEditor() {
  const [value, setValue] = React.useState<Value | undefined>();

  const handleChange: PlateEditorProps['onChange'] = (newValue) => {
    setValue(newValue);
    console.log('Editor content:', newValue);
  };

  return (
    <TooltipProvider>
      <PlateEditor initialValue={value} onChange={handleChange} />
    </TooltipProvider>
  );
}
```

### With Comments & Discussions

```tsx
import React from 'react';
import { PlateEditor, TooltipProvider, type TDiscussion } from '@oyat/editor';

function EditorWithComments() {
  const [discussions, setDiscussions] = React.useState<TDiscussion[]>([]);

  return (
    <TooltipProvider>
      <PlateEditor
        initialValue="Start typing..."
        onChange={(value) => console.log(value)}
        discussions={discussions}
        onDiscussionsChange={setDiscussions}
        currentUser="user-1:Jane Doe"
        commenting={true}
      />
    </TooltipProvider>
  );
}
```

## API Reference

### PlateEditor Props

```typescript
interface PlateEditorProps {
  initialValue?: Value | string;
  onChange?: (value: Value) => void;
  mode?: 'draft' | 'full';
  mediaPicker?: MediaPickerRenderProp;
  discussions?: TDiscussion[];
  currentUser?: string;
  onDiscussionsChange?: (discussions: TDiscussion[]) => void;
  commenting?: boolean;
}
```

| Prop                 | Type                              | Default     | Description                                                |
| -------------------- | --------------------------------- | ----------- | ---------------------------------------------------------- |
| `initialValue`       | `Value \| string`                 | `undefined` | Initial content for the editor                             |
| `onChange`           | `(value: Value) => void`          | `undefined` | Callback when content changes                               |
| `mode`               | `'draft' \| 'full'`                | `'draft'`   | Draft mode shows suggestions; full accepts changes         |
| `mediaPicker`        | `MediaPickerRenderProp`           | `undefined` | Custom media picker for image insertion                     |
| `discussions`        | `TDiscussion[]`                    | `undefined` | Discussion/collaboration data (controlled from outside)      |
| `currentUser`        | `string`                          | `undefined` | Current user in `"id:name"` format (e.g. `"id123:John Doe"`) |
| `onDiscussionsChange`| `(discussions: TDiscussion[]) => void` | `undefined` | Called when discussions change (new comment, resolved, etc.) |
| `commenting`         | `boolean`                         | `false`     | When true, show comment toolbar buttons                    |

### Available Plugin Kits

- `AlignKit` - Text alignment controls
- `AutoformatKit` - Markdown-style autoformatting
- `BasicBlocksKit` - Headings, paragraphs, blockquotes
- `BasicMarksKit` - Bold, italic, underline, etc.
- `BlockMenuKit` - Block-level menu controls
- `BlockPlaceholderKit` - Block placeholders
- `CalloutKit` - Callout/admonition blocks
- `CodeBlockKit` - Syntax-highlighted code blocks
- `ColumnKit` - Multi-column layouts
- `CommentKit` - Comment system
- `CursorOverlayKit` - Collaborative cursor overlay
- `DateKit` - Date picker integration
- `DndKit` - Drag and drop functionality
- `DocxKit` - DOCX import support
- `ExitBreakKit` - Soft/hard break handling
- `FixedToolbarKit` - Fixed toolbar UI
- `FloatingToolbarKit` - Floating toolbar UI
- `FontKit` - Font family and size controls
- `LineHeightKit` - Line height controls
- `LinkKit` - Link creation and management
- `ListKit` - Ordered and unordered lists
- `MathKit` - Mathematical expressions
- `MediaKit` - Image and media handling
- `MentionKit` - User mentions
- `SlashKit` - Slash command menu
- `SuggestionKit` - Content suggestions
- `TableKit` - Table creation and editing
- `TocKit` - Table of contents
- `ToggleKit` - Collapsible content blocks

### Additional Exports

For advanced usage, the package also exports:

- `EditorKit`, `BaseEditorKit` - Plugin arrays for custom editor setups
- `Editor`, `EditorContainer`, `EditorView` - Low-level editor components
- `parseUserId` - Parse user IDs from the `"id:name"` format
- `computeDiff`, `withGetFragmentExcludeDiff` - Diff utilities from `@platejs/diff`
- `serializeHtml`, `PlateStatic` - Static rendering from `platejs/static`
- Types: `MediaPickerApi`, `MediaPickerRenderProp`, `TDiscussion`, `Value`, `PlateEditorProps`, `EditorProps`, `MyEditor`

## Styling

The editor comes with built-in Tailwind CSS styles that are **automatically included** when you import the component - no separate CSS import needed!

### Custom Styling

The editor uses Tailwind CSS and includes all necessary theme variables. You can customize the appearance by:

- Overriding CSS variables in your own stylesheet
- Using Tailwind utility classes
- Applying custom themes via your Tailwind configuration

## Development

### Project Setup

If you want to set up the project from scratch:

```bash
# Create a new Vite React TypeScript project
pnpm create vite oyat-editor --template react-ts

cd oyat-editor

# Install shadcn/ui for Vite
# Follow: https://ui.shadcn.com/docs/installation/vite

# Add Plate UI components
pnpm dlx shadcn@latest add https://platejs.org/r/plate-ui

# Add Plate AI editor
pnpm dlx shadcn@latest add https://platejs.org/r/editor-ai

# pnpm add @platejs/diff
```

### Building the Library

```bash
pnpm run build:lib
```

This will:

- Build the library using Vite
- Generate TypeScript declarations automatically
- Output to `dist/` folder with optimized bundles

### Development Mode

Start the development server (runs the demo app):

```bash
pnpm run dev
```

### Type Checking

Run TypeScript type checking:

```bash
pnpm run type-check
```

### Linting

```bash
pnpm run lint
```

## Publishing

To publish a new version to npm:

```bash
# 1. Make sure all changes are committed
git add .
git commit -m "Your commit message"

# 2. Build the library
pnpm run build:lib

# 3. Verify the build output
ls -la dist/
# Should see: index.js, index.d.ts, index.js.map, and component declarations

# 4. Bump version (choose one)
pnpm version patch  # 1.0.0 → 1.0.1 (bug fixes)
pnpm version minor  # 1.0.0 → 1.1.0 (new features)
pnpm version major  # 1.0.0 → 2.0.0 (breaking changes)

# 5. Login to npm (if not already logged in)
npm login

# 6. Publish to npm
pnpm publish
# Note: First publish of a scoped package (@oyat/editor) requires: pnpm publish --access public

# 7. Verify publication
npm view @oyat/editor version
# Or visit: https://www.npmjs.com/package/@oyat/editor
```

**Note:** The `prepublishOnly` script automatically runs `build:lib` before publishing.

## Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is licensed under the MIT License.

## Support

- 📦 [NPM Package](https://www.npmjs.com/package/@oyat/editor)
- 📖 [Documentation](https://github.com/oyat-app/oyat-editor#readme)
- 🐛 [Issue Tracker](https://github.com/oyat-app/oyat-editor/issues)

## Acknowledgments

- Built with [Plate.js](https://platejs.org/) - The rich text editor framework
- Powered by [Slate.js](https://slatejs.org/) - The completely customizable framework for building rich text editors
- UI components from [Radix UI](https://www.radix-ui.com/) - Low-level UI primitives
- Styled with [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework