@parathantl/react-email-editor 0.1.0 → 0.1.2

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
@@ -157,6 +157,7 @@ Or pass MJML at init time without a ref:
157
157
  | `onChange` | `(template: EmailTemplate) => void` | Called on every template change (debounced 150ms) |
158
158
  | `onSave` | `(mjml: string, html: string) => void` | Called on Ctrl+S |
159
159
  | `onReady` | `() => void` | Called once after editor mounts |
160
+ | `onVariablesChange` | `(customVariables: Variable[]) => void` | Called when user adds/removes custom variables |
160
161
  | `fontFamilies` | `string[]` | Custom font options for the toolbar |
161
162
  | `fontSizes` | `string[]` | Custom font size options |
162
163
  | `persistenceKey` | `string` | Key for auto-save/restore (enables persistence) |
@@ -183,7 +184,7 @@ Or pass MJML at init time without a ref:
183
184
 
184
185
  ## Template Variables
185
186
 
186
- Define variables and insert them into text blocks as `{{ variable_name }}`:
187
+ Define variables and insert them into text blocks as `{{ variable_name }}`. Variables appear as insertable chips in the sidebar, grouped by category. Users can click or drag them into any text/heading block.
187
188
 
188
189
  ```tsx
189
190
  <EmailEditor
@@ -195,13 +196,139 @@ Define variables and insert them into text blocks as `{{ variable_name }}`:
195
196
  />
196
197
  ```
197
198
 
198
- Extract used variables programmatically:
199
+ | Variable Field | Required | Description |
200
+ |---------------|----------|-------------|
201
+ | `key` | Yes | The placeholder key used in `{{ key }}` syntax |
202
+ | `sample` | No | Sample value shown in previews and tooltips |
203
+ | `label` | No | Display label in the sidebar (defaults to `key`) |
204
+ | `group` | No | Group name for organizing variables in the sidebar |
205
+ | `icon` | No | Icon shown next to the variable chip |
206
+
207
+ ### Retrieving used variables
208
+
209
+ Extract which variables are actually used in the current template:
199
210
 
200
211
  ```tsx
201
212
  const keys = editorRef.current?.getVariables();
202
213
  // ['first_name', 'unsubscribe_url']
203
214
  ```
204
215
 
216
+ ### Listening for custom variable changes
217
+
218
+ Users can create custom variables at runtime via the sidebar. Use `onVariablesChange` to sync these back to your backend:
219
+
220
+ ```tsx
221
+ <EmailEditor
222
+ variables={backendVariables}
223
+ onVariablesChange={(customVars) => {
224
+ // customVars = variables created by the user in the editor
225
+ saveToBackend(customVars);
226
+ }}
227
+ />
228
+ ```
229
+
230
+ ## Custom Fonts
231
+
232
+ Pass custom font families and sizes to the editor. These appear in the rich text toolbar dropdowns.
233
+
234
+ ```tsx
235
+ <EmailEditor
236
+ fontFamilies={[
237
+ 'Arial, sans-serif',
238
+ 'Georgia, serif',
239
+ 'Courier New, monospace',
240
+ 'Inter, sans-serif', // your custom web font
241
+ ]}
242
+ fontSizes={['12px', '14px', '16px', '18px', '20px', '24px', '32px']}
243
+ />
244
+ ```
245
+
246
+ If omitted, the editor falls back to built-in defaults (8 font families, 11 font sizes).
247
+
248
+ ## Backend Integration
249
+
250
+ A complete example showing how to pass placeholders from your backend, save the template, and retrieve used variables:
251
+
252
+ ```tsx
253
+ import { useRef, useEffect, useState } from 'react';
254
+ import { EmailEditor } from '@parathantl/react-email-editor';
255
+ import '@parathantl/react-email-editor/styles.css';
256
+ import type { EmailEditorRef, EmailTemplate, Variable } from '@parathantl/react-email-editor';
257
+
258
+ function TemplateEditor({ templateId }: { templateId: string }) {
259
+ const editorRef = useRef<EmailEditorRef>(null);
260
+ const [variables, setVariables] = useState<Variable[]>([]);
261
+ const [initialTemplate, setInitialTemplate] = useState<EmailTemplate | undefined>();
262
+
263
+ // 1. Load variables and template from backend on mount
264
+ useEffect(() => {
265
+ fetch(`/api/templates/${templateId}`)
266
+ .then((res) => res.json())
267
+ .then((data) => {
268
+ setVariables(data.variables); // backend-defined placeholders
269
+ setInitialTemplate(data.template); // saved template JSON
270
+ });
271
+ }, [templateId]);
272
+
273
+ // 2. Save template + used variables to backend
274
+ const handleSave = async (mjml: string, html: string) => {
275
+ const usedVariables = editorRef.current?.getVariables(); // ['first_name', 'company']
276
+ const templateJSON = editorRef.current?.getJSON();
277
+
278
+ await fetch(`/api/templates/${templateId}`, {
279
+ method: 'PUT',
280
+ headers: { 'Content-Type': 'application/json' },
281
+ body: JSON.stringify({
282
+ mjml,
283
+ html,
284
+ template: templateJSON,
285
+ usedVariables,
286
+ }),
287
+ });
288
+ };
289
+
290
+ // 3. Sync user-created custom variables to backend
291
+ const handleVariablesChange = (customVars: Variable[]) => {
292
+ fetch(`/api/templates/${templateId}/variables`, {
293
+ method: 'POST',
294
+ headers: { 'Content-Type': 'application/json' },
295
+ body: JSON.stringify(customVars),
296
+ });
297
+ };
298
+
299
+ if (!initialTemplate) return <div>Loading...</div>;
300
+
301
+ return (
302
+ <EmailEditor
303
+ ref={editorRef}
304
+ initialTemplate={initialTemplate}
305
+ variables={variables}
306
+ onSave={handleSave}
307
+ onVariablesChange={handleVariablesChange}
308
+ onChange={(template) => {
309
+ // Optional: auto-save on every change
310
+ console.log('Template updated');
311
+ }}
312
+ fontFamilies={['Arial, sans-serif', 'Georgia, serif', 'Inter, sans-serif']}
313
+ />
314
+ );
315
+ }
316
+ ```
317
+
318
+ ### Data flow summary
319
+
320
+ ```
321
+ Backend Editor Backend
322
+ | | |
323
+ |-- variables (props) --------> | |
324
+ |-- initialTemplate (props) --> | |
325
+ | | |
326
+ | | -- onSave(mjml, html) -----> |
327
+ | | -- ref.getVariables() -----> | (used variable keys)
328
+ | | -- ref.getJSON() ----------> | (template structure)
329
+ | | -- onVariablesChange() ----> | (custom variables)
330
+ ```
331
+
205
332
  ## Custom Block Types
206
333
 
207
334
  Extend the editor with your own block types using the registry: