{"id":35659436,"url":"https://github.com/maifeeulasad/lilac","last_synced_at":"2026-04-25T11:03:51.496Z","repository":{"id":307785402,"uuid":"1030208250","full_name":"maifeeulasad/lilac","owner":"maifeeulasad","description":"lilac: A smooth and elegant WYSIWYG editor for effortless writing","archived":false,"fork":false,"pushed_at":"2026-04-01T21:05:19.000Z","size":1335,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-02T05:30:58.628Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://maifeeulasad.github.io/lilac/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/maifeeulasad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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-08-01T09:02:21.000Z","updated_at":"2026-04-01T21:04:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"599f579e-d5ea-42aa-b301-278e9b2dad87","html_url":"https://github.com/maifeeulasad/lilac","commit_stats":null,"previous_names":["maifeeulasad/lilac"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/maifeeulasad/lilac","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maifeeulasad%2Flilac","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maifeeulasad%2Flilac/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maifeeulasad%2Flilac/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maifeeulasad%2Flilac/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maifeeulasad","download_url":"https://codeload.github.com/maifeeulasad/lilac/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maifeeulasad%2Flilac/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31317831,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T21:35:00.834Z","status":"ssl_error","status_checked_at":"2026-04-02T21:34:59.806Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-05T16:17:06.497Z","updated_at":"2026-04-25T11:03:51.488Z","avatar_url":"https://github.com/maifeeulasad.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lilac Editor\n\n\u003e A smooth, modern WYSIWYG text editor built with TypeScript. Framework-agnostic core with adapters for React, Svelte, Angular, Vue, and Vanilla JS.\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![Zero Dependencies](https://img.shields.io/badge/Dependencies-Zero-brightgreen?style=for-the-badge)]()\n[![Framework Agnostic](https://img.shields.io/badge/Framework-Agnostic-blue?style=for-the-badge)]()\n\n## Architecture\n\nLilac follows an **adapter pattern** for maximum framework compatibility. The core functionality is isolated from framework-specific implementations, ensuring consistent behavior across all platforms.\n\n```\nlilac/\n├── core/                    # Framework-agnostic core\n│   ├── types/               # TypeScript type definitions\n│   ├── plugins/              # Plugin system (emoji, table, word count)\n│   ├── utils/                # Utility functions (formatting, icons)\n│   ├── components/           # Core components (Editor, Toolbar)\n│   └── index.ts              # Core exports\n├── adapter/                  # Framework-specific adapters\n│   ├── react/                # React component wrapper\n│   ├── svelte/               # Svelte component\n│   ├── angular/              # Angular component/directive\n│   ├── vue/                  # Vue component\n│   └── vanilla/              # Vanilla JS wrapper\n└── docs/                     # Documentation \u0026 demos\n```\n\n### Core Design Principles\n\n1. **UI Instructions in Core**: The core package contains all UI styling instructions to ensure consistent appearance across all framework adapters\n2. **Framework-Agnostic Logic**: Business logic and state management are kept framework-independent\n3. **Adapter Pattern**: Each framework gets its own adapter that bridges the core with framework-specific patterns\n\n## Features\n\n- **Framework-Agnostic Core**: Pure TypeScript implementation with no dependencies\n- **Consistent UI**: Centralized UI instructions ensure identical styling across all adapters\n- **Plugin System**: Extensible architecture with built-in plugins for emojis, tables, and word count\n- **Rich Text Formatting**: Bold, italic, underline, strikethrough, headings, lists, blockquotes, code blocks\n- **Media Support**: Link and image insertion with keyboard shortcuts\n- **Keyboard Shortcuts**: Ctrl/Cmd + B for bold, Ctrl/Cmd + I for italic, etc.\n- **Undo/Redo**: Full history support with 50-step undo stack\n- **Theme Support**: Light and dark themes with CSS custom properties\n- **Accessibility**: WCAG compliant with ARIA labels and keyboard navigation\n- **Plugin API**: Create custom plugins with toolbar buttons, keyboard shortcuts, and lifecycle hooks\n\n## Installation\n\n### Core (Vanilla JS / TypeScript)\n\n```bash\nnpm install @lilac-wysiwyg/core\npnpm add @lilac-wysiwyg/core\nyarn add @lilac-wysiwyg/core\n```\n\n### Framework Adapters\n\n```bash\n# React\nnpm install @lilac-wysiwyg/react\n\n# Svelte\nnpm install @lilac-wysiwyg/svelte\n\n# Angular\nnpm install @lilac-wysiwyg/angular\n\n# Vue\nnpm install @lilac-wysiwyg/vue\n```\n\n## Quick Start\n\n### Vanilla JS / TypeScript (Core)\n\n```typescript\nimport { LilacEditor, injectStyles } from '@lilac-wysiwyg/core';\n\n// Inject required styles (only needed once per page)\ninjectStyles();\n\n// Create editor instance\nconst editor = new LilacEditor({\n  container: document.getElementById('editor')!,\n  toolbar: { show: true },\n  placeholder: 'Start writing...',\n  onChange: (content) =\u003e {\n    console.log('Content:', content);\n  }\n});\n\n// Get content\nconst content = editor.getContent();\n\n// Set content\neditor.setContent('\u003cp\u003eHello World!\u003c/p\u003e');\n```\n\n### React\n\n```tsx\nimport { LilacEditor } from '@lilac-wysiwyg/react';\nimport '@lilac-wysiwyg/react/styles';\n\nfunction App() {\n  const [content, setContent] = useState('\u003cp\u003eHello!\u003c/p\u003e');\n\n  return (\n    \u003cLilacEditor\n      value={content}\n      onChange={setContent}\n      toolbar={{ show: true }}\n      placeholder=\"Start writing...\"\n    /\u003e\n  );\n}\n```\n\n### Vue 3\n\n```vue\n\u003ctemplate\u003e\n  \u003cLilacEditor\n    v-model=\"content\"\n    :toolbar=\"{ show: true }\"\n    placeholder=\"Start writing...\"\n  /\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { ref } from 'vue';\nimport { LilacEditor } from '@lilac-wysiwyg/vue';\n\nconst content = ref('\u003cp\u003eHello!\u003c/p\u003e');\n\u003c/script\u003e\n```\n\n## Using Built-in Plugins\n\n```typescript\nimport { \n  LilacEditor, \n  injectStyles,\n  pluginManager,\n  wordCountPlugin,\n  emojiPlugin,\n  tablePlugin\n} from '@lilac-wysiwyg/core';\n\ninjectStyles();\n\n// Install plugins\npluginManager.install(wordCountPlugin);\npluginManager.install(emojiPlugin);\npluginManager.install(tablePlugin);\n\nconst editor = new LilacEditor({\n  container: document.getElementById('editor')!,\n  toolbar: { show: true },\n  onChange: (content) =\u003e console.log('Content:', content)\n});\n```\n\n## API Reference\n\n### LilacEditor Constructor Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `container` | `HTMLElement` | **required** | DOM element to mount the editor |\n| `initialContent` | `string` | `''` | Initial HTML content of the editor |\n| `placeholder` | `string` | `'Start writing...'` | Placeholder text when editor is empty |\n| `readOnly` | `boolean` | `false` | Whether the editor is read-only |\n| `autoFocus` | `boolean` | `false` | Auto-focus editor on mount |\n| `theme` | `'light' \\| 'dark'` | `'light'` | Editor theme |\n| `onChange` | `(content: string) =\u003e void` | `undefined` | Content change callback |\n| `onFocus` | `() =\u003e void` | `undefined` | Focus event callback |\n| `onBlur` | `() =\u003e void` | `undefined` | Blur event callback |\n| `toolbar` | `ToolbarConfig` | `undefined` | Toolbar configuration |\n| `plugins` | `EditorPlugin[]` | `[]` | Plugins to install |\n\n### LilacEditor Methods\n\n| Method | Description |\n|--------|-------------|\n| `getContent()` | Get current editor HTML content |\n| `setContent(content)` | Set editor content |\n| `focus()` | Focus the editor |\n| `blur()` | Blur the editor |\n| `undo()` | Undo last change |\n| `redo()` | Redo last undone change |\n| `setReadOnly(readOnly)` | Enable/disable read-only mode |\n| `destroy()` | Clean up and remove the editor |\n\n### Toolbar Tools\n\n| Tool | Keyboard Shortcut |\n|------|-----------------|\n| Bold | Ctrl/Cmd + B |\n| Italic | Ctrl/Cmd + I |\n| Underline | Ctrl/Cmd + U |\n| Strikethrough | - |\n| Heading 1-3 | - |\n| Paragraph | - |\n| Bullet List | - |\n| Ordered List | - |\n| Blockquote | - |\n| Code Block | - |\n| Link | Ctrl/Cmd + K |\n| Image | - |\n\n## Plugin System\n\nLilac features a powerful plugin system that allows extending the editor with custom functionality.\n\n### Built-in Plugins\n\n- **Word Count Plugin**: Displays real-time document statistics (Ctrl+Shift+W)\n- **Emoji Picker Plugin**: Insert emojis with an easy-to-use picker (Ctrl+Shift+E)\n- **Table Inserter Plugin**: Insert and manage HTML tables (Ctrl+Shift+T)\n\n### Creating Custom Plugins\n\n```typescript\nimport type { EditorPlugin } from '@lilac-wysiwyg/core';\n\nexport const myCustomPlugin: EditorPlugin = {\n  id: 'my-custom-plugin',\n  name: 'My Custom Plugin',\n  version: '1.0.0',\n\n  // Toolbar buttons\n  toolbarButtons: [{\n    id: 'my-button',\n    icon: '\u003csvg\u003e...\u003c/svg\u003e',\n    label: 'My Tool',\n    tooltip: 'My custom tool',\n    onClick: (context) =\u003e {\n      context.insertContent('\u003cstrong\u003eCustom!\u003c/strong\u003e');\n    },\n  }],\n\n  // Keyboard shortcuts\n  keyboardShortcuts: [{\n    key: 'm',\n    ctrlKey: true,\n    action: (context) =\u003e {\n      context.insertContent('\u003cem\u003eShortcut!\u003c/em\u003e');\n    },\n  }],\n\n  // Lifecycle hooks\n  onInstall: (context) =\u003e console.log('Installed'),\n  onEditorMount: (context) =\u003e console.log('Ready'),\n  onContentChange: (content, context) =\u003e {\n    // React to content changes\n  },\n};\n```\n\n## Customization\n\n### Themes\n\nOverride CSS custom properties to create custom themes:\n\n```css\n.lilac-editor {\n  --lilac-color-primary: #your-color;\n  --lilac-color-background: #your-bg;\n  --lilac-border-radius: 8px;\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\npnpm install\n\n# Build core library\npnpm build\n\n# Watch for changes\npnpm dev\n\n# Type check\npnpm typecheck\n```\n\n## Documentation\n\nVisit our [GitHub Pages](https://maifeeulasad.github.io/lilac/) for complete documentation and live demos for each framework adapter.\n\n## Roadmap\n\n- [x] Rich text toolbar with all formatting options\n- [x] Plugin system with built-in plugins\n- [x] Emoji picker\n- [x] Table inserter\n- [x] Word count plugin\n- [x] React adapter\n- [x] Svelte adapter\n- [ ] Angular adapter\n- [ ] Vue adapter\n- [ ] Markdown export/import\n- [ ] Image upload and embedding\n- [ ] Find and replace\n- [ ] Mobile optimizations\n\n## Contributing\n\nWe welcome contributions! Please see our Contributing Guide for details.\n\n## License\n\nMIT License - See [LICENSE](LICENSE) for details.\n\n## Author\n\nMaifee Ul Asad \u003cmaifeeulasad@gmail.com\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003eMade with by \u003ca href=\"https://github.com/maifeeulasad\"\u003emaifeeulasad\u003c/a\u003e\u003c/p\u003e\n  \u003cp\u003eIf you find this project useful, please star us on GitHub!\u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaifeeulasad%2Flilac","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaifeeulasad%2Flilac","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaifeeulasad%2Flilac/lists"}