@mdaemon/html-editor 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,16 +13,14 @@ npm install @mdaemon/html-editor
13
13
  ### Vanilla JavaScript/TypeScript
14
14
 
15
15
  ```typescript
16
- import { HTMLEditor, setTranslate } from '@mdaemon/html-editor';
16
+ import { HTMLEditor } from '@mdaemon/html-editor';
17
17
  import '@mdaemon/html-editor/styles';
18
18
 
19
- // Optional: Set up translation function
20
- setTranslate((key) => myTranslationFunction(key));
21
-
22
- // Create editor
19
+ // Create editor with built-in language support
23
20
  const container = document.getElementById('editor');
24
21
  const editor = new HTMLEditor(container, {
25
22
  height: 400,
23
+ language: 'de', // German UI — see Localization section for supported codes
26
24
  basicEditor: false, // Full toolbar
27
25
  includeTemplates: true,
28
26
  templates: [
@@ -81,15 +79,44 @@ const editor = new HTMLEditor(container, {
81
79
  | `templates` | Template[] | [] | Array of templates |
82
80
  | `dropbox` | boolean | false | Enable Dropbox integration |
83
81
  | `images_upload_url` | string | - | URL for image uploads |
84
- | `font_family_formats` | string | - | Font family options |
85
- | `font_size_formats` | string | - | Font size options |
82
+ | `images_upload_credentials` | boolean | true | Include credentials in CORS upload requests |
83
+ | `images_upload_base_path` | string | '/' | Base path prefix for uploaded image URLs |
84
+ | `images_upload_max_size` | number | 10485760 | Maximum upload file size in bytes (default 10 MB) |
85
+ | `images_upload_headers` | Record\<string, string\> | - | Custom HTTP headers for upload requests |
86
+ | `font_family_formats` | string | *(TinyMCE defaults)* | Semicolon-separated font list (`Name=family,...`) |
87
+ | `font_size_formats` | string | '8pt 9pt 10pt 12pt 14pt 18pt 24pt 36pt' | Space-separated font sizes |
86
88
  | `fontName` | string | - | Default font family |
87
89
  | `fontSize` | string | - | Default font size |
88
90
  | `directionality` | 'ltr' \| 'rtl' | 'ltr' | Text direction |
89
- | `language` | string | 'en' | UI language |
91
+ | `language` | string | 'en' | UI language code (built-in translations for 31 languages) |
90
92
  | `height` | string \| number | 300 | Editor height |
93
+ | `auto_focus` | string | - | Auto-focus the editor on init |
91
94
  | `skin` | 'oxide' \| 'oxide-dark' | 'oxide' | Theme |
92
- | `toolbar_mode` | 'sliding' \| 'wrap' | 'sliding' | Toolbar overflow behavior |
95
+ | `content_css` | 'default' \| 'dark' | 'default' | Content area styling |
96
+ | `content_style` | string | - | Custom CSS injected into the content area |
97
+ | `toolbar` | string | *(see Toolbar section)* | Custom toolbar button layout |
98
+ | `toolbar_mode` | 'sliding' \| 'floating' \| 'wrap' | 'wrap' | Toolbar overflow behavior |
99
+ | `toolbar_sticky` | boolean | true | Keep toolbar pinned at the top while scrolling |
100
+ | `browser_spellcheck` | boolean | true | Enable browser spell-check |
101
+ | `entity_encoding` | 'raw' \| 'named' \| 'numeric' | 'raw' | HTML entity encoding mode |
102
+ | `convert_unsafe_embeds` | boolean | true | Sanitize embedded content |
103
+ | `format_empty_lines` | boolean | true | Format empty lines |
104
+ | `setup` | (editor) => void | - | Callback invoked before init — use to register custom buttons |
105
+
106
+ ### Toolbar Toggle
107
+
108
+ The toolbar supports a `||` (double pipe) separator to split buttons into a **primary row** and **collapsible overflow rows**. When `||` is present, a toggle button (`…`) appears at the far right of the primary row. Clicking it shows or hides the overflow buttons.
109
+
110
+ ```typescript
111
+ const editor = new HTMLEditor(container, {
112
+ // Buttons before || are always visible; buttons after || are toggled
113
+ toolbar: 'bold italic underline strikethrough | fontfamily fontsize || alignleft aligncenter alignright | forecolor backcolor | undo redo',
114
+ });
115
+ ```
116
+
117
+ The default `FULL_TOOLBAR` and `BASIC_TOOLBAR` presets include `||` so the toggle button appears out of the box. The overflow rows start collapsed.
118
+
119
+ If your custom toolbar string contains no `||`, all buttons render in a single flat toolbar with no toggle button (backwards compatible).
93
120
 
94
121
  ## API Reference
95
122
 
@@ -103,6 +130,13 @@ const editor = new HTMLEditor(container, {
103
130
  - `setDirty(state: boolean): void` - Set dirty state
104
131
  - `focus(): void` - Focus the editor
105
132
  - `hasFocus(): boolean` - Check if editor has focus
133
+ - `setLanguage(code: string): void` - Change UI language at runtime (rebuilds toolbar)
134
+ - `getTipTap(): Editor | null` - Access the underlying TipTap editor instance
135
+ - `getConfig(): EditorConfig` - Get the resolved editor configuration
136
+ - `isBasicEditor(): boolean` - Check if the editor is in basic mode
137
+ - `on(event, callback): void` - Subscribe to an editor event
138
+ - `off(event, callback): void` - Unsubscribe from an editor event
139
+ - `fire(event, ...args): void` - Fire an editor event manually
106
140
  - `destroy(): void` - Clean up and remove editor
107
141
 
108
142
  ### Events
@@ -112,6 +146,8 @@ const editor = new HTMLEditor(container, {
112
146
  - `dirty` - Dirty state changed
113
147
  - `focus` - Editor focused
114
148
  - `blur` - Editor blurred
149
+ - `languagechange` - UI language changed (receives language code)
150
+ - `templatechange` - A template was applied (receives the `Template` object)
115
151
 
116
152
  ### Supported Commands
117
153
 
@@ -119,12 +155,354 @@ The following TinyMCE-compatible commands are supported:
119
155
 
120
156
  - `bold`, `italic`, `underline`, `strikethrough`
121
157
  - `fontname`, `fontsize`, `lineheight`
122
- - `forecolor`, `backcolor`
158
+ - `forecolor`, `hilitecolor`, `backcolor`
123
159
  - `justifyleft`, `justifycenter`, `justifyright`, `justifyfull`
124
160
  - `insertunorderedlist`, `insertorderedlist`
125
161
  - `indent`, `outdent`
126
162
  - `undo`, `redo`
127
163
  - `removeformat`
164
+ - `mceremoveeditor` - Destroys the editor instance
165
+
166
+ ## Templates
167
+
168
+ The editor supports a template dropdown that lets users insert predefined HTML snippets. Enable it with `includeTemplates: true` and provide a `templates` array.
169
+
170
+ ### Template interface
171
+
172
+ ```typescript
173
+ interface Template {
174
+ id?: number | string; // Optional identifier
175
+ title: string; // Display name in the dropdown
176
+ description?: string; // Tooltip/description shown in the dropdown
177
+ content: string; // HTML content to insert
178
+ }
179
+ ```
180
+
181
+ ### Configuration
182
+
183
+ ```typescript
184
+ const editor = new HTMLEditor(container, {
185
+ includeTemplates: true,
186
+ templates: [
187
+ {
188
+ id: 1,
189
+ title: 'Greeting',
190
+ description: 'A simple greeting message',
191
+ content: '<h2>Hello!</h2><p>Thank you for reaching out.</p>',
192
+ },
193
+ {
194
+ id: 2,
195
+ title: 'Meeting Notes',
196
+ description: 'Template for meeting minutes',
197
+ content: '<h2>Meeting Notes</h2><p><strong>Date:</strong> [date]</p><h3>Agenda</h3><ol><li>Item 1</li></ol>',
198
+ },
199
+ ],
200
+ // Make sure 'template' appears in the toolbar string
201
+ toolbar: 'bold italic | template | undo redo',
202
+ });
203
+ ```
204
+
205
+ ### Listening for template changes
206
+
207
+ When a user selects a template, the `templatechange` event fires with the full `Template` object:
208
+
209
+ ```typescript
210
+ editor.on('templatechange', (template) => {
211
+ console.log('Applied template:', template.title);
212
+ console.log('Template ID:', template.id);
213
+ console.log('Content:', template.content);
214
+ });
215
+ ```
216
+
217
+ This event fires in addition to the standard `change` event, so consumers can distinguish a template insertion from regular edits and react accordingly (e.g. populate form fields, trigger a save, or log analytics).
218
+
219
+ ## Toolbar Buttons
220
+
221
+ All built-in toolbar button names that can be used in the `toolbar` config string:
222
+
223
+ | Button | Description |
224
+ |--------|-------------|
225
+ | `bold` | Toggle bold |
226
+ | `italic` | Toggle italic |
227
+ | `underline` | Toggle underline |
228
+ | `strikethrough` | Toggle strikethrough |
229
+ | `bullist` | Toggle bullet list |
230
+ | `numlist` | Toggle numbered list |
231
+ | `outdent` | Decrease indent |
232
+ | `indent` | Increase indent |
233
+ | `blockquote` | Toggle block quote |
234
+ | `fontfamily` | Font family dropdown |
235
+ | `fontsize` | Font size dropdown |
236
+ | `lineheight` | Line height dropdown (1, 1.2, 1.4, 1.6, 2) |
237
+ | `template` | Template dropdown (requires `includeTemplates: true`) |
238
+ | `alignleft` | Align left |
239
+ | `aligncenter` | Align center |
240
+ | `alignright` | Align right |
241
+ | `alignjustify` | Justify text |
242
+ | `forecolor` | Text color picker (28 preset colors + custom hex input) |
243
+ | `backcolor` | Highlight color picker (28 preset colors + custom hex input) |
244
+ | `removeformat` | Clear all formatting |
245
+ | `copy` | Copy selection |
246
+ | `cut` | Cut selection |
247
+ | `paste` | Paste from clipboard |
248
+ | `undo` | Undo last change |
249
+ | `redo` | Redo last undo |
250
+ | `image` | Insert image dialog (upload file or enter URL) |
251
+ | `charmap` | Special character picker (currency, math, arrows, symbols, Greek, punctuation) |
252
+ | `emoticons` | Emoji picker with search (smileys, gestures, hearts, objects, symbols, arrows) |
253
+ | `code` | Toggle code block |
254
+ | `link` | Insert/edit hyperlink dialog |
255
+ | `codesample` | Toggle code sample block |
256
+ | `fullscreen` | Toggle fullscreen editing mode |
257
+ | `preview` | Open content preview in a new window |
258
+ | `searchreplace` | Open Find & Replace dialog |
259
+ | `ltr` | Set text direction to left-to-right |
260
+ | `rtl` | Set text direction to right-to-left |
261
+
262
+ ### Default toolbars
263
+
264
+ **Full toolbar** (default when `basicEditor: false`):
265
+
266
+ ```
267
+ bold italic underline strikethrough | bullist numlist outdent indent blockquote | fontfamily fontsize || lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | image charmap emoticons | fullscreen preview | code link codesample | ltr rtl | searchreplace
268
+ ```
269
+
270
+ **Basic toolbar** (when `basicEditor: true`):
271
+
272
+ ```
273
+ bold italic underline strikethrough | bullist numlist outdent indent | fontfamily fontsize blockquote || lineheight alignleft aligncenter alignright alignjustify | forecolor backcolor | removeformat copy cut paste | undo redo | charmap emoticons | link | ltr rtl | searchreplace
274
+ ```
275
+
276
+ ## Image Upload
277
+
278
+ The image button opens a two-tab dialog:
279
+
280
+ - **Upload** — Drag-and-drop or browse for a local file. Supports JPEG, PNG, GIF, WebP, and SVG.
281
+ - **URL** — Enter an image URL directly.
282
+
283
+ If `images_upload_url` is configured, files are sent as `multipart/form-data` to that endpoint. The server response must be JSON containing a `location`, `url`, or `link` field with the resulting image URL. When no upload URL is set, images are embedded as base64 data URIs.
284
+
285
+ SVG files are automatically sanitized — dangerous elements (`<script>`, `<foreignObject>`, `<animate*>`) and event-handler attributes are stripped before insertion.
286
+
287
+ ```typescript
288
+ const editor = new HTMLEditor(container, {
289
+ images_upload_url: '/api/upload',
290
+ images_upload_credentials: true, // send cookies with CORS requests
291
+ images_upload_base_path: '/files/', // prefix for returned URLs
292
+ images_upload_max_size: 5 * 1024 * 1024, // 5 MB limit
293
+ images_upload_headers: {
294
+ 'X-CSRF-Token': token,
295
+ },
296
+ });
297
+ ```
298
+
299
+ ## Search & Replace
300
+
301
+ The `searchreplace` toolbar button (or **Ctrl/Cmd+F**) opens a Find & Replace dialog with:
302
+
303
+ - Case-sensitive matching toggle
304
+ - Whole-word matching toggle
305
+ - Find next / Find previous navigation
306
+ - Replace current match
307
+ - Replace all matches
308
+
309
+ **Dialog keyboard shortcuts:** Enter = find next, Shift+Enter = find previous, Escape = close.
310
+
311
+ ## Keyboard Shortcuts
312
+
313
+ | Shortcut | Action |
314
+ |----------|--------|
315
+ | Ctrl/Cmd+B | Toggle bold |
316
+ | Ctrl/Cmd+I | Toggle italic |
317
+ | Ctrl/Cmd+U | Toggle underline |
318
+ | Ctrl/Cmd+Z | Undo |
319
+ | Ctrl/Cmd+Shift+Z | Redo |
320
+ | Ctrl/Cmd+F | Open Find & Replace |
321
+
322
+ ## Localization
323
+
324
+ The editor ships with built-in translations for 31 languages. Set the language at construction or switch dynamically at runtime.
325
+
326
+ ### Setting the language
327
+
328
+ ```typescript
329
+ // At construction
330
+ const editor = new HTMLEditor(container, { language: 'fr' });
331
+
332
+ // Change at runtime — toolbar and dialogs update immediately
333
+ editor.setLanguage('ja');
334
+
335
+ // Listen for language changes
336
+ editor.on('languagechange', (code) => {
337
+ console.log('Language changed to:', code);
338
+ });
339
+ ```
340
+
341
+ ### Custom translations
342
+
343
+ If you need translations the built-in locales don't cover, you can provide your own function. A custom `setTranslate()` call takes priority over the built-in locale at construction time.
344
+
345
+ ```typescript
346
+ import { setTranslate, TRANSLATION_KEYS } from '@mdaemon/html-editor';
347
+
348
+ // See all keys that need translating
349
+ console.log(TRANSLATION_KEYS);
350
+
351
+ // Provide a custom translation function
352
+ setTranslate((key) => myCustomLookup(key));
353
+ ```
354
+
355
+ ### Supported languages
356
+
357
+ | Code | Language | Code | Language |
358
+ |------|----------|------|----------|
359
+ | `en` | English | `nl` | Nederlands |
360
+ | `ar` | العربية | `nb` | Norsk bokmål |
361
+ | `ca` | Català | `pl` | Polski |
362
+ | `zh` | 中文 | `pt` | Português |
363
+ | `cs` | Česky | `ro` | Româna |
364
+ | `da` | Dansk | `ru` | Русский |
365
+ | `en-gb` | English (UK) | `sr` | Srpski |
366
+ | `fi` | Suomi | `sl` | Slovenščina |
367
+ | `fr` | Français | `es` | Español |
368
+ | `fr-ca` | Canadien français | `sv` | Svenska |
369
+ | `de` | Deutsch | `zh-tw` | 繁體中文 (Taiwan) |
370
+ | `el` | Ελληνικά | `th` | ไทย |
371
+ | `hu` | Magyar | `tr` | Türkçe |
372
+ | `id` | Bahasa Indonesia | `vi` | Tiếng Việt |
373
+ | `it` | Italiano | | |
374
+ | `ja` | 日本語 | | |
375
+ | `ko` | 한글 | | |
376
+
377
+ ### Discovering available locales
378
+
379
+ ```typescript
380
+ import { availableLocales, getLocale } from '@mdaemon/html-editor';
381
+
382
+ console.log(availableLocales); // ['en', 'ar', 'ca', ...]
383
+ console.log(getLocale('de')); // { Bold: 'Fett', Italic: 'Kursiv', ... }
384
+ ```
385
+
386
+ ## Global Utilities
387
+
388
+ These functions are exported from the package and operate globally (affecting all editor instances).
389
+
390
+ ### Translation
391
+
392
+ ```typescript
393
+ import { setTranslate, getTranslate, resetTranslate, createTranslateFunction } from '@mdaemon/html-editor';
394
+
395
+ // Override translations for all editors
396
+ setTranslate((key) => myLookup(key));
397
+
398
+ // Get the current translate function
399
+ const t = getTranslate();
400
+
401
+ // Reset to built-in locale translations
402
+ resetTranslate();
403
+
404
+ // Create a translate function for a specific locale
405
+ const translateDe = createTranslateFunction('de');
406
+ console.log(translateDe('Bold')); // 'Fett'
407
+ ```
408
+
409
+ ### File source resolver
410
+
411
+ The file source resolver lets you transform image `src` attributes (e.g. to prepend a CDN URL or resolve relative paths).
412
+
413
+ ```typescript
414
+ import { setGetFileSrc, getGetFileSrc } from '@mdaemon/html-editor';
415
+
416
+ setGetFileSrc((path) => `https://cdn.example.com${path}`);
417
+
418
+ const resolver = getGetFileSrc();
419
+ console.log(resolver('/img/photo.jpg')); // 'https://cdn.example.com/img/photo.jpg'
420
+ ```
421
+
422
+ ### Exported constants
423
+
424
+ ```typescript
425
+ import { fontNames, CHAR_MAP, EMOJI_CATEGORIES, TRANSLATION_KEYS } from '@mdaemon/html-editor';
426
+
427
+ // fontNames — default semicolon-separated font family string
428
+ // CHAR_MAP — array of character categories for the character map dialog
429
+ // EMOJI_CATEGORIES — array of emoji categories for the emoji picker
430
+ // TRANSLATION_KEYS — array of all translation key strings
431
+ ```
432
+
433
+ ## Custom Toolbar Button API
434
+
435
+ The `setup` callback receives a TinyMCE-compatible editor API. Use `ui.registry.addButton()` to register custom buttons.
436
+
437
+ ```typescript
438
+ const editor = new HTMLEditor(container, {
439
+ toolbar: 'bold italic | myButton | undo redo',
440
+ setup: (ed) => {
441
+ ed.ui.registry.addButton('myButton', {
442
+ tooltip: 'My Custom Button',
443
+ text: 'Click Me', // text label on the button
444
+ icon: '/icons/custom.svg', // image URL (alternative to text)
445
+ disabled: false,
446
+ onSetup: (api) => {
447
+ // Called when the button is created
448
+ // api.setActive(true) — toggle active state
449
+ // api.setEnabled(false) — disable the button
450
+ // Return a teardown function (optional)
451
+ return () => { /* cleanup */ };
452
+ },
453
+ onAction: (api) => {
454
+ ed.insertContent('<p>Custom content!</p>');
455
+ },
456
+ });
457
+ },
458
+ });
459
+ ```
460
+
461
+ ### ToolbarButtonAPI
462
+
463
+ The `api` object passed to `onSetup` and `onAction`:
464
+
465
+ | Method | Description |
466
+ |--------|-------------|
467
+ | `isEnabled()` | Whether the button is currently enabled |
468
+ | `setEnabled(enabled)` | Enable or disable the button |
469
+ | `isActive()` | Whether the button is in an active/pressed state |
470
+ | `setActive(active)` | Toggle the active/pressed visual state |
471
+
472
+ ## Theming
473
+
474
+ ### Light and dark themes
475
+
476
+ Set `skin` to switch between light and dark chrome:
477
+
478
+ ```typescript
479
+ const editor = new HTMLEditor(container, {
480
+ skin: 'oxide-dark', // dark toolbar and dialogs
481
+ content_css: 'dark', // dark content area
482
+ });
483
+ ```
484
+
485
+ ### Custom content styles
486
+
487
+ Inject additional CSS into the editor content area:
488
+
489
+ ```typescript
490
+ const editor = new HTMLEditor(container, {
491
+ content_style: 'body { font-family: Georgia, serif; font-size: 16px; }',
492
+ });
493
+ ```
494
+
495
+ ### CSS classes
496
+
497
+ The editor DOM uses BEM-style classes you can target for further customization:
498
+
499
+ - `.md-editor` — outer wrapper
500
+ - `.md-editor-fullscreen` — applied in fullscreen mode
501
+ - `.md-editor-oxide` / `.md-editor-oxide-dark` — theme variant
502
+ - `.md-toolbar` — toolbar container
503
+ - `.md-toolbar-sticky` — sticky toolbar
504
+ - `.md-toolbar-primary` / `.md-toolbar-overflow` — primary and collapsible toolbar rows
505
+ - `.md-toolbar-btn` / `.md-toolbar-btn-active` — toolbar buttons
128
506
 
129
507
  ## Browser Support
130
508
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { Editor } from '@tiptap/core';
2
2
  import { Extension } from '@tiptap/core';
3
3
 
4
+ /** List of all supported locale codes */
5
+ export declare const availableLocales: string[];
6
+
4
7
  declare type BlurCallback = () => void;
5
8
 
6
9
  declare type ChangeCallback = (content: string) => void;
@@ -51,6 +54,13 @@ export declare interface ColorOption {
51
54
  label?: string;
52
55
  }
53
56
 
57
+ /**
58
+ * Create a TranslateFunction for a given language code.
59
+ * Returns a function that looks up keys in the locale map,
60
+ * falling back to the key itself if not found.
61
+ */
62
+ export declare function createTranslateFunction(code: string): TranslateFunction;
63
+
54
64
  declare type DirtyCallback = (dirty: boolean) => void;
55
65
 
56
66
  /**
@@ -88,6 +98,8 @@ export declare interface EditorConfig {
88
98
  images_upload_url?: string;
89
99
  images_upload_credentials?: boolean;
90
100
  images_upload_base_path?: string;
101
+ images_upload_max_size?: number;
102
+ images_upload_headers?: Record<string, string>;
91
103
  font_family_formats?: string;
92
104
  font_size_formats?: string;
93
105
  fontName?: string;
@@ -124,6 +136,8 @@ export declare interface EditorEventMap {
124
136
  change: ChangeCallback;
125
137
  focus: FocusCallback;
126
138
  blur: BlurCallback;
139
+ languagechange: LanguageChangeCallback;
140
+ templatechange: TemplateChangeCallback;
127
141
  }
128
142
 
129
143
  export declare interface EditorEvents {
@@ -185,6 +199,12 @@ declare interface FontSizeOptions {
185
199
  */
186
200
  export declare function getGetFileSrc(): (path: string) => string;
187
201
 
202
+ /**
203
+ * Get the locale string map for a given language code.
204
+ * Falls back to English if the code is not found.
205
+ */
206
+ export declare function getLocale(code: string): Record<string, string>;
207
+
188
208
  /**
189
209
  * Get global translation function
190
210
  */
@@ -215,9 +235,13 @@ export declare class HTMLEditor implements MDHTMLEditor {
215
235
  private customButtons;
216
236
  private eventListeners;
217
237
  private changeTimeout;
238
+ private imageUploadHelper;
218
239
  constructor(container: HTMLElement, config?: EditorConfig);
219
240
  private normalizeConfig;
220
241
  private createEditor;
242
+ private getImageUploadHelper;
243
+ private setupImageHandlers;
244
+ private handleImageFileUpload;
221
245
  private buildExtensions;
222
246
  private handleChange;
223
247
  getContent(): string;
@@ -233,6 +257,10 @@ export declare class HTMLEditor implements MDHTMLEditor {
233
257
  fire<K extends keyof EditorEventMap>(event: K, ...args: Parameters<EditorEventMap[K]>): void;
234
258
  destroy(): void;
235
259
  getTipTap(): Editor | null;
260
+ /**
261
+ * Set the UI language, updating all toolbar and dialog translations.
262
+ */
263
+ setLanguage(code: string): void;
236
264
  /**
237
265
  * Get the editor config
238
266
  */
@@ -263,6 +291,8 @@ export declare interface ImageUploadResult {
263
291
  */
264
292
  declare type InitCallback = (editor: MDHTMLEditor) => void;
265
293
 
294
+ export declare type LanguageChangeCallback = (code: string) => void;
295
+
266
296
  export declare const LineHeight: Extension<LineHeightOptions, any>;
267
297
 
268
298
  declare interface LineHeightOptions {
@@ -290,9 +320,17 @@ export declare interface MDHTMLEditor {
290
320
  off<K extends keyof EditorEventMap>(event: K, callback: EditorEventMap[K]): void;
291
321
  fire<K extends keyof EditorEventMap>(event: K, ...args: Parameters<EditorEventMap[K]>): void;
292
322
  destroy(): void;
323
+ setLanguage(code: string): void;
293
324
  getTipTap(): Editor | null;
294
325
  }
295
326
 
327
+ /**
328
+ * Reset the global translation function to the default identity function.
329
+ * This also clears the customized flag so that the next editor created
330
+ * will auto-apply the built-in locale based on its language config.
331
+ */
332
+ export declare function resetTranslate(): void;
333
+
296
334
  export declare class SearchReplace {
297
335
  private options;
298
336
  private overlay;
@@ -352,6 +390,8 @@ export declare interface Template {
352
390
  content: string;
353
391
  }
354
392
 
393
+ declare type TemplateChangeCallback = (template: Template) => void;
394
+
355
395
  export declare const TextDirection: Extension<TextDirectionOptions, any>;
356
396
 
357
397
  declare interface TextDirectionOptions {
@@ -367,12 +407,20 @@ export declare class Toolbar {
367
407
  private dropdowns;
368
408
  private charMap;
369
409
  private emojiPicker;
410
+ private imageUpload;
370
411
  private searchReplace;
371
412
  private updateInterval;
413
+ private boundClickHandler;
414
+ private boundKeydownHandler;
415
+ private overflowEl;
416
+ private toggleBtn;
372
417
  constructor(container: HTMLElement, options: ToolbarOptions);
373
418
  private get tiptap();
374
419
  private get trans();
375
420
  private render;
421
+ private renderGroups;
422
+ private createToggleButton;
423
+ private toggleOverflow;
376
424
  private createButton;
377
425
  private createActionButton;
378
426
  private createCustomButton;
@@ -383,6 +431,7 @@ export declare class Toolbar {
383
431
  private createDropdown;
384
432
  private createColorPicker;
385
433
  private bindEvents;
434
+ private unbindEvents;
386
435
  private closeAllDropdowns;
387
436
  private startStateUpdates;
388
437
  private updateButtonStates;
@@ -394,6 +443,7 @@ export declare class Toolbar {
394
443
  private openSourceCode;
395
444
  private openPreview;
396
445
  private toggleFullscreen;
446
+ rebuild(): void;
397
447
  destroy(): void;
398
448
  }
399
449
 
@@ -430,6 +480,9 @@ declare interface ToolbarOptions {
430
480
  */
431
481
  export declare type TranslateFunction = (key: string) => string;
432
482
 
483
+ /** All translation keys used by the editor */
484
+ export declare const TRANSLATION_KEYS: string[];
485
+
433
486
  /**
434
487
  * UI Registry for custom buttons (TinyMCE-compatible)
435
488
  */