A slot that accepts a function receiving the TipexEditor instance, rendered above the
25 | main editor content area
26 |
27 |
28 |
29 |
controlComponent
30 |
31 | Snippet<[TipexEditor]> | null
32 |
33 |
Optional
34 |
35 | A slot that accepts a function receiving the TipexEditor instance, used to completely replace the default controls. Set to null to hide all controls completely.
36 |
37 |
38 |
39 |
40 |
41 |
42 |
undefined
43 |
Optional
44 |
45 | A slot that accepts a function receiving the TipexEditor instance, rendered below the
46 | editor content and controls
47 |
48 |
49 |
50 |
51 |
52 |
55 |
Control System
56 |
57 | Tipex automatically detects which control system to use:
58 |
59 |
60 |
When controlComponent is provided: Uses your custom control component
61 |
62 | When controlComponent is not provided: Shows default controls with built-in utilities
63 |
64 |
65 | When controlComponent={'{null}'}: Hides all controls completely (no toolbar)
66 |
67 |
68 |
69 | This ensures a clean API where you don't need to manage boolean flags.
70 |
I've been working on this new feature for the past few days. It's been quite challenging but I think I'm making good progress. The documentation was a bit outdated so I had to figure out some things on my own.
26 | Tipex provides comprehensive access to TipTap's powerful command system, enabling full
27 | programmatic control over the editor. This guide covers essential commands, advanced techniques,
28 | and best practices for integrating editor functionality into your applications.
29 |
30 |
31 |
Getting Started with Commands
32 |
33 | All commands are accessed through the editor instance. First, ensure you have a reference to the
34 | editor:
35 |
36 |
37 |
38 |
39 |
Content Management
40 |
These commands handle basic content operations:
41 |
42 |
43 |
44 |
Text Formatting
45 |
Apply and remove text formatting with these commands:
46 |
47 |
48 |
49 |
List Management
50 |
Create and manage different types of lists:
51 |
52 |
53 |
54 |
Link Management
55 |
Handle links with validation and custom attributes:
56 |
57 |
58 |
59 |
Image Handling
60 |
Comprehensive image management including uploads, validation, and optimization:
61 |
62 |
63 |
64 |
Selection & Cursor Management
65 |
Control text selection and cursor positioning:
66 |
67 |
68 |
69 |
History & Undo/Redo
70 |
Manage editor history and undo/redo functionality:
71 |
72 |
73 |
74 |
Advanced Command Patterns
75 |
Leverage command chaining and conditional execution for complex operations:
76 |
77 |
78 |
79 |
Custom Commands
80 |
Create your own commands for specialized functionality:
81 |
82 |
83 |
84 |
Event-Driven Commands
85 |
React to editor events and execute commands automatically:
86 |
87 |
88 |
89 |
Best Practices
90 |
91 |
92 | Always chain focus(): Use editor.chain().focus().command().run() to
93 | ensure proper focus management
94 |
95 |
96 | Check command availability: Use editor.can().command() before executing
97 | commands
98 |
99 |
100 | Error handling: Wrap commands in try-catch blocks for production applications
101 |
102 |
103 | Performance: Batch multiple commands using chain() instead of individual
104 | calls
105 |
106 |
107 | State management: Use editor.isActive() to maintain UI state consistency
108 |
109 |
110 | Validation: Always validate user input before executing commands (URLs, file types,
111 | etc.)
112 |
113 |
114 |
115 |
116 |
117 | Complete API Reference: For the full list of available commands and their
118 | parameters, visit the
119 |
125 | official TipTap Commands API Documentation. Tipex provides 100% compatibility with all TipTap commands.
127 |
73 | Tipex is a cutting-edge rich text editor designed specifically for Svelte applications. Built on
74 | the powerful foundations of
75 | TipTap and
76 | ProseMirror,
77 | Tipex provides developers with an intuitive, highly customizable editing experience while
78 | abstracting away the complexity of underlying technologies. Whether you're building a simple blog
79 | or a complex content management system, Tipex scales to meet your needs.
80 |
81 |
82 |
83 |
84 |
Key Features
85 |
86 |
87 | Rich Text Editing: Full support for formatting, links, lists, images, and code blocks
88 |
93 | Svelte Native: Built specifically for Svelte with reactive bindings and modern svelte
94 | 5 runes syntax
95 |
96 |
97 | Accessible: WCAG compliant with keyboard navigation and screen reader support
98 |
99 |
Extensible: Plugin architecture allows for custom functionality
100 |
101 | TypeScript Ready: Full TypeScript support with comprehensive type definitions
102 |
103 |
104 |
105 |
Installation
106 |
107 | Install Tipex from NPM using your preferred package manager.
112 |
113 |
114 |
115 |
Examples & Variants
116 |
117 | Check out Tipex Editor Variants
122 | and its
123 | live preview
124 | for examples showcasing what you can build with Tipex, including multiple themes and configurations.
125 |
126 |
127 |
Quick Start
128 |
129 | Get started with Tipex in just a few lines of code. Import the component and its styles, then use
130 | it in your Svelte application.
131 |
132 |
133 |
134 |
Configuration Options
135 |
Tipex provides several boolean props for quick configuration:
136 |
137 |
138 | floating: Enable/disable the floating selection toolbar (!floating to disable)
139 |
140 |
141 | focal: Enable/disable focus ring styling (!focal to disable)
142 |
143 |
144 |
145 |
Styling & Theming
146 |
147 | Tipex is built with Tailwind CSS v4 and uses the modern `@import "tailwindcss"` syntax
148 | along with the new `@theme` configuration system. Import the CSS file to get started with beautiful,
149 | responsive styling powered by the latest Tailwind architecture.
150 |
151 |
152 |
153 |
154 |
155 | Tailwind v4 Architecture: Tipex leverages Tailwind CSS v4's advanced features including
156 | the new `@theme` configuration, CSS custom properties integration, and the modern import system.
157 | The styles use `@layer components` for organization, CSS custom properties for theming (`--color-tipex-*`),
158 | and the new `@custom-variant` syntax for dark mode handling. This provides superior performance,
159 | better DX, and more flexible customization compared to older Tailwind versions.
160 |
161 |
162 |
163 |
Props & Configuration
164 |
165 | Tipex accepts a comprehensive set of props for customization and configuration. Here are the
166 | available options:
167 |
168 |
169 |
170 |
Editor Instance Access
171 |
172 | Access the TipTap editor instance to programmatically control the editor, execute commands, or
173 | listen to events.
174 |
175 |
176 |
177 | The editor instance provides access to the full TipTap API, including commands for content
178 | manipulation, state management, and event handling. This allows for advanced integrations and
179 | custom functionality.
180 |
181 |
182 |
Advanced Customization
183 |
184 | Tipex is architected with customization at its core. Every aspect of the editor can be tailored to
185 | your needs:
186 |
187 |
188 |
189 | Custom Controls: Replace or extend the default toolbar with your own components
190 |
191 |
192 | Theme Customization: Comprehensive CSS custom properties for colors, spacing, and
193 | typography
194 |
195 |
196 | Extension System: Add new functionality through TipTap's extension architecture
197 |
198 |
Event Handling: React to editor events for custom workflows
199 |
Content Validation: Implement custom validation and sanitization logic
200 |
201 |
202 | Visit the customization guide for
203 | detailed examples and advanced techniques.
204 |
205 |
206 |
Commands & API
207 |
208 | Leverage the powerful command system to programmatically interact with the editor. Tipex provides
209 | full compatibility with TipTap's command API, enabling:
212 |
213 |
214 |
Content insertion and manipulation
215 |
Formatting and styling operations
216 |
Selection and cursor management
217 |
Undo/redo functionality
218 |
Custom command chaining
219 |
220 |
221 | Explore the commands documentation for
222 | comprehensive examples and use cases.
223 |
224 |
225 |
Performance & Accessibility
226 |
Tipex is optimized for performance and accessibility:
227 |
228 |
Lazy Loading: Components and extensions load only when needed
229 |
Virtual Scrolling: Efficient handling of large documents
230 |
ARIA Support: Full screen reader compatibility
231 |
Keyboard Navigation: Complete keyboard control for all features
232 |
Focus Management: Proper focus handling for complex interactions
233 |
234 |
235 |
About Friend Of Svelte
236 |
237 |
242 |
243 | Friend Of Svelte is
244 | a community-driven organization dedicated to creating high-quality, open-source tools and resources
245 | for the Svelte ecosystem. Our mission is to empower developers with exceptional tools that enhance
246 | productivity and developer experience.
247 |
248 |
249 |
250 |
251 | Join our growing community of contributors and help shape the future of Svelte development. We
252 | welcome contributions of all kinds - from code and documentation to feedback and feature requests.
253 |
254 |
255 |
256 |
257 | Developer Story: Learn about the journey of creating Tipex and becoming a
258 | master Svelte developer in our founder's blog.
263 |
264 |
265 |
266 |
268 |
--------------------------------------------------------------------------------
/src/item/codes/commandsCodes.json:
--------------------------------------------------------------------------------
1 | {
2 | "basicEditorSetup": "// Get editor reference\nlet editor: Editor;\n\n// In your component\n\n\n// Now you can use commands\neditor.commands.setContent('
')\neditor.commands.setContent(htmlString, true) // true to emit update event\n\n// Insert content at current cursor position\neditor.commands.insertContent('New content')\neditor.commands.insertContent('
HTML content
')\n\n// Insert content at specific position\neditor.commands.insertContentAt(10, 'Content at position 10')\n\n// Clear all content\neditor.commands.clearContent()\neditor.commands.clearContent(true) // true to emit update event\n\n// Focus the editor\neditor.commands.focus()\neditor.commands.focus('start') // Focus at start\neditor.commands.focus('end') // Focus at end\neditor.commands.focus(10) // Focus at specific position\n\n// Blur (unfocus) the editor\neditor.commands.blur()",
5 |
6 | "textFormatting": "// Basic formatting toggles (all available in enhanced Controls)\neditor.commands.toggleBold()\neditor.commands.toggleItalic()\neditor.commands.toggleUnderline() // Now supported with extension\neditor.commands.toggleStrike()\neditor.commands.toggleCode()\n\n// Set formatting (without toggle)\neditor.commands.setBold()\neditor.commands.setItalic()\neditor.commands.setUnderline()\neditor.commands.unsetBold()\neditor.commands.unsetItalic()\neditor.commands.unsetUnderline()\n\n// Heading management (H1, H2, H3 buttons available)\neditor.commands.toggleHeading({ level: 1 })\neditor.commands.toggleHeading({ level: 2 })\neditor.commands.toggleHeading({ level: 3 })\neditor.commands.setHeading({ level: 1 })\neditor.commands.unsetHeading()\n\n// Paragraph operations\neditor.commands.setParagraph()\n\n// Check active formatting states\nconst isBold = editor.isActive('bold')\nconst isItalic = editor.isActive('italic')\nconst isUnderline = editor.isActive('underline')\nconst isH1 = editor.isActive('heading', { level: 1 })\nconst isH2 = editor.isActive('heading', { level: 2 })",
7 |
8 | "listManagement": "// Toggle list types (all available in enhanced Controls)\neditor.commands.toggleBulletList() // Bullet list button\neditor.commands.toggleOrderedList() // Numbered list button \neditor.commands.toggleTaskList() // Task list button\n\n// Set specific list types\neditor.commands.setBulletList()\neditor.commands.setOrderedList()\neditor.commands.setTaskList()\n\n// List item operations\neditor.commands.splitListItem('listItem')\neditor.commands.sinkListItem('listItem') // Indent\neditor.commands.liftListItem('listItem') // Outdent\n\n// Task list specific\neditor.commands.toggleTask()\neditor.commands.setTaskList()\n\n// Check active list states\nconst isBulletList = editor.isActive('bulletList')\nconst isOrderedList = editor.isActive('orderedList')\nconst isTaskList = editor.isActive('taskList')\n\n// Example: Smart list button with state\nfunction createListButton(listType: 'bulletList' | 'orderedList' | 'taskList') {\n return {\n isActive: () => editor.isActive(listType),\n toggle: () => {\n switch(listType) {\n case 'bulletList':\n editor.chain().focus().toggleBulletList().run()\n break\n case 'orderedList':\n editor.chain().focus().toggleOrderedList().run()\n break\n case 'taskList':\n editor.chain().focus().toggleTaskList().run()\n break\n }\n }\n }\n}",
9 |
10 | "linkManagement": "// Basic link operations\neditor.commands.setLink({ href: 'https://example.com' })\neditor.commands.setLink({ \n href: 'https://example.com',\n target: '_blank',\n rel: 'noopener noreferrer'\n})\neditor.commands.unsetLink()\n\n// Advanced link handling with validation\nfunction setLinkWithValidation(url: string, text?: string) {\n // Validate URL\n if (!url.startsWith('http://') && !url.startsWith('https://')) {\n url = 'https://' + url\n }\n \n try {\n new URL(url) // Validate URL format\n \n if (text) {\n // Insert text with link\n editor.chain()\n .focus()\n .insertContent(`${text}`)\n .run()\n } else {\n // Apply link to selection\n editor.chain()\n .focus()\n .setLink({ \n href: url, \n target: '_blank', \n rel: 'noopener noreferrer' \n })\n .run()\n }\n } catch (error) {\n console.error('Invalid URL:', url)\n }\n}\n\n// Check if current selection/cursor is in a link\nconst isLinkActive = editor.isActive('link')\nconst linkAttributes = editor.getAttributes('link') // Get href, target, etc.",
11 |
12 | "imageHandling": "// Basic image insertion\neditor.commands.setImage({\n src: 'https://example.com/image.jpg',\n alt: 'Description',\n title: 'Image title'\n})\n\n// Handle file uploads with validation\nasync function handleImageUpload(file: File) {\n // Validate file type\n const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']\n if (!allowedTypes.includes(file.type)) {\n throw new Error('Unsupported file type')\n }\n \n // Validate file size (e.g., 5MB limit)\n const maxSize = 5 * 1024 * 1024\n if (file.size > maxSize) {\n throw new Error('File too large')\n }\n \n try {\n // Option 1: Upload to server\n const formData = new FormData()\n formData.append('image', file)\n \n const response = await fetch('/api/upload', {\n method: 'POST',\n body: formData\n })\n \n if (!response.ok) throw new Error('Upload failed')\n \n const { url, alt } = await response.json()\n \n editor.commands.setImage({\n src: url,\n alt: alt || file.name,\n title: file.name\n })\n \n } catch (error) {\n console.error('Image upload failed:', error)\n \n // Option 2: Fallback to base64 for small images\n if (file.size < 1024 * 1024) { // 1MB limit for base64\n const reader = new FileReader()\n reader.onload = (e) => {\n editor.commands.setImage({\n src: e.target?.result as string,\n alt: file.name,\n title: file.name\n })\n }\n reader.readAsDataURL(file)\n }\n }\n}\n\n// Handle paste events for images\neditor.on('paste', (event) => {\n const items = event.clipboardData?.items\n if (!items) return\n \n for (const item of items) {\n if (item.type.startsWith('image/')) {\n const file = item.getAsFile()\n if (file) {\n handleImageUpload(file)\n event.preventDefault()\n }\n }\n }\n})",
13 |
14 |
15 | "blockElements": "// Block elements (all available in enhanced Controls)\neditor.commands.toggleBlockquote() // Quote button\neditor.commands.toggleCodeBlock() // Code block button\neditor.commands.setHorizontalRule() // Horizontal rule button\n\n// Set specific block types\neditor.commands.setBlockquote()\neditor.commands.setCodeBlock()\neditor.commands.setCodeBlock({ language: 'javascript' })\n\n// Check active block states\nconst isBlockquote = editor.isActive('blockquote')\nconst isCodeBlock = editor.isActive('codeBlock')\n\n// Advanced block operations\neditor.commands.wrapIn('blockquote')\neditor.commands.lift('blockquote')\n\n// Insert dividers and breaks\neditor.commands.setHorizontalRule()\neditor.commands.setHardBreak()\n\n// Code block with language\neditor.chain()\n .focus()\n .toggleCodeBlock({ language: 'typescript' })\n .run()",
16 |
17 | "selectionManagement": "// Selection operations\neditor.commands.selectAll()\neditor.commands.selectTextblockStart()\neditor.commands.selectTextblockEnd()\neditor.commands.selectNodeForward()\neditor.commands.selectNodeBackward()\n\n// Set selection to specific range\neditor.commands.setTextSelection({ from: 0, to: 10 })\neditor.commands.setTextSelection(5) // Set cursor at position 5\n\n// Delete operations\neditor.commands.deleteSelection()\neditor.commands.deleteRange({ from: 0, to: 10 })\neditor.commands.deleteCurrentNode()\n\n// Navigation\neditor.commands.goToNext()\neditor.commands.goToPrevious()",
18 |
19 | "historyManagement": "// Undo/Redo operations (buttons available in enhanced Controls)\neditor.commands.undo() // Undo button with smart disabled state\neditor.commands.redo() // Redo button with smart disabled state\n\n// Check if undo/redo is available\nconst canUndo = editor.can().undo()\nconst canRedo = editor.can().redo()\n\n// Clear history\neditor.commands.clearHistory()\n\n// The enhanced Controls component automatically handles:\n// - Button disabled states based on availability\n// - Visual feedback for enabled/disabled buttons\n// - Proper ARIA labels for accessibility\n\n// Custom undo/redo buttons (if building custom controls)\nfunction createHistoryButton(type: 'undo' | 'redo') {\n return {\n canExecute: () => type === 'undo' ? editor.can().undo() : editor.can().redo(),\n execute: () => type === 'undo' ? editor.commands.undo() : editor.commands.redo(),\n isDisabled: () => type === 'undo' ? !editor.can().undo() : !editor.can().redo()\n }\n}",
20 |
21 | "advancedCommands": "// Command chaining for complex operations\neditor.chain()\n .focus()\n .toggleBold()\n .toggleItalic()\n .setTextAlign('center')\n .run()\n\n// Conditional command execution\nif (editor.isActive('bold')) {\n editor.chain().focus().unsetBold().setItalic().run()\n} else {\n editor.chain().focus().setBold().run()\n}\n\n// Check if command can be executed\nconst canToggleBold = editor.can().toggleBold()\nconst canSetHeading = editor.can().setHeading({ level: 2 })\n\n// Custom command wrapper with error handling\nfunction safeCommand(command: () => boolean) {\n try {\n const result = command()\n if (!result) {\n console.warn('Command execution failed')\n }\n return result\n } catch (error) {\n console.error('Command error:', error)\n return false\n }\n}\n\n// Usage\nsafeCommand(() => editor.chain().focus().toggleBold().run())\n\n// Batch operations with transaction\neditor.chain()\n .command(({ tr }) => {\n // Custom transaction operations\n tr.insertText('Hello')\n tr.addMark(0, 5, editor.schema.marks.bold.create())\n return true\n })\n .run()",
22 |
23 | "customCommands": "// Define custom command\nconst customCommand = () => ({ commands }: { commands: any }) => {\n return commands.insertContent('Custom content inserted!')\n}\n\n// Register and use custom command\neditor.commands.customCommand = customCommand()\neditor.commands.customCommand()\n\n// More complex custom command\nconst insertCurrentDate = () => ({ commands }: { commands: any }) => {\n const date = new Date().toLocaleDateString()\n return commands.insertContent(`
Today is ${date}
`)\n}\n\n// Smart formatting command\nconst smartFormat = (text: string) => ({ commands }: { commands: any }) => {\n // Auto-detect and apply formatting\n if (text.startsWith('# ')) {\n return commands.setHeading({ level: 1 })\n } else if (text.startsWith('## ')) {\n return commands.setHeading({ level: 2 })\n } else if (text.startsWith('- ')) {\n return commands.setBulletList()\n }\n return commands.setParagraph()\n}",
24 |
25 | "eventDrivenCommands": "// Listen to editor events and execute commands\neditor.on('update', ({ editor }) => {\n // Auto-save functionality\n const content = editor.getHTML()\n localStorage.setItem('editor-content', content)\n})\n\neditor.on('selectionUpdate', ({ editor }) => {\n // Update UI based on selection\n const { from, to } = editor.state.selection\n console.log(`Selection: ${from} to ${to}`)\n})\n\n// Custom keyboard shortcuts with commands\neditor.on('keydown', (event) => {\n // Custom Ctrl+Shift+D for current date\n if (event.ctrlKey && event.shiftKey && event.key === 'D') {\n event.preventDefault()\n editor.commands.insertContent(`
${new Date().toLocaleDateString()}
`)\n }\n \n // Auto-format on Enter\n if (event.key === 'Enter') {\n const { $from } = editor.state.selection\n const currentLine = $from.parent.textContent\n \n if (currentLine.startsWith('# ')) {\n setTimeout(() => {\n editor.commands.setHeading({ level: 1 })\n }, 0)\n }\n }\n})"
26 | }
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tipex
2 |
3 | Tipex stands as an advanced rich text editor tailored for Svelte, meticulously engineered with the robust
4 | frameworks [Tiptap](https://tiptap.dev/) and [Prosemirror](https://prosemirror.net/). It empowers developers to
5 | effortlessly craft rich text editors, liberating them from the intricacies of underlying technologies, style management,
6 | and related complexities.
7 |
8 | > Svelte 5 and runes mode activated! ✨🔮
9 |
10 | ## Key Features
11 |
12 | - 🚀 **Svelte 5 Ready**: Built with Svelte 5's latest features including runes, snippets, and modern reactivity
13 | - 🎨 **Smart Control System**: Automatically detects whether to show default or custom controls based on `controlComponent` prop
14 | - 🔌 **Extensible Architecture**: Fully extensible through Tiptap's extension system with default extensions included
15 | - 📱 **Mobile Responsive**: Optimized for both desktop and mobile with touch-friendly interactions
16 | - 🎯 **Context-Aware Floating Menu**: Intelligent floating toolbar that appears on text selection
17 | - 🔗 **Advanced Link Management**: Built-in link editing with clipboard integration and visual feedback
18 | - ✅ **Task Lists**: Native support for interactive checkboxes and task management
19 | - 🎭 **Modern Theming**: Built with Tailwind CSS v4 using OKLCH colors and CSS custom properties
20 | - ⚡ **Performance Optimized**: Leverages Svelte's reactivity and efficient DOM updates
21 | - 💼 **Full TypeScript Support**: Complete type safety with comprehensive type definitions
22 | - 🎨 **Focus Management**: Smart focus detection with visual feedback and accessibility support
23 |
24 | ## Installation
25 |
26 | Install the package from [NPM](https://www.npmjs.com/package/@friendofsvelte/tipex):
27 |
28 | ```bash
29 | npm install "@friendofsvelte/tipex"
30 | ```
31 |
32 | Check out [Tipex Editor Variants](https://github.com/Bishwas-py/tipex-editor-variants) and its [live preview](https://tipex-editor-variants.pages.dev/) for examples showcasing what you can build with the Tipex Svelte text editor, including multiple themes and configurations.
33 |
34 | ## Basic Usage
35 |
36 | Import the component and styles, then use it in your Svelte component:
37 |
38 | ```svelte
39 |
56 |
57 |
64 | ```
65 |
66 | ## Core Concepts
67 |
68 | ### Control System
69 |
70 | Tipex features a simple and flexible control system:
71 |
72 | 1. **Default Controls** (automatic when no `controlComponent` is provided):
73 | - Pre-built formatting toolbar with essential editing tools
74 | - Built-in utility buttons (copy, link management)
75 | - Perfect for quick implementation
76 |
77 | 2. **Custom Controls** (when `controlComponent` snippet is provided):
78 | - Full control over the editor interface
79 | - Complete customization freedom
80 | - Can extend default controls or create entirely new interfaces
81 | - Ideal for specialized use cases
82 |
83 | 3. **No Controls** (when `controlComponent={null}` is explicitly set):
84 | - Completely hides all control elements
85 | - Provides a clean, minimal editor interface
86 | - Perfect for read-only or embedded scenarios
87 |
88 | This simple approach provides maximum flexibility while maintaining ease of use.
89 |
90 | ### Extension System
91 |
92 | Tipex leverages Tiptap's extension system for enhanced functionality. It comes with sensible defaults but you can extend or override them:
93 |
94 | ```svelte
95 |
114 |
115 |
116 | ```
117 |
118 | ### Floating Menu
119 |
120 | The floating menu provides context-aware formatting options that appear when text is selected:
121 |
122 | ```svelte
123 |
124 | ```
125 |
126 | ### Focus Management
127 |
128 | Tipex includes smart focus detection with visual feedback:
129 |
130 | ```svelte
131 |
132 |
133 | ```
134 |
135 | ## Modern Theming with Tailwind CSS v4
136 |
137 | Tipex is built with **Tailwind CSS v4** and uses modern OKLCH colors for better color accuracy and consistency. The theming system uses CSS custom properties that you can override:
138 |
139 | ```css
140 | @import '@friendofsvelte/tipex/styles/index.css';
141 |
142 | @theme {
143 | /* Override Tipex colors */
144 | --color-tipex-primary-500: oklch(0.65 0.11 285); /* Custom purple */
145 | --color-tipex-success-500: oklch(0.647 0.208 142.425); /* Custom green */
146 |
147 | /* Custom spacing */
148 | --spacing-tipex-md: 1.25rem;
149 | --spacing-tipex-lg: 2rem;
150 | }
151 | ```
152 |
153 | ### Available CSS Custom Properties
154 |
155 | - **Colors**: `--color-tipex-{50-950}`, `--color-tipex-primary-{50-950}`, `--color-tipex-success-{50-950}`
156 | - **Spacing**: `--spacing-tipex-{xs,sm,md,lg,xl,2xl}`
157 | - **Sizing**: `--size-tipex-{1-12}`
158 | - **Typography**: `--text-tipex-{xs,sm,base,lg,xl,2xl}`
159 | - **Border Radius**: `--radius-tipex-{sm,md}`
160 | - **Z-Index**: `--z-tipex-{floating,controls}`
161 |
162 | ## Advanced Usage
163 |
164 | ### Custom Head and Foot Sections
165 |
166 | Add custom components above or below the editor using Svelte 5 snippets:
167 |
168 | ```svelte
169 |
174 |
175 |
176 | {#snippet head(editor)}
177 |
178 | {/snippet}
179 |
180 | {#snippet foot(editor)}
181 |
182 | {/snippet}
183 |
184 | ```
185 |
186 | ### Extending Default Controls
187 |
188 | Add custom utilities while keeping the default toolbar:
189 |
190 | ```svelte
191 |
196 |
197 |
198 | {#snippet controlComponent(tipex)}
199 |
200 |
201 |
202 |
205 |
206 | {/snippet}
207 |
208 | ```
209 |
210 | ### Custom Control Component
211 |
212 | Create a completely custom control interface:
213 |
214 | ```svelte
215 |
220 |
221 |
222 | {#snippet controlComponent(tipex)}
223 |
224 |
227 |
230 |
233 |
234 | {/snippet}
235 |
236 | ```
237 |
238 | ### No Controls (Minimal Editor)
239 |
240 | Hide all controls for a clean, minimal editor interface:
241 |
242 | ```svelte
243 |
248 |
249 |
250 |
251 | ```
252 |
253 | ## Props & Configuration
254 |
255 | Based on the actual `TipexProps` interface, here are all available properties:
256 |
257 | | Prop | Type | Default | Description |
258 | |------|------|---------|-------------|
259 | | `body` | `string` | `''` | Initial HTML content for the editor |
260 | | `tipex` | `TipexEditor` (bindable) | `undefined` | The editor instance - bind to access editor methods |
261 | | `extensions` | `AnyExtension[]` (bindable) | `defaultExtensions` | Array of Tiptap extensions to use |
262 | | `floating` | `boolean` | `false` | Enable floating menu on text selection |
263 | | `focal` | `boolean` | `true` | Enable focus ring styling |
264 | | `focused` | `boolean` (bindable) | `false` | Whether the editor is currently focused |
265 | | `autofocus` | `boolean` | `true` | Auto-focus the editor on mount |
266 | | `class` | `string` | `''` | Additional CSS classes for the editor container |
267 | | `style` | `string` | `''` | Inline styles for the editor container |
268 | | `ctxId` | `string` | `'_tipex'` | Context ID for the editor instance |
269 | | `head` | `Snippet<[TipexEditor]>` | `undefined` | Content rendered above the editor |
270 | | `foot` | `Snippet<[TipexEditor]>` | `undefined` | Content rendered below the editor |
271 | | `controlComponent` | `Snippet<[TipexEditor]> \| null` | `undefined` | Custom control component (replaces default controls). Set to `null` to hide all controls. |
272 | | `oncreate` | `(props: EditorEvents['create']) => void` | `() => {}` | Callback when editor is created |
273 | | `ondestroy` | `(props: EditorEvents['destroy']) => void` | `() => {}` | Callback when editor is destroyed |
274 | | `onupdate` | `(props: EditorEvents['update']) => void` | `() => {}` | Callback when editor content updates |
275 |
276 | ### Boolean Props with Negation
277 |
278 | You can disable boolean props using the `!` prefix:
279 |
280 | ```svelte
281 |
282 | ```
283 |
284 | ## Getting Editor Content
285 |
286 | Access the editor instance and its content using Svelte 5 runes:
287 |
288 | ```svelte
289 |
307 |
308 |
309 |
310 |
311 |
Words: {wordCount}
312 |
Characters: {textContent.length}
313 |
314 |
315 |
316 | HTML Output
317 |
{htmlContent}
318 |
319 | ```
320 |
321 | ## Documentation
322 |
323 | For comprehensive documentation, visit [tipex.pages.dev](https://tipex.pages.dev/).
324 |
325 | ## About Friend Of Svelte
326 |
327 | 
328 |
329 | [Friend Of Svelte](https://github.com/friendofsvelte) is a community-driven project to help Svelte developers find and
330 | develop awesome Svelte resources. Our mission is to create high-quality, maintainable, and accessible tools for the
331 | Svelte ecosystem.
332 |
333 | ### Join the Community
334 |
335 | - 🌟 Star our repositories
336 | - 🤝 Contribute to projects
337 | - 📢 Share your ideas
338 | - 👥 Open memberships for everyone
339 |
340 | If you like this project, you can be one of the friends by contributing to the project. Memberships are open for
341 | everyone.
342 |
343 | ## License
344 |
345 | MIT Licensed. Copyright (c) 2023-2024 Friend of Svelte.
346 |
--------------------------------------------------------------------------------
/src/routes/customization/+page.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | Customization Guide | Tipex Editor
12 |
16 |
17 |
18 |
22 |
23 | Back to Home
24 |
25 |
26 |
Customization Guide
27 |
28 | Tipex is architected with customization as a core principle. Every aspect of the editor can be
29 | tailored to match your application's design system and functional requirements. This comprehensive
30 | guide covers everything from basic styling to advanced extension development.
31 |
32 |
33 |
Quick Customization Overview
34 |
Tipex offers multiple layers of customization:
35 |
36 |
Theme Customization: Colors, spacing, typography, and visual styling
37 |
38 | Component Replacement: Replace built-in controls with your own components
39 |
40 |
Extension System: Add new functionality through TipTap extensions
41 |
Event Handling: Custom behavior through event listeners
42 |
Layout Customization: Header, footer, and utility area modifications
43 |
44 |
45 |
Theme & Styling Customization
46 |
47 | Tipex uses Tailwind CSS v4 with the modern `@theme` configuration system and CSS custom
48 | properties for comprehensive theming. You can override any aspect of the visual design using the new
49 | Tailwind v4 architecture:
50 |
51 |
52 |
53 |
54 |
Control Component Customization
55 |
56 |
57 | Tipex provides a single, flexible way to customize the editor controls through the
58 | `controlComponent` slot. You can either extend the default controls with custom utilities or
59 | completely replace them with your own implementation.
60 |
Include the default controls and utility buttons (copy, link management) in your editor:
73 |
74 |
75 |
Extending Default Controls with Custom Utilities
76 |
Add your own custom buttons alongside the built-in utilities:
77 |
78 |
79 |
Here's a more comprehensive example with multiple custom utilities:
80 |
81 |
82 |
83 |
84 |
85 |
Complete Control Replacement
86 |
Replace the entire control system with your own custom implementation:
87 |
88 |
89 |
Here's a complete custom control implementation:
90 |
91 |
92 |
93 |
⚠️ Tailwind v4 ONLY - No Legacy Versions!
94 |
95 | IMPORTANT: Tipex exclusively uses and
96 | requires Tailwind CSS v4. We do NOT support older versions (v1.x, v2.x, v3.x) as
97 | they lack the modern architecture required for Tipex's advanced theming system.
98 |
99 |
100 |
101 |
102 |
103 |
105 |
106 |
107 |
108 | Legacy Tailwind Versions Not Supported
109 |
110 |
111 |
112 |
Tailwind v3.x and older lack @theme configuration
113 |
Missing @custom-variant syntax for advanced dark mode
114 |
Inferior performance and larger bundle sizes
115 |
Limited component layer organization
116 |
117 |
118 |
119 |
120 |
121 |
122 |
Tailwind v4 Advantages
123 |
Tipex exclusively uses Tailwind CSS v4 for superior developer experience and performance:
124 |
125 |
126 | 🚀 Modern Import System: Clean `@import "tailwindcss"` syntax without configuration
127 | files
128 |
129 |
130 | 🎨 Native CSS Custom Properties: Direct integration with CSS variables in `@theme`
131 | blocks
132 |
133 |
134 | ⚡ Better Performance: Faster builds and smaller bundle sizes compared to v3.x
135 |
136 |
🛠️ Enhanced DX: Improved IntelliSense and better error messages
137 |
138 | 🌙 Custom Variants: Powerful `@custom-variant` syntax for complex state handling
139 |
140 |
141 | 📦 Component Layers: Better organization with `@layer components` for maintainable
142 | styles
143 |
144 |
🔮 Future-Proof: Built for modern CSS features and browser capabilities
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
Tailwind v4 Required
154 |
155 | Upgrade to Tailwind v4 immediately for the best Tipex experience. The new architecture is
156 | essential for Tipex's theming system to function properly.
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 | Migration Note: If you're using older Tailwind versions (v1.x, v2.x, v3.x), you
165 | MUST upgrade to Tailwind v4 for Tipex to work correctly. The new architecture provides significantly
166 | better performance, developer experience, and maintainability.
167 |
168 |
169 |
170 |
Advanced Layout Customization
171 |
Tipex supports comprehensive layout customization through multiple slot areas:
172 |
173 |
174 |
175 |
Here's a practical example with a custom header featuring document statistics:
176 |
177 |
178 |
179 |
Image Upload Customization
180 |
181 | Tipex provides flexible image handling. You can customize the upload process, validation, and
182 | storage:
183 |
184 |
185 |
186 |
187 |
Extension System
188 |
189 |
190 | Leverage TipTap's powerful extension system to add custom functionality. Tipex provides easy
191 | access to modify and extend the editor's capabilities:
192 |
Customize the built-in extensions to match your requirements:
215 |
216 |
217 |
218 |
Creating Custom Extensions
219 |
Build your own extensions for specialized functionality:
220 |
221 |
222 |
223 |
Event-Driven Customization
224 |
React to editor events for dynamic behavior and integrations:
225 |
226 |
227 |
228 |
Accessibility Customization
229 |
230 | Enhance accessibility with custom ARIA labels, keyboard navigation, and screen reader support:
231 |
232 |
233 |
234 |
235 |
Performance Optimization with Tailwind v4
236 |
Optimize your customized editor using Tailwind v4's performance benefits:
237 |
238 |
239 |
🎯 Tailwind v4 Tree Shaking: Automatic unused CSS elimination
240 |
⚡ Faster Builds: Improved build performance over legacy versions
241 |
📦 Smaller Bundles: More efficient CSS generation
242 |
🔄 Lazy Loading: Load extensions and components only when needed
243 |
⏱️ Debounced Updates: Throttle auto-save and real-time features
244 |
🖥️ Virtual Scrolling: For large documents, implement virtual scrolling
245 |
🧠 Memory Management: Clean up event listeners and subscriptions
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 | Tailwind v4 Performance Benefits
256 |
257 |
258 | Tailwind v4's modern architecture provides up to 50% faster builds and 30% smaller CSS
259 | bundles compared to v3.x, making your Tipex editor load faster and perform better.
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 | Best Practices with Tailwind v4: When customizing Tipex, leverage Tailwind v4's
268 | `@layer components`, `@theme` configuration, and `@custom-variant` features. Always test your changes
269 | across different devices and browsers. The modern Tailwind v4 architecture ensures better performance
270 | and maintainability compared to legacy versions.
271 |
272 |
273 |
274 |
Advanced Tailwind v4 Theming
275 |
276 | Create sophisticated themes using Tailwind v4's advanced features. Here's a complete example of a
277 | premium theme configuration:
278 |
279 |
280 |
281 |
282 |
283 | This example demonstrates Tailwind v4's powerful theming capabilities including gradient
284 | backgrounds, advanced shadows, custom scrollbars, and sophisticated component styling that would
285 | be much more complex in older Tailwind versions.
286 |
287 |
288 |
289 |
290 | 🚫 Why Tailwind v4 Only: Tipex exclusively supports and promotes Tailwind CSS
291 | v4 because it represents the future of utility-first CSS. The new architecture provides native
292 | CSS custom property integration, better performance, improved developer experience, and more
293 | maintainable code. We strongly discourage and do NOT support using older Tailwind versions
294 | (v1.x, v2.x, v3.x) as they lack the modern features that make Tipex's theming system possible.
295 |
296 | ⚠️ Legacy Tailwind Warning: Attempting to
297 | use Tipex with older Tailwind versions will result in broken styling, missing features, and poor
298 | performance. Upgrade to Tailwind v4 immediately.
299 |