@trycourier/react-designer 0.0.3 → 0.0.5

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.
Files changed (43) hide show
  1. package/README.md +206 -22
  2. package/dist/cjs/index.js +41 -35
  3. package/dist/cjs/index.js.map +4 -4
  4. package/dist/cjs/styles.css +20 -0
  5. package/dist/components/Providers/BrandProvider.d.ts +0 -12
  6. package/dist/components/Providers/Providers.types.d.ts +1 -0
  7. package/dist/components/Providers/TemplateProvider.d.ts +7 -12
  8. package/dist/components/Providers/api/common.d.ts +1 -1
  9. package/dist/components/Providers/index.d.ts +4 -2
  10. package/dist/components/Providers/store.d.ts +41 -6
  11. package/dist/components/Providers/useBrandActions.d.ts +22 -0
  12. package/dist/components/Providers/useTemplateActions.d.ts +23 -0
  13. package/dist/components/TemplateEditor/Channels/Email/Email.d.ts +3 -3
  14. package/dist/components/TemplateEditor/Channels/Inbox/Inbox.d.ts +6 -2
  15. package/dist/components/TemplateEditor/Channels/Inbox/InboxEditor.d.ts +1 -1
  16. package/dist/components/TemplateEditor/Channels/Push/Push.d.ts +11 -5
  17. package/dist/components/TemplateEditor/Channels/SMS/SMS.d.ts +10 -5
  18. package/dist/components/TemplateEditor/TemplateEditor.d.ts +1 -1
  19. package/dist/components/TemplateEditor/index.d.ts +5 -1
  20. package/dist/components/TemplateEditor/store.d.ts +3 -0
  21. package/dist/components/extensions/Divider/Divider.types.d.ts +2 -2
  22. package/dist/components/ui/Status/Status.d.ts +4 -1
  23. package/dist/components/ui-kit/Button/Button.d.ts +1 -1
  24. package/dist/components/ui-kit/ErrorBoundary/ErrorBoundary.d.ts +22 -0
  25. package/dist/components/ui-kit/ErrorBoundary/index.d.ts +1 -0
  26. package/dist/components/ui-kit/index.d.ts +1 -0
  27. package/dist/esm/index.js +41 -35
  28. package/dist/esm/index.js.map +4 -4
  29. package/dist/esm/styles.css +20 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/lib/api/uploadImage.d.ts +0 -1
  32. package/dist/lib/utils/errors.d.ts +26 -0
  33. package/dist/lib/utils/getTitle/demo.d.ts +1 -0
  34. package/dist/lib/utils/getTitle/getTitle.d.ts +18 -0
  35. package/dist/lib/utils/getTitle/getTitle.test.d.ts +1 -0
  36. package/dist/lib/utils/getTitle/index.d.ts +2 -0
  37. package/dist/lib/utils/getTitle/preserveStorageFormat.d.ts +30 -0
  38. package/dist/lib/utils/getTitle/preserveStorageFormat.test.d.ts +1 -0
  39. package/dist/lib/utils/index.d.ts +1 -0
  40. package/dist/lib/utils/updateElemental/updateElemental.d.ts +1 -1
  41. package/dist/styles.css +20 -0
  42. package/dist/types/elemental.types.d.ts +1 -0
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -145,15 +145,23 @@ import { TemplateEditor, TemplateProvider, useTemplateActions } from '@trycourie
145
145
  function SaveButtonComponent() {
146
146
  const { publishTemplate } = useTemplateActions();
147
147
 
148
- const handlePublishTemplate = () => {
148
+ const handlePublishTemplate = async () => {
149
149
  //... other publish logic
150
150
  await publishTemplate();
151
151
  }
152
152
 
153
- return (
154
- <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
153
+ return (
154
+ <div>
155
155
  <TemplateEditor hidePublish />
156
- <button onClick={handlePublishTemplate}>Save Template</button>;
156
+ <button onClick={handlePublishTemplate}>Save Template</button>
157
+ </div>
158
+ );
159
+ }
160
+
161
+ function App() {
162
+ return (
163
+ <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
164
+ <SaveButtonComponent />
157
165
  </TemplateProvider>
158
166
  );
159
167
  }
@@ -201,6 +209,8 @@ function App() {
201
209
 
202
210
  By default, the Courier Editor auto-saves content. To disable this feature, configure the provider as follows
203
211
 
212
+ *Note:* `useTemplateActions` *must be used inside of the `<TemplateProvider />` context*
213
+
204
214
  ```tsx
205
215
  import "@trycourier/react-designer/styles.css";
206
216
  import { TemplateEditor, TemplateProvider, useTemplateActions } from '@trycourier/react-designer';
@@ -208,16 +218,24 @@ import { TemplateEditor, TemplateProvider, useTemplateActions } from '@trycourie
208
218
  function SaveButtonComponent() {
209
219
  const { saveTemplate, publishTemplate } = useTemplateActions();
210
220
 
211
- const handleSaveTemplate = () => {
221
+ const handleSaveTemplate = async () => {
212
222
  //... other publish logic
213
223
  await saveTemplate(); // the template must be saved before publishing
214
224
  await publishTemplate();
215
225
  }
216
226
 
217
- return (
218
- <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
227
+ return (
228
+ <div>
219
229
  <TemplateEditor autoSave={false} hidePublish />
220
- <button onClick={handleSaveTemplate}>Save Template</button>;
230
+ <button onClick={handleSaveTemplate}>Save Template</button>
231
+ </div>
232
+ );
233
+ }
234
+
235
+ function App() {
236
+ return (
237
+ <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
238
+ <SaveButtonComponent />
221
239
  </TemplateProvider>
222
240
  );
223
241
  }
@@ -263,20 +281,20 @@ function App() {
263
281
  <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
264
282
  <TemplateEditor
265
283
  variables={{
266
- "user": {
267
- "firstName": "John",
268
- "lastName": "Doe",
269
- "email": "john@example.com"
270
- },
271
- "company": {
272
- "name": "Acme Inc",
273
- "address": {
274
- "street": "123 Main St",
275
- "city": "San Francisco"
276
- }
277
- }
278
- }}
279
- />
284
+ "user": {
285
+ "firstName": "John",
286
+ "lastName": "Doe",
287
+ "email": "john@example.com"
288
+ },
289
+ "company": {
290
+ "name": "Acme Inc",
291
+ "address": {
292
+ "street": "123 Main St",
293
+ "city": "San Francisco"
294
+ }
295
+ }
296
+ }}
297
+ />
280
298
  </TemplateProvider>
281
299
  );
282
300
  }
@@ -287,6 +305,172 @@ function App() {
287
305
  1. When editing text, type `{{` to open the variable suggestions dropdown. Select the variable you want to insert from the list.
288
306
  2. Via curly braces `{}` icon in top toolbar (if the variables are available for selected element).
289
307
 
308
+ ## Error Handling
309
+
310
+ The Courier Editor includes a comprehensive error handling system that automatically provides user-friendly notifications for various error types including API errors, network failures, validation issues, and file upload problems.
311
+
312
+ ### Custom Error Handling
313
+
314
+ You can programmatically trigger and handle errors using the `useTemplateActions` hook. This is useful for custom validation, user actions, or integration with external systems.
315
+
316
+ *Note: `useTemplateActions` must be used inside of the `<TemplateProvider />` context*
317
+
318
+ ```tsx
319
+ import { useTemplateActions, TemplateEditor, TemplateProvider } from '@trycourier/react-designer';
320
+
321
+ function CustomComponent() {
322
+ const { setTemplateError } = useTemplateActions();
323
+
324
+ const handleCustomAction = async () => {
325
+ try {
326
+ // Your custom logic here
327
+ await someApiCall();
328
+ } catch (error) {
329
+ // Simple string error (automatically converted)
330
+ setTemplateError("Something went wrong with your custom action");
331
+
332
+ // Or create a structured error with custom toast configuration
333
+ setTemplateError({
334
+ message: "Custom error message",
335
+ toastProps: {
336
+ duration: 6000,
337
+ action: {
338
+ label: "Retry",
339
+ onClick: () => handleCustomAction(),
340
+ },
341
+ description: "Additional context about the error"
342
+ }
343
+ });
344
+ }
345
+ };
346
+
347
+ return (
348
+ <div>
349
+ <TemplateEditor />
350
+ <button onClick={handleCustomAction}>Custom Action</button>
351
+ </div>
352
+ );
353
+ }
354
+
355
+ function App() {
356
+ return (
357
+ <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
358
+ <CustomComponent />
359
+ </TemplateProvider>
360
+ );
361
+ }
362
+ ```
363
+
364
+ ### Error Object Structure
365
+
366
+ All errors use a simple, consistent structure:
367
+
368
+ ```tsx
369
+ // Error interface
370
+ interface TemplateError {
371
+ message: string; // The error message to display
372
+ toastProps?: ExternalToast; // Optional Sonner toast configuration
373
+ }
374
+
375
+ // Usage examples
376
+ setTemplateError({
377
+ message: "Upload failed",
378
+ toastProps: {
379
+ duration: 5000,
380
+ description: "File size too large",
381
+ action: {
382
+ label: "Try Again",
383
+ onClick: () => retryUpload(),
384
+ }
385
+ }
386
+ });
387
+
388
+ // Different error scenarios
389
+ setTemplateError({ message: "Authentication failed", toastProps: { duration: 6000 } });
390
+ setTemplateError({ message: "Network error", toastProps: { description: "Check connection" } });
391
+ setTemplateError({ message: "Validation error", toastProps: { duration: 5000 } });
392
+ ```
393
+
394
+ ### Error Boundary Protection
395
+
396
+ The editor includes an error boundary component to catch and handle React rendering errors gracefully.
397
+
398
+ *Note: `useTemplateActions` must be used inside of the `<TemplateProvider />` context*
399
+
400
+ ```tsx
401
+ import { ErrorBoundary, useTemplateActions, TemplateEditor, TemplateProvider } from '@trycourier/react-designer';
402
+
403
+ function TemplateEditorWithErrorHandling() {
404
+ const { setTemplateError } = useTemplateActions();
405
+
406
+ return (
407
+ <ErrorBoundary
408
+ onError={(error, errorInfo) => {
409
+ // Custom error logging
410
+ console.error('Editor error:', error);
411
+
412
+ // Optional: integrate with template error system
413
+ setTemplateError({
414
+ message: `Render error: ${error.message}`,
415
+ toastProps: {
416
+ duration: 6000,
417
+ action: {
418
+ label: "Reload",
419
+ onClick: () => window.location.reload(),
420
+ },
421
+ }
422
+ });
423
+ }}
424
+ fallback={<div>Something went wrong. Please refresh the page.</div>}
425
+ >
426
+ <TemplateEditor />
427
+ </ErrorBoundary>
428
+ );
429
+ }
430
+
431
+ function App() {
432
+ return (
433
+ <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
434
+ <TemplateEditorWithErrorHandling />
435
+ </TemplateProvider>
436
+ );
437
+ }
438
+ ```
439
+
440
+ ### Clearing Errors
441
+
442
+ To programmatically clear the current error state:
443
+
444
+ *Note: `useTemplateActions` must be used inside of the `<TemplateProvider />` context*
445
+
446
+ ```tsx
447
+ import { useTemplateActions, TemplateEditor, TemplateProvider } from '@trycourier/react-designer';
448
+
449
+ function ClearErrorComponent() {
450
+ const { setTemplateError } = useTemplateActions();
451
+
452
+ const handleClearError = () => {
453
+ // Clear the error
454
+ setTemplateError(null);
455
+ };
456
+
457
+ return (
458
+ <div>
459
+ <TemplateEditor />
460
+ <button onClick={handleClearError}>Clear Error</button>
461
+ </div>
462
+ );
463
+ }
464
+
465
+ function App() {
466
+ return (
467
+ <TemplateProvider templateId="template-123" tenantId="tenant-123" token="jwt">
468
+ <ClearErrorComponent />
469
+ </TemplateProvider>
470
+ );
471
+ }
472
+ ```
473
+
290
474
  ## Brand Editor
291
475
 
292
476
  The Brand Editor component allows you to customize and manage a tenant's brand settings directly within your application. This specialized editor provides an interface for modifying brand colors, logos, and other visual elements that will be applied to your templates.