{"id":31552356,"url":"https://github.com/yodasmydad/zaubereditor","last_synced_at":"2026-04-13T08:31:34.223Z","repository":{"id":317681159,"uuid":"1067149975","full_name":"YodasMyDad/ZauberEditor","owner":"YodasMyDad","description":"A modern, extensible rich-text editor component for Blazor applications. Built with performance, accessibility, and developer experience in mind.","archived":false,"fork":false,"pushed_at":"2025-10-02T11:16:28.000Z","size":1127,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-02T12:29:11.434Z","etag":null,"topics":["blazor"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YodasMyDad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-30T12:55:52.000Z","updated_at":"2025-10-02T11:16:32.000Z","dependencies_parsed_at":"2025-10-02T12:29:13.061Z","dependency_job_id":"b660629c-2505-4ec6-8529-6e254810fc45","html_url":"https://github.com/YodasMyDad/ZauberEditor","commit_stats":null,"previous_names":["yodasmydad/zaubereditor"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/YodasMyDad/ZauberEditor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YodasMyDad%2FZauberEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YodasMyDad%2FZauberEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YodasMyDad%2FZauberEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YodasMyDad%2FZauberEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YodasMyDad","download_url":"https://codeload.github.com/YodasMyDad/ZauberEditor/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YodasMyDad%2FZauberEditor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278366632,"owners_count":25975090,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor"],"created_at":"2025-10-04T19:53:07.966Z","updated_at":"2026-04-13T08:31:34.210Z","avatar_url":"https://github.com/YodasMyDad.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blazor Rich Text Editor\n\n[![NuGet](https://img.shields.io/nuget/v/ZauberCMS.RTE.svg)](https://www.nuget.org/packages/ZauberCMS.RTE/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![.NET](https://img.shields.io/badge/.NET-10.0-blue.svg)](https://dotnet.microsoft.com/)\n\nA modern, extensible rich-text editor component for Blazor applications. Built with performance, accessibility, and developer experience in mind. [Built to be part of ZauberCMS](https://github.com/YodasMyDad/ZauberCMS), but released as own package.\n\n## Features\n\n- 🚀 **Blazor Native**: Fully built for Blazor Server and WebAssembly\n- 🎨 **Highly Configurable**: Extensive customization options for toolbar, capabilities, and behavior\n- 🔒 **Secure by Default**: Built-in HTML sanitization with configurable policies\n- ⌨️ **Keyboard Shortcuts**: Full keyboard support with customizable shortcuts\n- 🖼️ **Media Support**: Image upload, drag-and-drop, and embed support\n- 📱 **Responsive**: Mobile-friendly with touch support\n- 🎯 **Accessible**: ARIA compliant with screen reader support\n- 🧩 **Extensible**: Plugin architecture for custom toolbar items and functionality\n- 🎨 **Themes**: Light, dark theme support\n- 📝 **Source View**: Toggle between rich text and HTML source editing\n\n## Installation\n\n### NuGet Package\n\n```bash\ndotnet add package ZauberCMS.RTE\n```\n\n### Manual Installation\n\n1. Clone or download the ZauberCMS.RTE project\n2. Reference the `ZauberCMS.RTE.csproj` in your Blazor project\n3. Ensure static web assets are served correctly\n\n## Quick Start\n\n### 1. Register Services\n\nIn your `Program.cs`:\n\n```csharp\nusing ZauberCMS.RTE.Services;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add Zauber RTE services - scans entry assembly for custom toolbar items\nbuilder.Services.AddZauberRte();\n\n// Or scan additional assemblies for custom toolbar items\nbuilder.Services.AddZauberRte(typeof(Program).Assembly, typeof(MyPlugin.Class).Assembly);\n\n// IMPORTANT: If using base64 image uploads (AllowBase64ImageUpload = true),\n// increase SignalR message size limit to support large images\nbuilder.Services.AddSignalR(options =\u003e\n{\n    options.MaximumReceiveMessageSize = 1 * 1024 * 1024; // 1 MB\n});\n\nvar app = builder.Build();\n```\n\n**Note about SignalR Configuration:**\n\n- Base64-encoded images can be large (a 50KB image becomes ~67KB when base64-encoded)\n- The default SignalR message size limit is 32KB\n- If you enable base64 image uploads, you must increase this limit\n- Set `AllowBase64ImageUpload = false` in `ImageConstraints` if you only want URL-based images\n\n### 2. Add to Your Page\n\n```razor\n@using ZauberCMS.RTE.Components\n@using ZauberCMS.RTE.Models\n\n\u003cZauberRichTextEditor @bind-Value=\"editorContent\"\n                      Settings=\"editorSettings\"\n                      OnChange=\"HandleContentChange\" /\u003e\n\n@code {\n    private string editorContent = \"\";\n    private EditorSettings editorSettings = EditorSettings.CmsDefault();\n\n    private void HandleContentChange(EditorChangeArgs args)\n    {\n        // Handle content changes\n        Console.WriteLine($\"Content changed: {args.Html}\");\n    }\n}\n```\n\n### 3. Include Required Assets\n\nAdd the required CSS and JavaScript files to your `App.razor` (or `_Host.cshtml` for Blazor Server):\n\n```html\n\u003chead\u003e\n    \u003c!-- Other head content --\u003e\n    \n    \u003c!-- Zauber RTE Styles (required) --\u003e\n    \u003clink rel=\"stylesheet\" href=\"_content/ZauberCMS.RTE/css/fontawesome.min.css\" /\u003e\n    \u003clink rel=\"stylesheet\" href=\"_content/ZauberCMS.RTE/css/zauber-editor.css\" /\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n    \u003c!-- Your app content --\u003e\n    \u003cscript src=\"_framework/blazor.web.js\"\u003e\u003c/script\u003e\n    \n    \u003c!-- Zauber RTE Scripts (required) --\u003e\n    \u003cscript src=\"_content/ZauberCMS.RTE/js/lib/purify.min.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"_content/ZauberCMS.RTE/js/zauber-rte.js\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n```\n\n**Important Notes:**\n\n- The Zauber RTE scripts must be loaded after the Blazor framework script\n- Font Awesome is bundled for the toolbar icons\n- All editor, panel, and component styles are consolidated in `zauber-editor.css`\n\n## Configuration\n\n### Basic Settings\n\n```csharp\nvar settings = new EditorSettings\n{\n    // Configure toolbar layout - controls which buttons appear\n    ToolbarLayout = ToolbarLayout.Full,  // or Simple, Minimal, Cms\n\n    // Set dimensions\n    Dimensions = new EditorDimensions\n    {\n        Width = \"100%\",\n        Height = \"300px\",\n        MinHeight = 100,\n        MaxHeight = 600\n    },\n\n    // Image constraints\n    ImageConstraints = new ImageConstraints\n    {\n        MaxWidth = 800,\n        MaxHeight = 600,\n        MaintainAspectRatio = true,\n        AllowBase64ImageUpload = false, // Set to true to enable file uploads as base64 (requires SignalR config)\n        AllowedImageTypes = new() { \".jpg\", \".jpeg\", \".gif\", \".png\" }\n    }\n};\n```\n\n### Predefined Configurations\n\n```csharp\n// CMS-ready configuration with full toolbar\nvar cmsSettings = EditorSettings.CmsDefault();\n\n// Minimal configuration with simple toolbar (bold, italic, underline, align)\nvar minimalSettings = EditorSettings.Minimal();\n\n// Or customize the toolbar layout directly\nvar customSettings = new EditorSettings\n{\n    ToolbarLayout = ToolbarLayout.FromItems(\n        new ToolbarBlock(\"bold\", \"italic\", \"underline\"),\n        new ToolbarSeparator(),\n        new ToolbarBlock(\"link\", \"image\")\n    )\n};\n```\n\n### HTML Sanitization\n\n```csharp\nvar settings = new EditorSettings\n{\n    HtmlPolicy = new HtmlPolicy\n    {\n        AllowedTags = new HashSet\u003cstring\u003e { \"p\", \"strong\", \"em\", \"a\", \"img\" },\n        AllowedAttributes = new Dictionary\u003cstring, HashSet\u003cstring\u003e\u003e\n        {\n            [\"a\"] = new() { \"href\", \"target\" },\n            [\"img\"] = new() { \"src\", \"alt\", \"width\", \"height\" }\n        },\n        AllowDataUrls = false,\n        AllowExternalImages = true\n    }\n};\n```\n\n### Keyboard Shortcuts\n\nKeyboard shortcuts are defined directly on toolbar items, making them fully extensible:\n\n```csharp\npublic class MyCustomItem : ToolbarItemBase\n{\n    public override string Id =\u003e \"myCustom\";\n    public override string Label =\u003e \"My Custom Action\";\n    public override string IconCss =\u003e \"fa-star\";\n    public override string Shortcut =\u003e \"Control+Shift+m\";  // Define your shortcut here!\n    \n    public override Task ExecuteAsync(EditorApi api)\n    {\n        // Your custom logic\n        return Task.CompletedTask;\n    }\n}\n```\n\nBuilt-in shortcuts:\n\n- **Bold**: Ctrl+B\n- **Italic**: Ctrl+I  \n- **Underline**: Ctrl+U\n- **Link**: Ctrl+K\n- **Unordered List**: Ctrl+Shift+8\n- **Ordered List**: Ctrl+Shift+7\n- **Undo**: Ctrl+Z\n- **Redo**: Ctrl+Y\n\n## Component API\n\n### Properties\n\n| Property        | Type             | Description                      |\n| --------------- | ---------------- | -------------------------------- |\n| `Value`         | `string?`        | The HTML content of the editor   |\n| `Settings`      | `EditorSettings` | Configuration settings           |\n| `ToolbarLayout` | `ToolbarLayout`  | Toolbar layout configuration     |\n| `Theme`         | `Theme`          | Visual theme (Light, Dark, Auto) |\n| `ReadOnly`      | `bool`           | Whether the editor is read-only  |\n\n### Events\n\n| Event                | Type                                     | Description                 |\n| -------------------- | ---------------------------------------- | --------------------------- |\n| `ValueChanged`       | `EventCallback\u003cstring?\u003e`                 | Fired when content changes  |\n| `OnChange`           | `EventCallback\u003cEditorChangeArgs\u003e`        | Detailed change information |\n| `OnKeyDown`          | `EventCallback\u003cZauberKeyboardEventArgs\u003e` | Keyboard events             |\n| `OnSelectionChanged` | `EventCallback\u003cSelectionChangedArgs\u003e`    | Selection changes           |\n| `OnPaste`            | `EventCallback\u003cPasteArgs\u003e`               | Paste events                |\n| `OnImageResized`     | `EventCallback\u003cImageResizedArgs\u003e`        | Image resize events         |\n| `OnCommandExecuted`  | `EventCallback\u003cCommandExecutedArgs\u003e`     | Toolbar command execution   |\n\n## Toolbar Customization\n\n### Default Toolbar Items\n\nThe editor comes with comprehensive toolbar items:\n\n**Text Formatting**: Bold, Italic, Underline, Strikethrough, Code, Subscript, Superscript\n\n**Headings**: H1-H6 (available as individual buttons or dropdown)\n\n**Lists**: Unordered List, Ordered List\n\n**Alignment**: Left, Center, Right, Justified\n\n**Insert**: Link, Image\n\n**Utilities**: Clean Html, Undo, Redo, View Source, Theme Toggle\n\n### Toolbar Item Types\n\nThe editor supports three types of toolbar items:\n\n1. **Button** - Standard clickable button (Bold, Italic, etc.)\n2. **Dropdown** - Menu with child items (e.g., Headings dropdown with H1-H6)\n3. **Separator** - Visual divider between toolbar groups\n\n### Flexible Toolbar Layouts\n\nThe new flexible layout system allows complete customization with blocks, separators, and individual items:\n\n```csharp\nusing ZauberCMS.RTE.Models;\n\n// Use predefined layouts\nvar settings = new EditorSettings\n{\n    ToolbarLayout = ToolbarLayout.Simple,  // Simple: basic formatting + alignment\n    // ToolbarLayout = ToolbarLayout.Full,    // Full: all features logically grouped\n    // ToolbarLayout = ToolbarLayout.Minimal, // Minimal: bold, italic, link only\n    // ToolbarLayout = ToolbarLayout.Cms,     // CMS-focused layout\n};\n\n// Create custom layout with blocks and separators\nvar customLayout = ToolbarLayout.FromItems(\n    new ToolbarBlock(\"bold\", \"italic\", \"underline\"),  // Block of buttons\n    new ToolbarSeparator(),                            // Visual separator\n    new ToolbarBlock(\"headings\"),                      // Headings dropdown (H1-H6)\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"link\", \"image\")\n);\n\n// Advanced: individual items with custom CSS (use IEnumerable for cssClass parameter)\nvar advancedLayout = ToolbarLayout.FromItems(\n    new ToolbarBlock(\"my-custom-class\", new[] { \"undo\", \"redo\" }),\n    new ToolbarSeparator(\"my-separator-style\"),\n    new ToolbarItemReference(\"link\", \"my-link-style\"),\n    new ToolbarBlock(\"bold\", \"italic\")\n);\n```\n\n### Headings Dropdown\n\nThe new headings dropdown consolidates H1-H6 into a single dropdown menu:\n\n```csharp\n// Use the headings dropdown (recommended)\nToolbarLayout = ToolbarLayout.FromItems(\n    new ToolbarBlock(\"bold\", \"italic\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"headings\")  // Dropdown with H1-H6 and reset option\n);\n\n// Or use individual heading buttons\nToolbarLayout = ToolbarLayout.FromItems(\n    new ToolbarBlock(\"bold\", \"italic\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\")  // Individual buttons\n);\n```\n\nThe headings dropdown automatically:\n\n- Shows the currently active heading (H1, H2, etc.)\n- Highlights the selected heading in the dropdown menu\n- Displays heading previews with appropriate font sizes\n- Closes when clicking outside the dropdown\n\n### Layout Examples\n\n```csharp\n// Blog editor with all features\npublic static ToolbarLayout BlogLayout =\u003e ToolbarLayout.FromItems(\n    new ToolbarBlock(\"undo\", \"redo\", \"viewSource\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"headings\", \"blockquote\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"bold\", \"italic\", \"underline\", \"strike\", \"code\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"ul\", \"ol\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"link\", \"unlink\", \"image\"),\n    new ToolbarSeparator(),\n    new ToolbarBlock(\"alignLeft\", \"alignCenter\", \"alignRight\")\n);\n\n// Simple comment editor\npublic static ToolbarLayout CommentLayout =\u003e ToolbarLayout.FromItems(\n    new ToolbarBlock(\"bold\", \"italic\", \"link\")\n);\n\n// Using helper methods\nvar layout = ToolbarLayout.FromItems(\n    ToolbarLayoutExtensions.Block(\"bold\", \"italic\"),\n    ToolbarLayoutExtensions.Separator(),\n    ToolbarLayoutExtensions.Item(\"headings\")\n);\n```\n\n### Custom Toolbar Items\n\nCreate custom toolbar items by implementing `IToolbarItem`. See the **Extension Guide** section below for detailed examples.\n\n### Creating Custom Dropdowns\n\nYou can create your own dropdown toolbar items:\n\n```csharp\npublic class MyDropdownItem : ToolbarItemBase\n{\n    public override string Id =\u003e \"myDropdown\";\n    public override string Label =\u003e \"My Options\";\n    public override string IconCss =\u003e \"fa-list\";\n    public override ToolbarPlacement Placement =\u003e ToolbarPlacement.Custom;\n    public override ToolbarItemType ItemType =\u003e ToolbarItemType.Dropdown;\n    \n    public override List\u003cIToolbarItem\u003e ChildItems =\u003e\n    [\n        new MyOption1Item(),\n        new MyOption2Item(),\n        new MyOption3Item()\n    ];\n    \n    public override Task ExecuteAsync(IEditorApi api) =\u003e Task.CompletedTask;\n}\n```\n\n## Advanced Usage\n\n### Programmatic Control\n\n```csharp\n@inject EditorApi EditorApi\n\n\u003cZauberRichTextEditor @ref=\"editor\" /\u003e\n\n@code {\n    private ZauberRichTextEditor? editor;\n\n    private async Task InsertCustomContent()\n    {\n        if (editor?.EditorApi != null)\n        {\n            await editor.EditorApi.InsertHtmlAsync(\"\u003cp\u003eCustom content\u003c/p\u003e\");\n            await editor.EditorApi.SetSelectionAsync(\"end\");\n        }\n    }\n}\n```\n\n### Image Handling\n\n```csharp\nprivate async Task HandleImageUpload(ImageUploadArgs args)\n{\n    // Handle image upload\n    var imageUrl = await UploadImageToServer(args.File);\n\n    // Insert the image\n    await args.InsertImageAsync(imageUrl, args.AltText);\n}\n```\n\n### Custom Panels\n\nCreate custom slide-out panels by inheriting from `PanelBase`:\n\n```razor\n\u003c!-- CustomPanel.razor --\u003e\n@using ZauberCMS.RTE.Models\n@inherits PanelBase\n\n\u003cdiv class=\"rte-panel-content\"\u003e\n    \u003ch3 class=\"rte-panel-title\"\u003eCustom Panel\u003c/h3\u003e\n    \n    \u003cdiv class=\"rte-form-group\"\u003e\n        \u003clabel class=\"rte-label\"\u003eEnter Value\u003c/label\u003e\n        \u003cinput @bind=\"customValue\" class=\"rte-input\" /\u003e\n    \u003c/div\u003e\n\n    \u003cdiv class=\"rte-panel-actions\"\u003e\n        \u003cbutton type=\"button\" class=\"rte-btn rte-btn-secondary\" @onclick=\"CloseAsync\"\u003e\n            Cancel\n        \u003c/button\u003e\n        \u003cbutton type=\"button\" class=\"rte-btn rte-btn-primary\" @onclick=\"ApplyAsync\"\u003e\n            Apply\n        \u003c/button\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n@code {\n    private string customValue = \"\";\n\n    private async Task ApplyAsync()\n    {\n        if (Api == null) return;\n        \n        // Use HtmlBuilder for clean HTML generation\n        var html = HtmlBuilder.Element(\"div\")\n            .Class(\"custom-content\")\n            .Text(customValue)\n            .Build();\n            \n        await Api.InsertHtmlAsync(html);\n        await CloseAsync();\n    }\n}\n```\n\n## Styling\n\n### CSS Variables\n\nCustomize appearance using CSS variables:\n\n```css\n.zauber-rte {\n    --rte-primary-color: #007acc;\n    --rte-border-color: #e1e5e9;\n    --rte-background-color: #ffffff;\n    --rte-text-color: #333333;\n    --rte-toolbar-height: 40px;\n    --rte-font-family: 'Segoe UI', sans-serif;\n}\n```\n\n### Themes\n\n```razor\n\u003c!-- Light theme --\u003e\n\u003cZauberRichTextEditor Theme=\"Theme.Light\" /\u003e\n\n\u003c!-- Dark theme --\u003e\n\u003cZauberRichTextEditor Theme=\"Theme.Dark\" /\u003e\n\n\u003c!-- Auto theme (follows system preference) --\u003e\n\u003cZauberRichTextEditor Theme=\"Theme.Auto\" /\u003e\n```\n\n## Security Considerations\n\n- HTML content is sanitized by default using a configurable policy\n- Data URLs can be disabled for images\n- External images can be restricted\n- XSS protection through DOMPurify integration\n- Content Security Policy (CSP) friendly\n\n## Browser Support\n\n- Chrome 80+\n- Firefox 75+\n- Safari 13+\n- Edge 80+\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable\n5. Submit a pull request\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Extensibility\n\nCreate custom toolbar buttons and panels in minutes. Zauber RTE provides a simple, powerful extension system.\n\n```csharp\n// Create a custom toolbar item\npublic class EmojiItem : ToolbarItemBase\n{\n    public override string Id =\u003e \"emoji\";\n    public override string Label =\u003e \"Emoji\";\n    public override string IconCss =\u003e \"fa-smile\";\n    \n    public override async Task ExecuteAsync(EditorApi api)\n    {\n        await api.InsertHtmlAsync(\"😀\");\n    }\n}\n```\n\n### Override Built-in Items\n\nCustomize any built-in toolbar item by creating your own with the same ID:\n\n```csharp\n// Override the built-in Bold button with custom behavior\npublic class BoldItem : ToolbarItemBase\n{\n    public override string Id =\u003e \"bold\";  // Same ID = replaces default\n    public override string Label =\u003e \"Bold\";\n    public override string IconCss =\u003e \"fa-bold\";\n    public override string Shortcut =\u003e \"Control+b\";\n    \n    public override async Task ExecuteAsync(EditorApi api)\n    {\n        // Your custom bold logic here\n        await api.ToggleMarkAsync(\"strong\");\n        await api.ShowToastAsync(\"Bold applied!\");\n    }\n}\n```\n\nBy default, `AllowOverrides = true` lets your items replace built-in ones. Set to `false` to prevent overrides:\n\n```csharp\n// Advanced configuration with options\nbuilder.Services.AddZauberRte(options =\u003e\n{\n    options.AllowOverrides = false;  // Your items won't replace built-ins\n}, typeof(Program).Assembly, typeof(MyPlugin.Class).Assembly);\n```\n\n**[→ Extension Guide](QUICK_START_EXTENDING.md)** - Full documentation with copy-paste templates for toolbar items and custom panels\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyodasmydad%2Fzaubereditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyodasmydad%2Fzaubereditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyodasmydad%2Fzaubereditor/lists"}